Reorganisation of the source tree
[ghc.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%x\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%x ", 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 %d, fail to %d\n", literals[instrs[pc]],
166 instrs[pc+1]);
167 pc += 2; break;
168 case bci_TESTEQ_I:
169 debugBelch("TESTEQ_I %d, 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 %d, fail to %d\n", literals[instrs[pc]],
175 instrs[pc+1]);
176 pc += 2; break;
177 case bci_TESTEQ_F:
178 debugBelch("TESTEQ_F %d, 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 %d, fail to %d\n", literals[instrs[pc]],
184 instrs[pc+1]);
185 pc += 2; break;
186 case bci_TESTEQ_D:
187 debugBelch("TESTEQ_D %d, 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 */