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