1 /* -----------------------------------------------------------------------------
2 * Bytecode disassembler
4 * Copyright (c) 1994-2002.
6 * $RCSfile: Disassembler.c,v $
8 * $Date: 2003/03/25 17:04:09 $
9 * ---------------------------------------------------------------------------*/
13 #include "PosixSource.h"
21 #include "Bytecodes.h"
23 #include "Disassembler.h"
24 #include "Interpreter.h"
28 /* --------------------------------------------------------------------------
30 * ------------------------------------------------------------------------*/
33 disInstr ( StgBCO *bco, int pc )
37 StgWord16* instrs = (StgWord16*)(bco->instrs->payload);
39 StgArrWords* literal_arr = bco->literals;
40 StgWord* literals = (StgWord*)(&literal_arr->payload[0]);
42 StgMutArrPtrs* ptrs_arr = bco->ptrs;
43 StgPtr* ptrs = (StgPtr*)(&ptrs_arr->payload[0]);
45 StgArrWords* itbls_arr = bco->itbls;
46 StgInfoTable** itbls = (StgInfoTable**)(&itbls_arr->payload[0]);
48 switch (instrs[pc++]) {
50 fprintf(stderr, "SWIZZLE stkoff %d by %d\n",
51 instrs[pc], (signed int)instrs[pc+1]);
54 fprintf(stderr, "CCALL marshaller at 0x%x\n",
55 literals[instrs[pc]] );
58 fprintf(stderr, "STKCHECK %d\n", instrs[pc] );
61 fprintf(stderr, "PUSH_L %d\n", instrs[pc] );
64 fprintf(stderr, "PUSH_LL %d %d\n", instrs[pc], instrs[pc+1] );
67 fprintf(stderr, "PUSH_LLL %d %d %d\n", instrs[pc], instrs[pc+1],
71 fprintf(stderr, "PUSH_G " ); printPtr( ptrs[instrs[pc]] );
72 fprintf(stderr, "\n" );
76 fprintf(stderr, "PUSH_ALTS " ); printPtr( ptrs[instrs[pc]] );
77 fprintf(stderr, "\n");
80 fprintf(stderr, "PUSH_ALTS_P " ); printPtr( ptrs[instrs[pc]] );
81 fprintf(stderr, "\n");
84 fprintf(stderr, "PUSH_ALTS_N " ); printPtr( ptrs[instrs[pc]] );
85 fprintf(stderr, "\n");
88 fprintf(stderr, "PUSH_ALTS_F " ); printPtr( ptrs[instrs[pc]] );
89 fprintf(stderr, "\n");
92 fprintf(stderr, "PUSH_ALTS_D " ); printPtr( ptrs[instrs[pc]] );
93 fprintf(stderr, "\n");
96 fprintf(stderr, "PUSH_ALTS_L " ); printPtr( ptrs[instrs[pc]] );
97 fprintf(stderr, "\n");
100 fprintf(stderr, "PUSH_ALTS_V " ); printPtr( ptrs[instrs[pc]] );
101 fprintf(stderr, "\n");
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");
110 case bci_PUSH_APPLY_N:
111 fprintf(stderr, "PUSH_APPLY_N\n");
113 case bci_PUSH_APPLY_V:
114 fprintf(stderr, "PUSH_APPLY_V\n");
116 case bci_PUSH_APPLY_F:
117 fprintf(stderr, "PUSH_APPLY_F\n");
119 case bci_PUSH_APPLY_D:
120 fprintf(stderr, "PUSH_APPLY_D\n");
122 case bci_PUSH_APPLY_L:
123 fprintf(stderr, "PUSH_APPLY_L\n");
125 case bci_PUSH_APPLY_P:
126 fprintf(stderr, "PUSH_APPLY_P\n");
128 case bci_PUSH_APPLY_PP:
129 fprintf(stderr, "PUSH_APPLY_PP\n");
131 case bci_PUSH_APPLY_PPP:
132 fprintf(stderr, "PUSH_APPLY_PPP\n");
134 case bci_PUSH_APPLY_PPPP:
135 fprintf(stderr, "PUSH_APPLY_PPPP\n");
137 case bci_PUSH_APPLY_PPPPP:
138 fprintf(stderr, "PUSH_APPLY_PPPPP\n");
140 case bci_PUSH_APPLY_PPPPPP:
141 fprintf(stderr, "PUSH_APPLY_PPPPPP\n");
143 case bci_PUSH_APPLY_PPPPPPP:
144 fprintf(stderr, "PUSH_APPLY_PPPPPPP\n");
147 fprintf(stderr, "SLIDE %d down by %d\n", instrs[pc], instrs[pc+1] );
150 fprintf(stderr, "ALLOC_AP %d words\n", instrs[pc] );
153 fprintf(stderr, "ALLOC_PAP %d words, %d arity\n",
154 instrs[pc], instrs[pc+1] );
157 fprintf(stderr, "MKAP %d words, %d stkoff\n", instrs[pc+1],
161 fprintf(stderr, "UNPACK %d\n", instrs[pc] );
164 fprintf(stderr, "PACK %d words with itbl ", instrs[pc+1] );
165 printPtr( (StgPtr)itbls[instrs[pc]] );
166 fprintf(stderr, "\n");
170 fprintf(stderr, "TESTLT_I %d, fail to %d\n", literals[instrs[pc]],
174 fprintf(stderr, "TESTEQ_I %d, fail to %d\n", literals[instrs[pc]],
179 fprintf(stderr, "TESTLT_F %d, fail to %d\n", literals[instrs[pc]],
183 fprintf(stderr, "TESTEQ_F %d, fail to %d\n", literals[instrs[pc]],
188 fprintf(stderr, "TESTLT_D %d, fail to %d\n", literals[instrs[pc]],
192 fprintf(stderr, "TESTEQ_D %d, fail to %d\n", literals[instrs[pc]],
197 fprintf(stderr, "TESTLT_P %d, fail to %d\n", instrs[pc],
201 fprintf(stderr, "TESTEQ_P %d, fail to %d\n", instrs[pc],
205 fprintf(stderr, "CASEFAIL\n" );
208 fprintf(stderr, "JMP to %d\n", instrs[pc]);
212 fprintf(stderr, "ENTER\n");
216 fprintf(stderr, "RETURN\n" );
219 fprintf(stderr, "RETURN_P\n" );
222 fprintf(stderr, "RETURN_N\n" );
225 fprintf(stderr, "RETURN_F\n" );
228 fprintf(stderr, "RETURN_D\n" );
231 fprintf(stderr, "RETURN_L\n" );
234 fprintf(stderr, "RETURN_V\n" );
238 barf("disInstr: unknown opcode");
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 ...
249 void disassemble( StgBCO *bco )
252 StgWord16* instrs = (StgWord16*)(bco->instrs->payload);
253 StgMutArrPtrs* ptrs = bco->ptrs;
254 nat nbcs = (int)instrs[0];
257 fprintf(stderr, "BCO\n" );
260 fprintf(stderr, "\t%2d: ", pc );
261 pc = disInstr ( bco, pc );
264 fprintf(stderr, "INSTRS:\n " );
266 for (i = 0; i < nbcs; i++) {
267 fprintf(stderr, "%3d ", (int)instrs[i] );
269 if (j == 0) { j = 16; fprintf(stderr, "\n "); };
271 fprintf(stderr, "\n");
273 fprintf(stderr, "PTRS:\n " );
275 for (i = 0; i < ptrs->ptrs; i++) {
276 fprintf(stderr, "%8p ", ptrs->payload[i] );
278 if (j == 0) { j = 8; fprintf(stderr, "\n "); };
280 fprintf(stderr, "\n");
282 fprintf(stderr, "\n");
283 ASSERT(pc == nbcs+1);