2 /* -----------------------------------------------------------------------------
3 * Bytecode disassembler
5 * Copyright (c) 1994-1998.
7 * $RCSfile: Disassembler.c,v $
9 * $Date: 2000/10/09 11:20:16 $
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);
94 static InstrPtr disIntIntPC ( StgBCO *bco, InstrPtr pc, char* i )
98 x = bcoInstr(bco,pc++);
99 y = bcoInstr(bco,pc++);
100 z = bcoInstr16(bco,pc); pc += 2;
101 fprintf(stderr,"%s %d %d %d",i,x,y,pc+z);
106 static InstrPtr disPC ( StgBCO *bco, InstrPtr pc, char* i )
108 StgWord y = bcoInstr16(bco,pc); pc += 2;
109 fprintf(stderr,"%s %d",i,pc+y);
113 static InstrPtr disInfo ( StgBCO *bco, InstrPtr pc, char* i )
115 StgInfoTable* info = bcoConstInfoPtr(bco,bcoInstr(bco,pc++));
116 /* ToDo: print contents of infotable */
117 fprintf(stderr,"%s ",i);
118 printPtr(stgCast(StgPtr,info));
122 static InstrPtr disInfo16 ( StgBCO *bco, InstrPtr pc, char* i )
124 StgWord x = bcoInstr16(bco,pc);
125 StgInfoTable* info = bcoConstInfoPtr(bco,x);
127 /* ToDo: print contents of infotable */
128 fprintf(stderr,"%s ",i);
129 printPtr(stgCast(StgPtr,info));
133 static InstrPtr disConstPtr ( StgBCO *bco, InstrPtr pc, char* i )
135 StgInt o = bcoInstr(bco,pc++);
136 StgPtr x = bcoConstPtr(bco,o);
137 fprintf(stderr,"%s [%d]=",i,o);
138 printPtr(x); /* bad way to print it... */
142 static InstrPtr disConstPtr16 ( StgBCO *bco, InstrPtr pc, char* i )
146 o = bcoInstr16(bco,pc); pc += 2;
147 x = bcoConstPtr(bco,o);
148 fprintf(stderr,"%s [%d]=",i,o);
149 printPtr(x); /* bad way to print it... */
153 static InstrPtr disConstInt ( StgBCO *bco, InstrPtr pc, char* i )
155 StgInt x = bcoConstInt(bco,bcoInstr(bco,pc++));
156 fprintf(stderr,"%s %d (0x%x)",i,x,x);
160 static InstrPtr disConstInt16 ( StgBCO *bco, InstrPtr pc, char* i )
162 StgInt x = bcoConstInt(bco,bcoInstr16(bco,pc)); pc += 2;
163 fprintf(stderr,"%s %d (0x%x)",i,x,x);
167 static InstrPtr disConstAddr ( StgBCO *bco, InstrPtr pc, char* i )
169 StgAddr x = bcoConstAddr(bco,bcoInstr(bco,pc++));
170 fprintf(stderr,"%s ",i);
175 static InstrPtr disConstAddr16 ( StgBCO *bco, InstrPtr pc, char* i )
177 StgAddr x = bcoConstAddr(bco,bcoInstr16(bco,pc)); pc += 2;
178 fprintf(stderr,"%s ",i);
183 static InstrPtr disConstChar ( StgBCO *bco, InstrPtr pc, char* i )
185 StgChar x = bcoConstChar(bco,bcoInstr(bco,pc++));
187 fprintf(stderr,"%s '%c'",i,x); else
188 fprintf(stderr,"%s 0x%x",i,(int)x);
192 static InstrPtr disConstChar16 ( StgBCO *bco, InstrPtr pc, char* i )
194 StgChar x = bcoConstChar(bco,bcoInstr16(bco,pc)); pc += 2;
196 fprintf(stderr,"%s '%c'",i,x); else
197 fprintf(stderr,"%s 0x%x",i,(int)x);
201 static InstrPtr disConstFloat ( StgBCO *bco, InstrPtr pc, char* i )
203 StgFloat x = bcoConstFloat(bco,bcoInstr(bco,pc++));
204 fprintf(stderr,"%s %f",i,x);
208 static InstrPtr disConstFloat16 ( StgBCO *bco, InstrPtr pc, char* i )
210 StgFloat x = bcoConstFloat(bco,bcoInstr16(bco,pc)); pc += 2;
211 fprintf(stderr,"%s %f",i,x);
215 static InstrPtr disConstDouble ( StgBCO *bco, InstrPtr pc, char* i )
217 StgDouble x = bcoConstDouble(bco,bcoInstr(bco,pc++));
218 fprintf(stderr,"%s %f",i,x);
222 static InstrPtr disConstDouble16 ( StgBCO *bco, InstrPtr pc, char* i )
224 StgDouble x = bcoConstDouble(bco,bcoInstr16(bco,pc)); pc += 2;
225 fprintf(stderr,"%s %f",i,x);
229 InstrPtr disInstr( StgBCO *bco, InstrPtr pc )
232 ASSERT(pc < bco->n_instrs);
233 in = bcoInstr(bco,pc++);
235 case i_INTERNAL_ERROR:
236 return disNone(bco,pc,"INTERNAL_ERROR");
238 return disNone(bco,pc,"PANIC");
240 return disInt(bco,pc,"STK_CHECK");
241 case i_STK_CHECK_big:
242 return disInt16(bco,pc,"STK_CHECK_big");
244 return disInt(bco,pc,"ARG_CHECK");
246 return disInt(bco,pc,"ALLOC_AP");
248 return disInt(bco,pc,"ALLOC_PAP");
250 return disInfo(bco,pc,"ALLOC_CONSTR");
251 case i_ALLOC_CONSTR_big:
252 return disInfo16(bco,pc,"ALLOC_CONSTR_big");
254 return disIntInt(bco,pc,"MKAP");
256 return disIntInt16(bco,pc,"MKAP_big");
258 return disIntInt(bco,pc,"MKPAP");
260 return disInt(bco,pc,"PACK");
262 return disIntInt(bco,pc,"SLIDE");
264 return disIntInt(bco,pc,"R_V");
266 return disIntInt(bco,pc,"R_V_E");
268 return disIntInt(bco,pc,"V_V");
270 return disIntInt(bco,pc,"S_E");
272 return disIntInt16(bco,pc,"SLIDE_big");
274 return disNone(bco,pc,"ENTER");
276 return disConstPtr(bco,pc,"RETADDR");
278 return disConstPtr16(bco,pc,"RETADDR_big");
280 return disIntPC(bco,pc,"TEST");
282 return disNone(bco,pc,"UNPACK");
284 return disInt(bco,pc,"VAR");
286 return disInt16(bco,pc,"VAR_big");
288 return disConstPtr(bco,pc,"CONST");
290 return disConstPtr16(bco,pc,"CONST_big");
294 return disInt(bco,pc,"ALLOC_ROW");
295 case i_ALLOC_ROW_big:
296 return disInt16(bco,pc,"ALLOC_ROW_big");
298 return disInt(bco,pc,"PACK_ROW");
300 return disInt16(bco,pc,"PACK_ROW_big");
302 return disNone(bco,pc,"UNPACK_ROW");
303 case i_CONST_ROW_TRIV:
304 return disNone(bco,pc,"CONST_ROW_TRIV");
307 return disInt(bco,pc,"PACK_INJ_VAR");
308 case i_PACK_INJ_VAR_big:
309 return disInt16(bco,pc,"PACK_INJ_VAR_big");
310 case i_PACK_INJ_CONST_8:
311 return disInt(bco,pc,"PACK_INJ_CONST_8");
312 case i_PACK_INJ_REL_8:
313 return disIntInt(bco,pc,"PACK_INJ_REL_8");
315 return disNone(bco,pc,"PACK_INJ");
318 return disNone(bco,pc,"UNPACK_INJ");
321 return disIntPC(bco,pc,"TEST_INJ_VAR");
322 case i_TEST_INJ_VAR_big:
323 return disInt16PC(bco,pc,"TEST_INJ_VAR_big");
324 case i_TEST_INJ_CONST_8:
325 return disIntPC(bco,pc,"TEST_INJ_CONST_8");
326 case i_TEST_INJ_REL_8:
327 return disIntIntPC(bco,pc,"TEST_INJ_REL_8");
329 return disPC(bco,pc,"TEST_INJ");
332 return disInt(bco,pc,"CONST_WORD_8");
334 return disInt(bco,pc,"ADD_WORD_VAR");
335 case i_ADD_WORD_VAR_big:
336 return disInt16(bco,pc,"ADD_WORD_VAR_big");
337 case i_ADD_WORD_VAR_8:
338 return disIntInt(bco,pc,"ADD_WORD_VAR_8");
342 return disNone(bco,pc,"VOID");
345 return disInt(bco,pc,"VAR_INT");
347 return disInt16(bco,pc,"VAR_INT_big");
349 return disConstInt(bco,pc,"CONST_INT");
350 case i_CONST_INT_big:
351 return disConstInt16(bco,pc,"CONST_INT_big");
353 return disNone(bco,pc,"PACK_INT");
355 return disNone(bco,pc,"UNPACK_INT");
357 return disPC(bco,pc,"TEST_INT");
359 case i_CONST_INTEGER:
360 return disConstAddr(bco,pc,"CONST_INTEGER");
361 case i_CONST_INTEGER_big:
362 return disConstAddr16(bco,pc,"CONST_INTEGER_big");
365 return disInt(bco,pc,"VAR_WORD");
367 return disConstInt(bco,pc,"CONST_WORD");
368 case i_CONST_WORD_big:
369 return disConstInt16(bco,pc,"CONST_WORD_big");
371 return disNone(bco,pc,"PACK_WORD");
373 return disNone(bco,pc,"UNPACK_WORD");
376 return disInt(bco,pc,"VAR_ADDR");
378 return disInt16(bco,pc,"VAR_ADDR_big");
380 return disConstAddr(bco,pc,"CONST_ADDR");
381 case i_CONST_ADDR_big:
382 return disConstAddr16(bco,pc,"CONST_ADDR_big");
384 return disNone(bco,pc,"PACK_ADDR");
386 return disNone(bco,pc,"UNPACK_ADDR");
389 return disInt(bco,pc,"VAR_CHAR");
391 return disInt16(bco,pc,"VAR_CHAR_big");
393 return disConstChar(bco,pc,"CONST_CHAR");
394 case i_CONST_CHAR_big:
395 return disConstChar16(bco,pc,"CONST_CHAR_big");
397 return disNone(bco,pc,"PACK_CHAR");
399 return disNone(bco,pc,"UNPACK_CHAR");
402 return disInt(bco,pc,"VAR_FLOAT");
403 case i_VAR_FLOAT_big:
404 return disInt16(bco,pc,"VAR_FLOAT_big");
406 return disConstFloat(bco,pc,"CONST_FLOAT");
407 case i_CONST_FLOAT_big:
408 return disConstFloat16(bco,pc,"CONST_FLOAT_big");
410 return disNone(bco,pc,"PACK_FLOAT");
412 return disNone(bco,pc,"UNPACK_FLOAT");
415 return disInt(bco,pc,"VAR_DOUBLE");
416 case i_VAR_DOUBLE_big:
417 return disInt16(bco,pc,"VAR_DOUBLE_big");
419 return disConstDouble(bco,pc,"CONST_DOUBLE");
420 case i_CONST_DOUBLE_big:
421 return disConstDouble16(bco,pc,"CONST_DOUBLE_big");
423 return disNone(bco,pc,"PACK_DOUBLE");
424 case i_UNPACK_DOUBLE:
425 return disNone(bco,pc,"UNPACK_DOUBLE");
428 return disInt(bco,pc,"VAR_STABLE");
430 return disNone(bco,pc,"PACK_STABLE");
431 case i_UNPACK_STABLE:
432 return disNone(bco,pc,"UNPACK_STABLE");
436 Primop1 op = bcoInstr(bco,pc++);
438 case i_INTERNAL_ERROR1:
439 return disNone(bco,pc,"INTERNAL_ERROR1");
441 return disNone(bco,pc,"i_pushseqframe");
442 case i_pushcatchframe:
443 return disNone(bco,pc,"i_pushcatchframe");
446 const AsmPrim* p = asmFindPrimop(i_PRIMOP1,op);
448 return disNone(bco,pc,p->name);
450 barf("Unrecognised primop1 %d\n",op);
456 Primop2 op = bcoInstr(bco,pc++);
458 case i_INTERNAL_ERROR2:
459 return disNone(bco,pc,"INTERNAL_ERROR2");
462 return disNone(bco,pc,"ROW_INSERT_1");
463 case i_rowChainInsert:
464 return disNone(bco,pc,"ROW_INSERT");
465 case i_rowChainBuild:
466 return disNone(bco,pc,"ROW_BUILD");
468 return disNone(bco,pc,"ROW_REMOVE_1");
469 case i_rowChainRemove:
470 return disNone(bco,pc,"ROW_REMOVE");
471 case i_rowChainSelect:
472 return disNone(bco,pc,"ROW_SELECT");
474 return disNone(bco,pc,"ccall");
476 case i_ccall_ccall_Id:
477 return disNone(bco,pc,"ccall_ccall_Id");
478 case i_ccall_ccall_IO:
479 return disNone(bco,pc,"ccall_ccall_IO");
480 case i_ccall_stdcall_Id:
481 return disNone(bco,pc,"ccall_stdcall_Id");
482 case i_ccall_stdcall_IO:
483 return disNone(bco,pc,"ccall_stdcall_IO");
485 return disNone(bco,pc,"primRaise");
487 return disNone(bco,pc,"primTakeMVar");
490 const AsmPrim* p = asmFindPrimop(i_PRIMOP2,op);
492 return disNone(bco,pc,p->name);
494 barf("Unrecognised primop2 %d\n",op);
499 barf("Unrecognised instruction %d\n",in);
503 void disassemble( StgBCO *bco, char* prefix )
506 int pcLim = bco->n_instrs;
507 ASSERT( get_itbl(bco)->type == BCO);
509 fprintf(stderr,"%s%d:\t",prefix,pc);
510 pc = disInstr(bco,pc);
511 fprintf(stderr,"\n");
514 ppStgExpr(bco->stgexpr);
515 fprintf(stderr, "\n");
518 fprintf(stderr, "\t(no associated tree)\n" );
521 #endif /* INTERPRETER */