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