2 /* -----------------------------------------------------------------------------
3 * Bytecode disassembler
5 * Copyright (c) 1994-1998.
7 * $RCSfile: Disassembler.c,v $
9 * $Date: 1999/12/07 11:49:11 $
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);
84 static InstrPtr disPC ( StgBCO *bco, InstrPtr pc, char* i )
86 StgWord y = bcoInstr16(bco,pc); pc += 2;
87 fprintf(stderr,"%s %d",i,pc+y);
91 static InstrPtr disInfo ( StgBCO *bco, InstrPtr pc, char* i )
93 StgInfoTable* info = bcoConstInfoPtr(bco,bcoInstr(bco,pc++));
94 /* ToDo: print contents of infotable */
95 fprintf(stderr,"%s ",i);
96 printPtr(stgCast(StgPtr,info));
100 static InstrPtr disInfo16 ( StgBCO *bco, InstrPtr pc, char* i )
102 StgWord x = bcoInstr16(bco,pc);
103 StgInfoTable* info = bcoConstInfoPtr(bco,x);
105 /* ToDo: print contents of infotable */
106 fprintf(stderr,"%s ",i);
107 printPtr(stgCast(StgPtr,info));
111 static InstrPtr disConstPtr ( StgBCO *bco, InstrPtr pc, char* i )
113 StgInt o = bcoInstr(bco,pc++);
114 StgPtr x = bcoConstPtr(bco,o);
115 fprintf(stderr,"%s [%d]=",i,o);
116 printPtr(x); /* bad way to print it... */
120 static InstrPtr disConstPtr16 ( StgBCO *bco, InstrPtr pc, char* i )
124 o = bcoInstr16(bco,pc); pc += 2;
125 x = bcoConstPtr(bco,o);
126 fprintf(stderr,"%s [%d]=",i,o);
127 printPtr(x); /* bad way to print it... */
131 static InstrPtr disConstInt ( StgBCO *bco, InstrPtr pc, char* i )
133 StgInt x = bcoConstInt(bco,bcoInstr(bco,pc++));
134 fprintf(stderr,"%s %d (0x%x)",i,x,x);
138 static InstrPtr disConstInt16 ( StgBCO *bco, InstrPtr pc, char* i )
140 StgInt x = bcoConstInt(bco,bcoInstr16(bco,pc)); pc += 2;
141 fprintf(stderr,"%s %d (0x%x)",i,x,x);
145 static InstrPtr disConstAddr ( StgBCO *bco, InstrPtr pc, char* i )
147 StgAddr x = bcoConstAddr(bco,bcoInstr(bco,pc++));
148 fprintf(stderr,"%s ",i);
153 static InstrPtr disConstAddr16 ( StgBCO *bco, InstrPtr pc, char* i )
155 StgAddr x = bcoConstAddr(bco,bcoInstr16(bco,pc)); pc += 2;
156 fprintf(stderr,"%s ",i);
161 static InstrPtr disConstChar ( StgBCO *bco, InstrPtr pc, char* i )
163 StgChar x = bcoConstChar(bco,bcoInstr(bco,pc++));
165 fprintf(stderr,"%s '%c'",i,x); else
166 fprintf(stderr,"%s 0x%x",i,(int)x);
170 static InstrPtr disConstChar16 ( StgBCO *bco, InstrPtr pc, char* i )
172 StgChar x = bcoConstChar(bco,bcoInstr16(bco,pc)); pc += 2;
174 fprintf(stderr,"%s '%c'",i,x); else
175 fprintf(stderr,"%s 0x%x",i,(int)x);
179 static InstrPtr disConstFloat ( StgBCO *bco, InstrPtr pc, char* i )
181 StgFloat x = bcoConstFloat(bco,bcoInstr(bco,pc++));
182 fprintf(stderr,"%s %f",i,x);
186 static InstrPtr disConstFloat16 ( StgBCO *bco, InstrPtr pc, char* i )
188 StgFloat x = bcoConstFloat(bco,bcoInstr16(bco,pc)); pc += 2;
189 fprintf(stderr,"%s %f",i,x);
193 static InstrPtr disConstDouble ( StgBCO *bco, InstrPtr pc, char* i )
195 StgDouble x = bcoConstDouble(bco,bcoInstr(bco,pc++));
196 fprintf(stderr,"%s %f",i,x);
200 static InstrPtr disConstDouble16 ( StgBCO *bco, InstrPtr pc, char* i )
202 StgDouble x = bcoConstDouble(bco,bcoInstr16(bco,pc)); pc += 2;
203 fprintf(stderr,"%s %f",i,x);
207 InstrPtr disInstr( StgBCO *bco, InstrPtr pc )
210 ASSERT(pc < bco->n_instrs);
211 in = bcoInstr(bco,pc++);
213 case i_INTERNAL_ERROR:
214 return disNone(bco,pc,"INTERNAL_ERROR");
216 return disNone(bco,pc,"PANIC");
218 return disInt(bco,pc,"STK_CHECK");
219 case i_STK_CHECK_big:
220 return disInt16(bco,pc,"STK_CHECK_big");
222 return disInt(bco,pc,"ARG_CHECK");
224 return disInt(bco,pc,"ALLOC_AP");
226 return disInt(bco,pc,"ALLOC_PAP");
228 return disInfo(bco,pc,"ALLOC_CONSTR");
229 case i_ALLOC_CONSTR_big:
230 return disInfo16(bco,pc,"ALLOC_CONSTR_big");
232 return disIntInt(bco,pc,"MKAP");
234 return disIntInt16(bco,pc,"MKAP_big");
236 return disIntInt(bco,pc,"MKPAP");
238 return disInt(bco,pc,"PACK");
240 return disIntInt(bco,pc,"SLIDE");
242 return disIntInt(bco,pc,"R_V");
244 return disIntInt(bco,pc,"R_V_E");
246 return disIntInt(bco,pc,"V_V");
248 return disIntInt(bco,pc,"S_E");
250 return disIntInt16(bco,pc,"SLIDE_big");
252 return disNone(bco,pc,"ENTER");
254 return disConstPtr(bco,pc,"RETADDR");
256 return disConstPtr16(bco,pc,"RETADDR_big");
258 return disIntPC(bco,pc,"TEST");
260 return disNone(bco,pc,"UNPACK");
262 return disInt(bco,pc,"VAR");
264 return disInt16(bco,pc,"VAR_big");
266 return disConstPtr(bco,pc,"CONST");
268 return disConstPtr16(bco,pc,"CONST_big");
271 return disNone(bco,pc,"VOID");
274 return disInt(bco,pc,"VAR_INT");
276 return disInt16(bco,pc,"VAR_INT_big");
278 return disConstInt(bco,pc,"CONST_INT");
279 case i_CONST_INT_big:
280 return disConstInt16(bco,pc,"CONST_INT_big");
282 return disNone(bco,pc,"PACK_INT");
284 return disNone(bco,pc,"UNPACK_INT");
286 return disPC(bco,pc,"TEST_INT");
288 case i_CONST_INTEGER:
289 return disConstAddr(bco,pc,"CONST_INTEGER");
290 case i_CONST_INTEGER_big:
291 return disConstAddr16(bco,pc,"CONST_INTEGER_big");
294 return disInt(bco,pc,"VAR_WORD");
296 return disConstInt(bco,pc,"CONST_WORD");
298 return disNone(bco,pc,"PACK_WORD");
300 return disNone(bco,pc,"UNPACK_WORD");
303 return disInt(bco,pc,"VAR_ADDR");
305 return disInt16(bco,pc,"VAR_ADDR_big");
307 return disConstAddr(bco,pc,"CONST_ADDR");
308 case i_CONST_ADDR_big:
309 return disConstAddr16(bco,pc,"CONST_ADDR_big");
311 return disNone(bco,pc,"PACK_ADDR");
313 return disNone(bco,pc,"UNPACK_ADDR");
316 return disInt(bco,pc,"VAR_CHAR");
318 return disInt16(bco,pc,"VAR_CHAR_big");
320 return disConstChar(bco,pc,"CONST_CHAR");
321 case i_CONST_CHAR_big:
322 return disConstChar16(bco,pc,"CONST_CHAR_big");
324 return disNone(bco,pc,"PACK_CHAR");
326 return disNone(bco,pc,"UNPACK_CHAR");
329 return disInt(bco,pc,"VAR_FLOAT");
330 case i_VAR_FLOAT_big:
331 return disInt16(bco,pc,"VAR_FLOAT_big");
333 return disConstFloat(bco,pc,"CONST_FLOAT");
334 case i_CONST_FLOAT_big:
335 return disConstFloat16(bco,pc,"CONST_FLOAT_big");
337 return disNone(bco,pc,"PACK_FLOAT");
339 return disNone(bco,pc,"UNPACK_FLOAT");
342 return disInt(bco,pc,"VAR_DOUBLE");
343 case i_VAR_DOUBLE_big:
344 return disInt16(bco,pc,"VAR_DOUBLE_big");
346 return disConstDouble(bco,pc,"CONST_DOUBLE");
347 case i_CONST_DOUBLE_big:
348 return disConstDouble16(bco,pc,"CONST_DOUBLE_big");
350 return disNone(bco,pc,"PACK_DOUBLE");
351 case i_UNPACK_DOUBLE:
352 return disNone(bco,pc,"UNPACK_DOUBLE");
355 return disInt(bco,pc,"VAR_STABLE");
357 return disNone(bco,pc,"PACK_STABLE");
358 case i_UNPACK_STABLE:
359 return disNone(bco,pc,"UNPACK_STABLE");
363 Primop1 op = bcoInstr(bco,pc++);
365 case i_INTERNAL_ERROR1:
366 return disNone(bco,pc,"INTERNAL_ERROR1");
368 return disNone(bco,pc,"i_pushseqframe");
369 case i_pushcatchframe:
370 return disNone(bco,pc,"i_pushcatchframe");
373 const AsmPrim* p = asmFindPrimop(i_PRIMOP1,op);
375 return disNone(bco,pc,p->name);
377 barf("Unrecognised primop1 %d\n",op);
383 Primop2 op = bcoInstr(bco,pc++);
385 case i_INTERNAL_ERROR2:
386 return disNone(bco,pc,"INTERNAL_ERROR2");
387 case i_ccall_ccall_Id:
388 return disNone(bco,pc,"ccall_ccall_Id");
389 case i_ccall_ccall_IO:
390 return disNone(bco,pc,"ccall_ccall_IO");
391 case i_ccall_stdcall_Id:
392 return disNone(bco,pc,"ccall_stdcall_Id");
393 case i_ccall_stdcall_IO:
394 return disNone(bco,pc,"ccall_stdcall_IO");
396 return disNone(bco,pc,"primRaise");
398 return disNone(bco,pc,"primTakeMVar");
401 const AsmPrim* p = asmFindPrimop(i_PRIMOP2,op);
403 return disNone(bco,pc,p->name);
405 barf("Unrecognised primop2 %d\n",op);
410 barf("Unrecognised instruction %d\n",in);
414 void disassemble( StgBCO *bco, char* prefix )
417 int pcLim = bco->n_instrs;
418 ASSERT( get_itbl(bco)->type == BCO);
420 fprintf(stderr,"%s%d:\t",prefix,pc);
421 pc = disInstr(bco,pc);
422 fprintf(stderr,"\n");
425 ppStgExpr(bco->stgexpr);
426 fprintf(stderr, "\n");
429 fprintf(stderr, "\t(no associated tree)\n" );
432 #endif /* INTERPRETER */