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