2 /* -----------------------------------------------------------------------------
3 * Bytecode disassembler
5 * Copyright (c) 1994-1998.
7 * $RCSfile: Disassembler.c,v $
9 * $Date: 2000/12/19 16:48:35 $
10 * ---------------------------------------------------------------------------*/
19 #include "Bytecodes.h"
20 #include "Assembler.h"
22 #include "Disassembler.h"
23 #include "Interpreter.h"
25 /* --------------------------------------------------------------------------
27 * ------------------------------------------------------------------------*/
29 static int disInstr ( StgBCO *bco, int pc )
31 StgArrWords* instr_arr = bco->instrs;
32 UShort* instrs = (UShort*)(&instr_arr->payload[0]);
34 switch (instrs[pc++]) {
36 fprintf(stderr, "ARGCHECK %d\n", instrs[pc] );
39 fprintf(stderr, "PUSH_L %d\n", instrs[pc] );
42 fprintf(stderr, "PUSH_LL %d %d\n", instrs[pc], instrs[pc+1] );
45 fprintf(stderr, "PUSH_LLL %d %d %d\n", instrs[pc], instrs[pc+1],
49 fprintf(stderr, "PUSH_G " ); printPtr( ptrs[instrs[pc]] );
52 fprintf(stderr, "PUSH_AS " ); printPtr( ptrs[instrs[pc]] );
53 fprintf(stderr, " 0x%x", literals[instrs[pc+1]] );
56 fprintf(stderr, "PUSH_UBX ");
57 for (i = 0; i < instrs[pc+1]; i++)
58 fprintf(stderr, "0x%x ", literals[i + instrs[pc]] );
59 fprintf(stderr, "\n");
62 fprintf(stderr, "PUSH_TAG %d\n", instrs[pc] );
65 fprintf(stderr, "SLIDE %d down by %d\n", instrs[pc], instrs[pc+1] );
68 fprintf(stderr, "ALLOC %d words\n", instrs[pc] );
71 fprintf(stderr, "MKAP %d words, %d stkoff\n", instrs[pc+1],
75 fprintf(stderr, "UNPACK %d\n", instrs[pc] );
78 fprintf(stderr, "UPK_TAG %d words, %d conoff, %d stkoff\n",
79 instrs[pc], instrs[pc+1], instrs[pc+2] );
82 fprintf(stderr, "PACK %d words with itbl ", instrs[pc+1] );
83 printPtr( itbls[instrs[pc]] );
88 pc = disLitN ( bco, pc ); break;
89 case i_TESTEQ_I: pc = disLitNInt ( bco, pc );
94 static InstrPtr disNone ( StgBCO *bco, InstrPtr pc, char* i );
95 static InstrPtr disInt ( StgBCO *bco, InstrPtr pc, char* i );
96 static InstrPtr disIntInt ( StgBCO *bco, InstrPtr pc, char* i );
97 static InstrPtr disInfo ( StgBCO *bco, InstrPtr pc, char* i );
98 static InstrPtr disConstPtr ( StgBCO *bco, InstrPtr pc, char* i );
99 static InstrPtr disConstInt ( StgBCO *bco, InstrPtr pc, char* i );
100 static InstrPtr disConstChar ( StgBCO *bco, InstrPtr pc, char* i );
101 static InstrPtr disConstFloat ( StgBCO *bco, InstrPtr pc, char* i );
103 static InstrPtr disNone ( StgBCO *bco, InstrPtr pc, char* i )
105 fprintf(stderr,"%s",i);
109 static InstrPtr disInt ( StgBCO *bco, InstrPtr pc, char* i )
111 StgInt x = bcoInstr(bco,pc++);
112 ASSERT(pc <= bco->n_instrs);
113 fprintf(stderr,"%s %d",i,x);
117 static InstrPtr disInt16 ( StgBCO *bco, InstrPtr pc, char* i )
119 StgInt x = bcoInstr16(bco,pc); pc+=2;
120 ASSERT(pc <= bco->n_instrs);
121 fprintf(stderr,"%s %d",i,x);
125 static InstrPtr disIntInt ( StgBCO *bco, InstrPtr pc, char* i )
127 StgInt x = bcoInstr(bco,pc++);
128 StgInt y = bcoInstr(bco,pc++);
129 fprintf(stderr,"%s %d %d",i,x,y);
133 static InstrPtr disIntInt16 ( StgBCO *bco, InstrPtr pc, char* i )
136 x = bcoInstr16(bco,pc); pc += 2;
137 y = bcoInstr16(bco,pc); pc += 2;
138 fprintf(stderr,"%s %d %d",i,x,y);
142 static InstrPtr disIntPC ( StgBCO *bco, InstrPtr pc, char* i )
146 x = bcoInstr(bco,pc++);
147 y = bcoInstr16(bco,pc); pc += 2;
148 fprintf(stderr,"%s %d %d",i,x,pc+y);
153 static InstrPtr disInt16PC ( StgBCO *bco, InstrPtr pc, char* i )
157 x = bcoInstr(bco,pc); pc += 2;
158 y = bcoInstr16(bco,pc); pc += 2;
159 fprintf(stderr,"%s %d %d",i,x,pc+y);
162 static InstrPtr disIntIntPC ( StgBCO *bco, InstrPtr pc, char* i )
166 x = bcoInstr(bco,pc++);
167 y = bcoInstr(bco,pc++);
168 z = bcoInstr16(bco,pc); pc += 2;
169 fprintf(stderr,"%s %d %d %d",i,x,y,pc+z);
174 static InstrPtr disPC ( StgBCO *bco, InstrPtr pc, char* i )
176 StgWord y = bcoInstr16(bco,pc); pc += 2;
177 fprintf(stderr,"%s %d",i,pc+y);
181 static InstrPtr disInfo ( StgBCO *bco, InstrPtr pc, char* i )
183 StgInfoTable* info = bcoConstInfoPtr(bco,bcoInstr(bco,pc++));
184 /* ToDo: print contents of infotable */
185 fprintf(stderr,"%s ",i);
186 printPtr(stgCast(StgPtr,info));
190 static InstrPtr disInfo16 ( StgBCO *bco, InstrPtr pc, char* i )
192 StgWord x = bcoInstr16(bco,pc);
193 StgInfoTable* info = bcoConstInfoPtr(bco,x);
195 /* ToDo: print contents of infotable */
196 fprintf(stderr,"%s ",i);
197 printPtr(stgCast(StgPtr,info));
201 static InstrPtr disConstPtr ( StgBCO *bco, InstrPtr pc, char* i )
203 StgInt o = bcoInstr(bco,pc++);
204 StgPtr x = bcoConstPtr(bco,o);
205 fprintf(stderr,"%s [%d]=",i,o);
206 printPtr(x); /* bad way to print it... */
210 static InstrPtr disConstPtr16 ( StgBCO *bco, InstrPtr pc, char* i )
214 o = bcoInstr16(bco,pc); pc += 2;
215 x = bcoConstPtr(bco,o);
216 fprintf(stderr,"%s [%d]=",i,o);
217 printPtr(x); /* bad way to print it... */
221 static InstrPtr disConstInt ( StgBCO *bco, InstrPtr pc, char* i )
223 StgInt x = bcoConstInt(bco,bcoInstr(bco,pc++));
224 fprintf(stderr,"%s %d (0x%x)",i,x,x);
228 static InstrPtr disConstInt16 ( StgBCO *bco, InstrPtr pc, char* i )
230 StgInt x = bcoConstInt(bco,bcoInstr16(bco,pc)); pc += 2;
231 fprintf(stderr,"%s %d (0x%x)",i,x,x);
235 static InstrPtr disConstAddr ( StgBCO *bco, InstrPtr pc, char* i )
237 StgAddr x = bcoConstAddr(bco,bcoInstr(bco,pc++));
238 fprintf(stderr,"%s ",i);
243 static InstrPtr disConstAddr16 ( StgBCO *bco, InstrPtr pc, char* i )
245 StgAddr x = bcoConstAddr(bco,bcoInstr16(bco,pc)); pc += 2;
246 fprintf(stderr,"%s ",i);
251 static InstrPtr disConstChar ( StgBCO *bco, InstrPtr pc, char* i )
253 StgChar x = bcoConstChar(bco,bcoInstr(bco,pc++));
255 fprintf(stderr,"%s '%c'",i,x); else
256 fprintf(stderr,"%s 0x%x",i,(int)x);
260 static InstrPtr disConstChar16 ( StgBCO *bco, InstrPtr pc, char* i )
262 StgChar x = bcoConstChar(bco,bcoInstr16(bco,pc)); pc += 2;
264 fprintf(stderr,"%s '%c'",i,x); else
265 fprintf(stderr,"%s 0x%x",i,(int)x);
269 static InstrPtr disConstFloat ( StgBCO *bco, InstrPtr pc, char* i )
271 StgFloat x = bcoConstFloat(bco,bcoInstr(bco,pc++));
272 fprintf(stderr,"%s %f",i,x);
276 static InstrPtr disConstFloat16 ( StgBCO *bco, InstrPtr pc, char* i )
278 StgFloat x = bcoConstFloat(bco,bcoInstr16(bco,pc)); pc += 2;
279 fprintf(stderr,"%s %f",i,x);
283 static InstrPtr disConstDouble ( StgBCO *bco, InstrPtr pc, char* i )
285 StgDouble x = bcoConstDouble(bco,bcoInstr(bco,pc++));
286 fprintf(stderr,"%s %f",i,x);
290 static InstrPtr disConstDouble16 ( StgBCO *bco, InstrPtr pc, char* i )
292 StgDouble x = bcoConstDouble(bco,bcoInstr16(bco,pc)); pc += 2;
293 fprintf(stderr,"%s %f",i,x);
297 InstrPtr disInstr( StgBCO *bco, InstrPtr pc )
300 ASSERT(pc < bco->n_instrs);
301 in = bcoInstr(bco,pc++);
303 case i_INTERNAL_ERROR:
304 return disNone(bco,pc,"INTERNAL_ERROR");
306 return disNone(bco,pc,"PANIC");
308 return disInt(bco,pc,"STK_CHECK");
309 case i_STK_CHECK_big:
310 return disInt16(bco,pc,"STK_CHECK_big");
312 return disInt(bco,pc,"ARG_CHECK");
314 return disInt(bco,pc,"ALLOC_AP");
316 return disInt(bco,pc,"ALLOC_PAP");
318 return disInfo(bco,pc,"ALLOC_CONSTR");
319 case i_ALLOC_CONSTR_big:
320 return disInfo16(bco,pc,"ALLOC_CONSTR_big");
322 return disIntInt(bco,pc,"MKAP");
324 return disIntInt16(bco,pc,"MKAP_big");
326 return disIntInt(bco,pc,"MKPAP");
328 return disInt(bco,pc,"PACK");
330 return disIntInt(bco,pc,"SLIDE");
332 return disIntInt(bco,pc,"R_V");
334 return disIntInt(bco,pc,"R_V_E");
336 return disIntInt(bco,pc,"V_V");
338 return disIntInt(bco,pc,"S_E");
340 return disIntInt16(bco,pc,"SLIDE_big");
342 return disNone(bco,pc,"ENTER");
344 return disConstPtr(bco,pc,"RETADDR");
346 return disConstPtr16(bco,pc,"RETADDR_big");
348 return disIntPC(bco,pc,"TEST");
350 return disNone(bco,pc,"UNPACK");
352 return disInt(bco,pc,"VAR");
354 return disInt16(bco,pc,"VAR_big");
356 return disConstPtr(bco,pc,"CONST");
358 return disConstPtr16(bco,pc,"CONST_big");
362 return disInt(bco,pc,"ALLOC_ROW");
363 case i_ALLOC_ROW_big:
364 return disInt16(bco,pc,"ALLOC_ROW_big");
366 return disInt(bco,pc,"PACK_ROW");
368 return disInt16(bco,pc,"PACK_ROW_big");
370 return disNone(bco,pc,"UNPACK_ROW");
371 case i_CONST_ROW_TRIV:
372 return disNone(bco,pc,"CONST_ROW_TRIV");
375 return disInt(bco,pc,"PACK_INJ_VAR");
376 case i_PACK_INJ_VAR_big:
377 return disInt16(bco,pc,"PACK_INJ_VAR_big");
378 case i_PACK_INJ_CONST_8:
379 return disInt(bco,pc,"PACK_INJ_CONST_8");
380 case i_PACK_INJ_REL_8:
381 return disIntInt(bco,pc,"PACK_INJ_REL_8");
383 return disNone(bco,pc,"PACK_INJ");
386 return disNone(bco,pc,"UNPACK_INJ");
389 return disIntPC(bco,pc,"TEST_INJ_VAR");
390 case i_TEST_INJ_VAR_big:
391 return disInt16PC(bco,pc,"TEST_INJ_VAR_big");
392 case i_TEST_INJ_CONST_8:
393 return disIntPC(bco,pc,"TEST_INJ_CONST_8");
394 case i_TEST_INJ_REL_8:
395 return disIntIntPC(bco,pc,"TEST_INJ_REL_8");
397 return disPC(bco,pc,"TEST_INJ");
400 return disInt(bco,pc,"CONST_WORD_8");
402 return disInt(bco,pc,"ADD_WORD_VAR");
403 case i_ADD_WORD_VAR_big:
404 return disInt16(bco,pc,"ADD_WORD_VAR_big");
405 case i_ADD_WORD_VAR_8:
406 return disIntInt(bco,pc,"ADD_WORD_VAR_8");
410 return disNone(bco,pc,"VOID");
413 return disInt(bco,pc,"VAR_INT");
415 return disInt16(bco,pc,"VAR_INT_big");
417 return disConstInt(bco,pc,"CONST_INT");
418 case i_CONST_INT_big:
419 return disConstInt16(bco,pc,"CONST_INT_big");
421 return disNone(bco,pc,"PACK_INT");
423 return disNone(bco,pc,"UNPACK_INT");
425 return disPC(bco,pc,"TEST_INT");
427 case i_CONST_INTEGER:
428 return disConstAddr(bco,pc,"CONST_INTEGER");
429 case i_CONST_INTEGER_big:
430 return disConstAddr16(bco,pc,"CONST_INTEGER_big");
433 return disInt(bco,pc,"VAR_WORD");
435 return disConstInt(bco,pc,"CONST_WORD");
436 case i_CONST_WORD_big:
437 return disConstInt16(bco,pc,"CONST_WORD_big");
439 return disNone(bco,pc,"PACK_WORD");
441 return disNone(bco,pc,"UNPACK_WORD");
444 return disInt(bco,pc,"VAR_ADDR");
446 return disInt16(bco,pc,"VAR_ADDR_big");
448 return disConstAddr(bco,pc,"CONST_ADDR");
449 case i_CONST_ADDR_big:
450 return disConstAddr16(bco,pc,"CONST_ADDR_big");
452 return disNone(bco,pc,"PACK_ADDR");
454 return disNone(bco,pc,"UNPACK_ADDR");
457 return disInt(bco,pc,"VAR_CHAR");
459 return disInt16(bco,pc,"VAR_CHAR_big");
461 return disConstChar(bco,pc,"CONST_CHAR");
462 case i_CONST_CHAR_big:
463 return disConstChar16(bco,pc,"CONST_CHAR_big");
465 return disNone(bco,pc,"PACK_CHAR");
467 return disNone(bco,pc,"UNPACK_CHAR");
470 return disInt(bco,pc,"VAR_FLOAT");
471 case i_VAR_FLOAT_big:
472 return disInt16(bco,pc,"VAR_FLOAT_big");
474 return disConstFloat(bco,pc,"CONST_FLOAT");
475 case i_CONST_FLOAT_big:
476 return disConstFloat16(bco,pc,"CONST_FLOAT_big");
478 return disNone(bco,pc,"PACK_FLOAT");
480 return disNone(bco,pc,"UNPACK_FLOAT");
483 return disInt(bco,pc,"VAR_DOUBLE");
484 case i_VAR_DOUBLE_big:
485 return disInt16(bco,pc,"VAR_DOUBLE_big");
487 return disConstDouble(bco,pc,"CONST_DOUBLE");
488 case i_CONST_DOUBLE_big:
489 return disConstDouble16(bco,pc,"CONST_DOUBLE_big");
491 return disNone(bco,pc,"PACK_DOUBLE");
492 case i_UNPACK_DOUBLE:
493 return disNone(bco,pc,"UNPACK_DOUBLE");
496 return disInt(bco,pc,"VAR_STABLE");
498 return disNone(bco,pc,"PACK_STABLE");
499 case i_UNPACK_STABLE:
500 return disNone(bco,pc,"UNPACK_STABLE");
504 Primop1 op = bcoInstr(bco,pc++);
506 case i_INTERNAL_ERROR1:
507 return disNone(bco,pc,"INTERNAL_ERROR1");
509 return disNone(bco,pc,"i_pushseqframe");
510 case i_pushcatchframe:
511 return disNone(bco,pc,"i_pushcatchframe");
514 const AsmPrim* p = asmFindPrimop(i_PRIMOP1,op);
516 return disNone(bco,pc,p->name);
518 barf("Unrecognised primop1 %d\n",op);
524 Primop2 op = bcoInstr(bco,pc++);
526 case i_INTERNAL_ERROR2:
527 return disNone(bco,pc,"INTERNAL_ERROR2");
530 return disNone(bco,pc,"ROW_INSERT_1");
531 case i_rowChainInsert:
532 return disNone(bco,pc,"ROW_INSERT");
533 case i_rowChainBuild:
534 return disNone(bco,pc,"ROW_BUILD");
536 return disNone(bco,pc,"ROW_REMOVE_1");
537 case i_rowChainRemove:
538 return disNone(bco,pc,"ROW_REMOVE");
539 case i_rowChainSelect:
540 return disNone(bco,pc,"ROW_SELECT");
542 return disNone(bco,pc,"ccall");
544 case i_ccall_ccall_Id:
545 return disNone(bco,pc,"ccall_ccall_Id");
546 case i_ccall_ccall_IO:
547 return disNone(bco,pc,"ccall_ccall_IO");
548 case i_ccall_stdcall_Id:
549 return disNone(bco,pc,"ccall_stdcall_Id");
550 case i_ccall_stdcall_IO:
551 return disNone(bco,pc,"ccall_stdcall_IO");
553 return disNone(bco,pc,"primRaise");
555 return disNone(bco,pc,"primTakeMVar");
558 const AsmPrim* p = asmFindPrimop(i_PRIMOP2,op);
560 return disNone(bco,pc,p->name);
562 barf("Unrecognised primop2 %d\n",op);
567 barf("Unrecognised instruction %d\n",in);
571 void disassemble( StgBCO *bco, char* prefix )
574 int pcLim = bco->n_instrs;
575 ASSERT( get_itbl(bco)->type == BCO);
577 fprintf(stderr,"%s%d:\t",prefix,pc);
578 pc = disInstr(bco,pc);
579 fprintf(stderr,"\n");
582 ppStgExpr(bco->stgexpr);
583 fprintf(stderr, "\n");
586 fprintf(stderr, "\t(no associated tree)\n" );
589 #endif /* INTERPRETER */