2 /* -----------------------------------------------------------------------------
3 * Bytecode disassembler
5 * Copyright (c) 1994-1998.
7 * $RCSfile: Disassembler.c,v $
9 * $Date: 2002/07/17 09:21:49 $
10 * ---------------------------------------------------------------------------*/
14 #include "PosixSource.h"
22 #include "Bytecodes.h"
24 #include "Disassembler.h"
25 #include "Interpreter.h"
29 /* --------------------------------------------------------------------------
31 * ------------------------------------------------------------------------*/
33 int disInstr ( StgBCO *bco, int pc )
37 StgArrWords* instr_arr = bco->instrs;
38 UShort* instrs = (UShort*)(&instr_arr->payload[0]);
40 StgArrWords* literal_arr = bco->literals;
41 StgWord* literals = (StgWord*)(&literal_arr->payload[0]);
43 StgMutArrPtrs* ptrs_arr = bco->ptrs;
44 StgPtr* ptrs = (StgPtr*)(&ptrs_arr->payload[0]);
46 StgArrWords* itbls_arr = bco->itbls;
47 StgInfoTable** itbls = (StgInfoTable**)(&itbls_arr->payload[0]);
49 switch (instrs[pc++]) {
51 fprintf(stderr, "SWIZZLE stkoff %d by %d\n",
52 instrs[pc], (signed int)instrs[pc+1]);
55 fprintf(stderr, "CCALL marshaller at 0x%x\n",
56 literals[instrs[pc]] );
59 fprintf(stderr, "STKCHECK %d\n", instrs[pc] );
62 fprintf(stderr, "ARGCHECK %d\n", instrs[pc] );
65 fprintf(stderr, "PUSH_L %d\n", instrs[pc] );
68 fprintf(stderr, "PUSH_LL %d %d\n", instrs[pc], instrs[pc+1] );
71 fprintf(stderr, "PUSH_LLL %d %d %d\n", instrs[pc], instrs[pc+1],
75 fprintf(stderr, "PUSH_G " ); printPtr( ptrs[instrs[pc]] );
76 fprintf(stderr, "\n" );
79 fprintf(stderr, "PUSH_AS " ); printPtr( ptrs[instrs[pc]] );
80 fprintf(stderr, " 0x%x", literals[instrs[pc+1]] );
81 fprintf(stderr, "\n");
84 fprintf(stderr, "PUSH_UBX ");
85 for (i = 0; i < instrs[pc+1]; i++)
86 fprintf(stderr, "0x%x ", literals[i + instrs[pc]] );
87 fprintf(stderr, "\n");
90 fprintf(stderr, "PUSH_TAG %d\n", instrs[pc] );
93 fprintf(stderr, "SLIDE %d down by %d\n", instrs[pc], instrs[pc+1] );
96 fprintf(stderr, "ALLOC %d words\n", instrs[pc] );
99 fprintf(stderr, "MKAP %d words, %d stkoff\n", instrs[pc+1],
103 fprintf(stderr, "UNPACK %d\n", instrs[pc] );
106 fprintf(stderr, "UPK_TAG %d words, %d conoff, %d stkoff\n",
107 instrs[pc], instrs[pc+1], instrs[pc+2] );
110 fprintf(stderr, "PACK %d words with itbl ", instrs[pc+1] );
111 printPtr( (StgPtr)itbls[instrs[pc]] );
112 fprintf(stderr, "\n");
116 fprintf(stderr, "CASEFAIL\n" );
119 fprintf(stderr, "JMP to %d\n", instrs[pc]);
123 fprintf(stderr, "TESTLT_I %d, fail to %d\n", literals[instrs[pc]],
127 fprintf(stderr, "TESTEQ_I %d, fail to %d\n", literals[instrs[pc]],
132 fprintf(stderr, "TESTLT_F %d, fail to %d\n", literals[instrs[pc]],
136 fprintf(stderr, "TESTEQ_F %d, fail to %d\n", literals[instrs[pc]],
141 fprintf(stderr, "TESTLT_D %d, fail to %d\n", literals[instrs[pc]],
145 fprintf(stderr, "TESTEQ_D %d, fail to %d\n", literals[instrs[pc]],
150 fprintf(stderr, "TESTLT_P %d, fail to %d\n", instrs[pc],
154 fprintf(stderr, "TESTEQ_P %d, fail to %d\n", instrs[pc],
158 fprintf(stderr, "RETURN " ); printPtr( (StgPtr)itbls[instrs[pc]] );
159 fprintf(stderr, "\n");
162 fprintf(stderr, "ENTER\n");
165 barf("disInstr: unknown opcode");
171 /* Something of a kludge .. how do we know where the end of the insn
172 array is, since it isn't recorded anywhere? Answer: the first
173 short is the number of bytecodes which follow it.
174 See ByteCodeGen.linkBCO.insns_arr for construction ...
176 void disassemble( StgBCO *bco )
179 StgArrWords* instr_arr = bco->instrs;
180 UShort* instrs = (UShort*)(&instr_arr->payload[0]);
181 StgMutArrPtrs* ptrs = bco->ptrs;
182 nat nbcs = (int)instrs[0];
185 fprintf(stderr, "BCO\n" );
188 fprintf(stderr, "\t%2d: ", pc );
189 pc = disInstr ( bco, pc );
192 fprintf(stderr, "INSTRS:\n " );
194 for (i = 0; i < nbcs; i++) {
195 fprintf(stderr, "%3d ", (int)instrs[i] );
197 if (j == 0) { j = 16; fprintf(stderr, "\n "); };
199 fprintf(stderr, "\n");
201 fprintf(stderr, "PTRS:\n " );
203 for (i = 0; i < ptrs->ptrs; i++) {
204 fprintf(stderr, "%8p ", ptrs->payload[i] );
206 if (j == 0) { j = 8; fprintf(stderr, "\n "); };
208 fprintf(stderr, "\n");
210 fprintf(stderr, "\n");
211 ASSERT(pc == nbcs+1);