4407c77f3b233f9154955dd323c8d67064254187
[ghc-hetmet.git] / rts / Disassembler.c
1 /* -----------------------------------------------------------------------------
2  * Bytecode disassembler
3  *
4  * Copyright (c) 1994-2002.
5  *
6  * $RCSfile: Disassembler.c,v $
7  * $Revision: 1.29 $
8  * $Date: 2004/09/03 15:28:19 $
9  * ---------------------------------------------------------------------------*/
10
11 #ifdef DEBUG
12
13 #include "PosixSource.h"
14 #include "Rts.h"
15 #include "RtsAPI.h"
16 #include "RtsUtils.h"
17 #include "Closures.h"
18 #include "TSO.h"
19 #include "Schedule.h"
20
21 #include "Bytecodes.h"
22 #include "Printer.h"
23 #include "Disassembler.h"
24 #include "Interpreter.h"
25
26 /* --------------------------------------------------------------------------
27  * Disassembler
28  * ------------------------------------------------------------------------*/
29
30 int
31 disInstr ( StgBCO *bco, int pc )
32 {
33    int i;
34    StgWord16 instr;
35
36    StgWord16*     instrs      = (StgWord16*)(bco->instrs->payload);
37
38    StgArrWords*   literal_arr = bco->literals;
39    StgWord*       literals    = (StgWord*)(&literal_arr->payload[0]);
40
41    StgMutArrPtrs* ptrs_arr    = bco->ptrs;
42    StgPtr*        ptrs        = (StgPtr*)(&ptrs_arr->payload[0]);
43
44    instr = instrs[pc++];
45    switch (instr) {
46       case bci_SWIZZLE:
47          debugBelch("SWIZZLE stkoff %d by %d\n",
48                          instrs[pc], (signed int)instrs[pc+1]);
49          pc += 2; break;
50       case bci_CCALL:
51          debugBelch("CCALL    marshaller at 0x%lx\n", 
52                          literals[instrs[pc]] );
53          pc += 1; break;
54       case bci_STKCHECK: 
55          debugBelch("STKCHECK %d\n", instrs[pc] );
56          pc += 1; break;
57       case bci_PUSH_L: 
58          debugBelch("PUSH_L   %d\n", instrs[pc] );
59          pc += 1; break;
60       case bci_PUSH_LL:
61          debugBelch("PUSH_LL  %d %d\n", instrs[pc], instrs[pc+1] ); 
62          pc += 2; break;
63       case bci_PUSH_LLL:
64          debugBelch("PUSH_LLL %d %d %d\n", instrs[pc], instrs[pc+1], 
65                                                             instrs[pc+2] ); 
66          pc += 3; break;
67       case bci_PUSH_G:
68          debugBelch("PUSH_G   " ); printPtr( ptrs[instrs[pc]] );
69          debugBelch("\n" );
70          pc += 1; break;
71
72       case bci_PUSH_ALTS:
73          debugBelch("PUSH_ALTS  " ); printPtr( ptrs[instrs[pc]] );
74          debugBelch("\n");
75          pc += 1; break;
76       case bci_PUSH_ALTS_P:
77          debugBelch("PUSH_ALTS_P  " ); printPtr( ptrs[instrs[pc]] );
78          debugBelch("\n");
79          pc += 1; break;
80       case bci_PUSH_ALTS_N:
81          debugBelch("PUSH_ALTS_N  " ); printPtr( ptrs[instrs[pc]] );
82          debugBelch("\n");
83          pc += 1; break;
84       case bci_PUSH_ALTS_F:
85          debugBelch("PUSH_ALTS_F  " ); printPtr( ptrs[instrs[pc]] );
86          debugBelch("\n");
87          pc += 1; break;
88       case bci_PUSH_ALTS_D:
89          debugBelch("PUSH_ALTS_D  " ); printPtr( ptrs[instrs[pc]] );
90          debugBelch("\n");
91          pc += 1; break;
92       case bci_PUSH_ALTS_L:
93          debugBelch("PUSH_ALTS_L  " ); printPtr( ptrs[instrs[pc]] );
94          debugBelch("\n");
95          pc += 1; break;
96       case bci_PUSH_ALTS_V:
97          debugBelch("PUSH_ALTS_V  " ); printPtr( ptrs[instrs[pc]] );
98          debugBelch("\n");
99          pc += 1; break;
100
101       case bci_PUSH_UBX:
102          debugBelch("PUSH_UBX ");
103          for (i = 0; i < instrs[pc+1]; i++) 
104             debugBelch("0x%lx ", literals[i + instrs[pc]] );
105          debugBelch("\n");
106          pc += 2; break;
107       case bci_PUSH_APPLY_N:
108           debugBelch("PUSH_APPLY_N\n");
109           break;
110       case bci_PUSH_APPLY_V:
111           debugBelch("PUSH_APPLY_V\n");
112           break;
113       case bci_PUSH_APPLY_F:
114           debugBelch("PUSH_APPLY_F\n");
115           break;
116       case bci_PUSH_APPLY_D:
117           debugBelch("PUSH_APPLY_D\n");
118           break;
119       case bci_PUSH_APPLY_L:
120           debugBelch("PUSH_APPLY_L\n");
121           break;
122       case bci_PUSH_APPLY_P:
123           debugBelch("PUSH_APPLY_P\n");
124           break;
125       case bci_PUSH_APPLY_PP:
126           debugBelch("PUSH_APPLY_PP\n");
127           break;
128       case bci_PUSH_APPLY_PPP:
129           debugBelch("PUSH_APPLY_PPP\n");
130           break;
131       case bci_PUSH_APPLY_PPPP:
132           debugBelch("PUSH_APPLY_PPPP\n");
133           break;
134       case bci_PUSH_APPLY_PPPPP:
135           debugBelch("PUSH_APPLY_PPPPP\n");
136           break;
137       case bci_PUSH_APPLY_PPPPPP:
138           debugBelch("PUSH_APPLY_PPPPPP\n");
139           break;
140       case bci_SLIDE: 
141          debugBelch("SLIDE     %d down by %d\n", instrs[pc], instrs[pc+1] );
142          pc += 2; break;
143       case bci_ALLOC_AP:
144          debugBelch("ALLOC_AP  %d words\n", instrs[pc] );
145          pc += 1; break;
146       case bci_ALLOC_PAP:
147          debugBelch("ALLOC_PAP %d arity, %d words\n",
148                  instrs[pc], instrs[pc+1] );
149          pc += 2; break;
150       case bci_MKAP:
151          debugBelch("MKAP      %d words, %d stkoff\n", instrs[pc+1], 
152                                                            instrs[pc] );
153          pc += 2; break;
154       case bci_MKPAP:
155          debugBelch("MKPAP     %d words, %d stkoff\n", instrs[pc+1], 
156                                                            instrs[pc] );
157          pc += 2; break;
158       case bci_UNPACK:
159          debugBelch("UNPACK    %d\n", instrs[pc] );
160          pc += 1; break;
161       case bci_PACK:
162          debugBelch("PACK      %d words with itbl ", instrs[pc+1] );
163          printPtr( (StgPtr)literals[instrs[pc]] );
164          debugBelch("\n");
165          pc += 2; break;
166
167       case bci_TESTLT_I:
168          debugBelch("TESTLT_I  %ld, fail to %d\n", literals[instrs[pc]],
169                                                       instrs[pc+1]);
170          pc += 2; break;
171       case bci_TESTEQ_I:
172          debugBelch("TESTEQ_I  %ld, fail to %d\n", literals[instrs[pc]],
173                                                       instrs[pc+1]);
174          pc += 2; break;
175
176       case bci_TESTLT_F:
177          debugBelch("TESTLT_F  %ld, fail to %d\n", literals[instrs[pc]],
178                                                       instrs[pc+1]);
179          pc += 2; break;
180       case bci_TESTEQ_F:
181          debugBelch("TESTEQ_F  %ld, fail to %d\n", literals[instrs[pc]],
182                                                       instrs[pc+1]);
183          pc += 2; break;
184
185       case bci_TESTLT_D:
186          debugBelch("TESTLT_D  %ld, fail to %d\n", literals[instrs[pc]],
187                                                       instrs[pc+1]);
188          pc += 2; break;
189       case bci_TESTEQ_D:
190          debugBelch("TESTEQ_D  %ld, fail to %d\n", literals[instrs[pc]],
191                                                       instrs[pc+1]);
192          pc += 2; break;
193
194       case bci_TESTLT_P:
195          debugBelch("TESTLT_P  %d, fail to %d\n", instrs[pc],
196                                                       instrs[pc+1]);
197          pc += 2; break;
198       case bci_TESTEQ_P:
199          debugBelch("TESTEQ_P  %d, fail to %d\n", instrs[pc],
200                                                       instrs[pc+1]);
201          pc += 2; break;
202       case bci_CASEFAIL: 
203          debugBelch("CASEFAIL\n" );
204          break;
205       case bci_JMP:
206          debugBelch("JMP to    %d\n", instrs[pc]);
207          pc += 1; break;
208
209       case bci_ENTER:
210          debugBelch("ENTER\n");
211          break;
212
213       case bci_RETURN:
214          debugBelch("RETURN\n" );
215          break;
216       case bci_RETURN_P:
217          debugBelch("RETURN_P\n" );
218          break;
219       case bci_RETURN_N:
220          debugBelch("RETURN_N\n" );
221          break;
222       case bci_RETURN_F:
223          debugBelch("RETURN_F\n" );
224          break;
225       case bci_RETURN_D:
226          debugBelch("RETURN_D\n" );
227          break;
228       case bci_RETURN_L:
229          debugBelch("RETURN_L\n" );
230          break;
231       case bci_RETURN_V:
232          debugBelch("RETURN_V\n" );
233          break;
234
235       default:
236          barf("disInstr: unknown opcode %u", (unsigned int) instr);
237    }
238    return pc;
239 }
240
241
242 /* Something of a kludge .. how do we know where the end of the insn
243    array is, since it isn't recorded anywhere?  Answer: the first
244    short is the number of bytecodes which follow it.  
245    See ByteCodeGen.linkBCO.insns_arr for construction ...  
246 */
247 void disassemble( StgBCO *bco )
248 {
249    nat i, j;
250    StgWord16*     instrs    = (StgWord16*)(bco->instrs->payload);
251    StgMutArrPtrs* ptrs      = bco->ptrs;
252    nat            nbcs      = (int)instrs[0];
253    nat            pc        = 1;
254
255    debugBelch("BCO\n" );
256    pc = 1;
257    while (pc <= nbcs) {
258       debugBelch("\t%2d:  ", pc );
259       pc = disInstr ( bco, pc );
260    }
261
262    debugBelch("INSTRS:\n   " );
263    j = 16;
264    for (i = 0; i < nbcs; i++) {
265       debugBelch("%3d ", (int)instrs[i] );
266       j--; 
267       if (j == 0) { j = 16; debugBelch("\n   "); };
268    }
269    debugBelch("\n");
270
271    debugBelch("PTRS:\n   " );
272    j = 8;
273    for (i = 0; i < ptrs->ptrs; i++) {
274       debugBelch("%8p ", ptrs->payload[i] );
275       j--; 
276       if (j == 0) { j = 8; debugBelch("\n   "); };
277    }
278    debugBelch("\n");
279
280    debugBelch("\n");
281    ASSERT(pc == nbcs+1);
282 }
283
284 #endif /* DEBUG */