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