2 /* -----------------------------------------------------------------------------
3 * Bytecode disassembler
5 * Copyright (c) 1994-1998.
7 * $RCSfile: Disassembler.c,v $
9 * $Date: 2000/06/15 13:23:51 $
10 * ---------------------------------------------------------------------------*/
17 #include "Bytecodes.h"
18 #include "Assembler.h"
20 #include "Disassembler.h"
22 /* --------------------------------------------------------------------------
24 * ------------------------------------------------------------------------*/
26 static InstrPtr disNone ( StgBCO *bco, InstrPtr pc, char* i );
27 static InstrPtr disInt ( StgBCO *bco, InstrPtr pc, char* i );
28 static InstrPtr disIntInt ( StgBCO *bco, InstrPtr pc, char* i );
29 static InstrPtr disInfo ( StgBCO *bco, InstrPtr pc, char* i );
30 static InstrPtr disConstPtr ( StgBCO *bco, InstrPtr pc, char* i );
31 static InstrPtr disConstInt ( StgBCO *bco, InstrPtr pc, char* i );
32 static InstrPtr disConstChar ( StgBCO *bco, InstrPtr pc, char* i );
33 static InstrPtr disConstFloat ( StgBCO *bco, InstrPtr pc, char* i );
35 static InstrPtr disNone ( StgBCO *bco, InstrPtr pc, char* i )
37 fprintf(stderr,"%s",i);
41 static InstrPtr disInt ( StgBCO *bco, InstrPtr pc, char* i )
43 StgInt x = bcoInstr(bco,pc++);
44 ASSERT(pc <= bco->n_instrs);
45 fprintf(stderr,"%s %d",i,x);
49 static InstrPtr disInt16 ( StgBCO *bco, InstrPtr pc, char* i )
51 StgInt x = bcoInstr16(bco,pc); pc+=2;
52 ASSERT(pc <= bco->n_instrs);
53 fprintf(stderr,"%s %d",i,x);
57 static InstrPtr disIntInt ( StgBCO *bco, InstrPtr pc, char* i )
59 StgInt x = bcoInstr(bco,pc++);
60 StgInt y = bcoInstr(bco,pc++);
61 fprintf(stderr,"%s %d %d",i,x,y);
65 static InstrPtr disIntInt16 ( StgBCO *bco, InstrPtr pc, char* i )
68 x = bcoInstr16(bco,pc); pc += 2;
69 y = bcoInstr16(bco,pc); pc += 2;
70 fprintf(stderr,"%s %d %d",i,x,y);
74 static InstrPtr disIntPC ( StgBCO *bco, InstrPtr pc, char* i )
78 x = bcoInstr(bco,pc++);
79 y = bcoInstr16(bco,pc); pc += 2;
80 fprintf(stderr,"%s %d %d",i,x,pc+y);
85 static InstrPtr disInt16PC ( StgBCO *bco, InstrPtr pc, char* i )
89 x = bcoInstr(bco,pc); pc += 2;
90 y = bcoInstr16(bco,pc); pc += 2;
91 fprintf(stderr,"%s %d %d",i,x,pc+y);
96 static InstrPtr disPC ( StgBCO *bco, InstrPtr pc, char* i )
98 StgWord y = bcoInstr16(bco,pc); pc += 2;
99 fprintf(stderr,"%s %d",i,pc+y);
103 static InstrPtr disInfo ( StgBCO *bco, InstrPtr pc, char* i )
105 StgInfoTable* info = bcoConstInfoPtr(bco,bcoInstr(bco,pc++));
106 /* ToDo: print contents of infotable */
107 fprintf(stderr,"%s ",i);
108 printPtr(stgCast(StgPtr,info));
112 static InstrPtr disInfo16 ( StgBCO *bco, InstrPtr pc, char* i )
114 StgWord x = bcoInstr16(bco,pc);
115 StgInfoTable* info = bcoConstInfoPtr(bco,x);
117 /* ToDo: print contents of infotable */
118 fprintf(stderr,"%s ",i);
119 printPtr(stgCast(StgPtr,info));
123 static InstrPtr disConstPtr ( StgBCO *bco, InstrPtr pc, char* i )
125 StgInt o = bcoInstr(bco,pc++);
126 StgPtr x = bcoConstPtr(bco,o);
127 fprintf(stderr,"%s [%d]=",i,o);
128 printPtr(x); /* bad way to print it... */
132 static InstrPtr disConstPtr16 ( StgBCO *bco, InstrPtr pc, char* i )
136 o = bcoInstr16(bco,pc); pc += 2;
137 x = bcoConstPtr(bco,o);
138 fprintf(stderr,"%s [%d]=",i,o);
139 printPtr(x); /* bad way to print it... */
143 static InstrPtr disConstInt ( StgBCO *bco, InstrPtr pc, char* i )
145 StgInt x = bcoConstInt(bco,bcoInstr(bco,pc++));
146 fprintf(stderr,"%s %d (0x%x)",i,x,x);
150 static InstrPtr disConstInt16 ( StgBCO *bco, InstrPtr pc, char* i )
152 StgInt x = bcoConstInt(bco,bcoInstr16(bco,pc)); pc += 2;
153 fprintf(stderr,"%s %d (0x%x)",i,x,x);
157 static InstrPtr disConstAddr ( StgBCO *bco, InstrPtr pc, char* i )
159 StgAddr x = bcoConstAddr(bco,bcoInstr(bco,pc++));
160 fprintf(stderr,"%s ",i);
165 static InstrPtr disConstAddr16 ( StgBCO *bco, InstrPtr pc, char* i )
167 StgAddr x = bcoConstAddr(bco,bcoInstr16(bco,pc)); pc += 2;
168 fprintf(stderr,"%s ",i);
173 static InstrPtr disConstChar ( StgBCO *bco, InstrPtr pc, char* i )
175 StgChar x = bcoConstChar(bco,bcoInstr(bco,pc++));
177 fprintf(stderr,"%s '%c'",i,x); else
178 fprintf(stderr,"%s 0x%x",i,(int)x);
182 static InstrPtr disConstChar16 ( StgBCO *bco, InstrPtr pc, char* i )
184 StgChar x = bcoConstChar(bco,bcoInstr16(bco,pc)); pc += 2;
186 fprintf(stderr,"%s '%c'",i,x); else
187 fprintf(stderr,"%s 0x%x",i,(int)x);
191 static InstrPtr disConstFloat ( StgBCO *bco, InstrPtr pc, char* i )
193 StgFloat x = bcoConstFloat(bco,bcoInstr(bco,pc++));
194 fprintf(stderr,"%s %f",i,x);
198 static InstrPtr disConstFloat16 ( StgBCO *bco, InstrPtr pc, char* i )
200 StgFloat x = bcoConstFloat(bco,bcoInstr16(bco,pc)); pc += 2;
201 fprintf(stderr,"%s %f",i,x);
205 static InstrPtr disConstDouble ( StgBCO *bco, InstrPtr pc, char* i )
207 StgDouble x = bcoConstDouble(bco,bcoInstr(bco,pc++));
208 fprintf(stderr,"%s %f",i,x);
212 static InstrPtr disConstDouble16 ( StgBCO *bco, InstrPtr pc, char* i )
214 StgDouble x = bcoConstDouble(bco,bcoInstr16(bco,pc)); pc += 2;
215 fprintf(stderr,"%s %f",i,x);
219 InstrPtr disInstr( StgBCO *bco, InstrPtr pc )
222 ASSERT(pc < bco->n_instrs);
223 in = bcoInstr(bco,pc++);
225 case i_INTERNAL_ERROR:
226 return disNone(bco,pc,"INTERNAL_ERROR");
228 return disNone(bco,pc,"PANIC");
230 return disInt(bco,pc,"STK_CHECK");
231 case i_STK_CHECK_big:
232 return disInt16(bco,pc,"STK_CHECK_big");
234 return disInt(bco,pc,"ARG_CHECK");
236 return disInt(bco,pc,"ALLOC_AP");
238 return disInt(bco,pc,"ALLOC_PAP");
240 return disInfo(bco,pc,"ALLOC_CONSTR");
241 case i_ALLOC_CONSTR_big:
242 return disInfo16(bco,pc,"ALLOC_CONSTR_big");
244 return disIntInt(bco,pc,"MKAP");
246 return disIntInt16(bco,pc,"MKAP_big");
248 return disIntInt(bco,pc,"MKPAP");
250 return disInt(bco,pc,"PACK");
252 return disIntInt(bco,pc,"SLIDE");
254 return disIntInt(bco,pc,"R_V");
256 return disIntInt(bco,pc,"R_V_E");
258 return disIntInt(bco,pc,"V_V");
260 return disIntInt(bco,pc,"S_E");
262 return disIntInt16(bco,pc,"SLIDE_big");
264 return disNone(bco,pc,"ENTER");
266 return disConstPtr(bco,pc,"RETADDR");
268 return disConstPtr16(bco,pc,"RETADDR_big");
270 return disIntPC(bco,pc,"TEST");
272 return disNone(bco,pc,"UNPACK");
274 return disInt(bco,pc,"VAR");
276 return disInt16(bco,pc,"VAR_big");
278 return disConstPtr(bco,pc,"CONST");
280 return disConstPtr16(bco,pc,"CONST_big");
284 return disInt(bco,pc,"ALLOC_ROW");
285 case i_ALLOC_ROW_big:
286 return disInt16(bco,pc,"ALLOC_ROW_big");
288 return disInt(bco,pc,"PACK_ROW");
290 return disInt16(bco,pc,"PACK_ROW_big");
293 return disInt(bco,pc,"PACK_INJ");
295 return disInt16(bco,pc,"PACK_INJ_big");
296 case i_PACK_INJ_CONST:
297 return disInt(bco,pc,"PACK_INJ_CONST");
300 return disNone(bco,pc,"UNPACK_ROW");
302 return disNone(bco,pc,"UNPACK_INJ");
305 return disIntPC(bco,pc,"TEST_INJ");
307 return disInt16PC(bco,pc,"TEST_INJ_big");
308 case i_TEST_INJ_CONST:
309 return disIntPC(bco,pc,"TEST_INJ_CONST");
313 return disNone(bco,pc,"VOID");
316 return disInt(bco,pc,"VAR_INT");
318 return disInt16(bco,pc,"VAR_INT_big");
320 return disConstInt(bco,pc,"CONST_INT");
321 case i_CONST_INT_big:
322 return disConstInt16(bco,pc,"CONST_INT_big");
324 return disNone(bco,pc,"PACK_INT");
326 return disNone(bco,pc,"UNPACK_INT");
328 return disPC(bco,pc,"TEST_INT");
330 case i_CONST_INTEGER:
331 return disConstAddr(bco,pc,"CONST_INTEGER");
332 case i_CONST_INTEGER_big:
333 return disConstAddr16(bco,pc,"CONST_INTEGER_big");
336 return disInt(bco,pc,"VAR_WORD");
338 return disConstInt(bco,pc,"CONST_WORD");
340 return disNone(bco,pc,"PACK_WORD");
342 return disNone(bco,pc,"UNPACK_WORD");
345 return disInt(bco,pc,"VAR_ADDR");
347 return disInt16(bco,pc,"VAR_ADDR_big");
349 return disConstAddr(bco,pc,"CONST_ADDR");
350 case i_CONST_ADDR_big:
351 return disConstAddr16(bco,pc,"CONST_ADDR_big");
353 return disNone(bco,pc,"PACK_ADDR");
355 return disNone(bco,pc,"UNPACK_ADDR");
358 return disInt(bco,pc,"VAR_CHAR");
360 return disInt16(bco,pc,"VAR_CHAR_big");
362 return disConstChar(bco,pc,"CONST_CHAR");
363 case i_CONST_CHAR_big:
364 return disConstChar16(bco,pc,"CONST_CHAR_big");
366 return disNone(bco,pc,"PACK_CHAR");
368 return disNone(bco,pc,"UNPACK_CHAR");
371 return disInt(bco,pc,"VAR_FLOAT");
372 case i_VAR_FLOAT_big:
373 return disInt16(bco,pc,"VAR_FLOAT_big");
375 return disConstFloat(bco,pc,"CONST_FLOAT");
376 case i_CONST_FLOAT_big:
377 return disConstFloat16(bco,pc,"CONST_FLOAT_big");
379 return disNone(bco,pc,"PACK_FLOAT");
381 return disNone(bco,pc,"UNPACK_FLOAT");
384 return disInt(bco,pc,"VAR_DOUBLE");
385 case i_VAR_DOUBLE_big:
386 return disInt16(bco,pc,"VAR_DOUBLE_big");
388 return disConstDouble(bco,pc,"CONST_DOUBLE");
389 case i_CONST_DOUBLE_big:
390 return disConstDouble16(bco,pc,"CONST_DOUBLE_big");
392 return disNone(bco,pc,"PACK_DOUBLE");
393 case i_UNPACK_DOUBLE:
394 return disNone(bco,pc,"UNPACK_DOUBLE");
397 return disInt(bco,pc,"VAR_STABLE");
399 return disNone(bco,pc,"PACK_STABLE");
400 case i_UNPACK_STABLE:
401 return disNone(bco,pc,"UNPACK_STABLE");
405 Primop1 op = bcoInstr(bco,pc++);
407 case i_INTERNAL_ERROR1:
408 return disNone(bco,pc,"INTERNAL_ERROR1");
410 return disNone(bco,pc,"i_pushseqframe");
411 case i_pushcatchframe:
412 return disNone(bco,pc,"i_pushcatchframe");
415 const AsmPrim* p = asmFindPrimop(i_PRIMOP1,op);
417 return disNone(bco,pc,p->name);
419 barf("Unrecognised primop1 %d\n",op);
425 Primop2 op = bcoInstr(bco,pc++);
427 case i_INTERNAL_ERROR2:
428 return disNone(bco,pc,"INTERNAL_ERROR2");
429 case i_ccall_ccall_Id:
430 return disNone(bco,pc,"ccall_ccall_Id");
431 case i_ccall_ccall_IO:
432 return disNone(bco,pc,"ccall_ccall_IO");
433 case i_ccall_stdcall_Id:
434 return disNone(bco,pc,"ccall_stdcall_Id");
435 case i_ccall_stdcall_IO:
436 return disNone(bco,pc,"ccall_stdcall_IO");
438 return disNone(bco,pc,"primRaise");
440 return disNone(bco,pc,"primTakeMVar");
443 const AsmPrim* p = asmFindPrimop(i_PRIMOP2,op);
445 return disNone(bco,pc,p->name);
447 barf("Unrecognised primop2 %d\n",op);
452 barf("Unrecognised instruction %d\n",in);
456 void disassemble( StgBCO *bco, char* prefix )
459 int pcLim = bco->n_instrs;
460 ASSERT( get_itbl(bco)->type == BCO);
462 fprintf(stderr,"%s%d:\t",prefix,pc);
463 pc = disInstr(bco,pc);
464 fprintf(stderr,"\n");
467 ppStgExpr(bco->stgexpr);
468 fprintf(stderr, "\n");
471 fprintf(stderr, "\t(no associated tree)\n" );
474 #endif /* INTERPRETER */