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