[project @ 1999-02-23 17:20:34 by sof]
[ghc-hetmet.git] / ghc / rts / Disassembler.c
1 /* -*- mode: hugs-c; -*- */
2 /* -----------------------------------------------------------------------------
3  * $Id: Disassembler.c,v 1.3 1999/02/05 16:02:37 simonm Exp $
4  *
5  * Copyright (c) The GHC Team 1994-1999.
6  *
7  * Bytecode disassembler
8  *
9  * ---------------------------------------------------------------------------*/
10
11 #include "Rts.h"
12
13 #ifdef INTERPRETER
14
15 #include "RtsUtils.h"
16 #include "Bytecodes.h"
17 #include "Assembler.h"
18 #include "Printer.h"
19 #include "Disassembler.h"
20
21 /* --------------------------------------------------------------------------
22  * Disassembler
23  * ------------------------------------------------------------------------*/
24
25 static InstrPtr disNone         ( StgBCO *bco, InstrPtr pc, char* i );
26 static InstrPtr disInt          ( StgBCO *bco, InstrPtr pc, char* i );
27 static InstrPtr disIntInt       ( StgBCO *bco, InstrPtr pc, char* i );
28 static InstrPtr disInfo         ( StgBCO *bco, InstrPtr pc, char* i );
29 static InstrPtr disConstPtr     ( StgBCO *bco, InstrPtr pc, char* i );
30 static InstrPtr disConstInt     ( StgBCO *bco, InstrPtr pc, char* i );
31 static InstrPtr disConstChar    ( StgBCO *bco, InstrPtr pc, char* i );
32 static InstrPtr disConstFloat   ( StgBCO *bco, InstrPtr pc, char* i );
33
34 static InstrPtr disNone      ( StgBCO *bco, InstrPtr pc, char* i )
35 {
36     fprintf(stderr,"%s",i);
37     return pc;
38 }
39
40 static InstrPtr disInt       ( StgBCO *bco, InstrPtr pc, char* i )
41 {
42     StgInt x = bcoInstr(bco,pc++);
43     ASSERT(pc < bco->n_instrs);
44     fprintf(stderr,"%s %d",i,x);
45     return pc;
46 }
47
48 static InstrPtr disIntInt    ( StgBCO *bco, InstrPtr pc, char* i )
49 {
50     StgInt x = bcoInstr(bco,pc++);
51     StgInt y = bcoInstr(bco,pc++);
52     fprintf(stderr,"%s %d %d",i,x,y);
53     return pc;
54 }
55
56 static InstrPtr disIntPC     ( StgBCO *bco, InstrPtr pc, char* i )
57 {
58     StgInt  x = bcoInstr(bco,pc++);
59     StgWord y = bcoInstr(bco,pc++);
60     fprintf(stderr,"%s %d %d",i,x,pc+y);
61     return pc;
62 }
63
64 static InstrPtr disPC        ( StgBCO *bco, InstrPtr pc, char* i )
65 {
66     StgWord y = bcoInstr(bco,pc++);
67     fprintf(stderr,"%s %d",i,pc+y);
68     return pc;
69 }
70
71 static InstrPtr disInfo   ( StgBCO *bco, InstrPtr pc, char* i )
72 {
73     StgInfoTable* info = bcoConstInfoPtr(bco,bcoInstr(bco,pc++));
74     /* ToDo: print contents of infotable */
75     fprintf(stderr,"%s ",i);
76     printPtr(stgCast(StgPtr,info));
77     return pc;
78 }
79
80 static InstrPtr disConstPtr  ( StgBCO *bco, InstrPtr pc, char* i )
81 {
82     StgInt o = bcoInstr(bco,pc++);
83     StgPtr x = bcoConstPtr(bco,o);
84     fprintf(stderr,"%s [%d]=",i,o); 
85     printPtr(x); /* bad way to print it... */
86     return pc;
87 }
88
89 static InstrPtr disConst2Ptr ( StgBCO *bco, InstrPtr pc, char* i )
90 {
91     StgWord o1 = bcoInstr(bco,pc++);
92     StgWord o2 = bcoInstr(bco,pc++);
93     StgWord o  = o1*256 + o2;
94     StgPtr x = bcoConstPtr(bco,o);
95     fprintf(stderr,"%s [%d]=",i,o); 
96     printPtr(x); /* bad way to print it... */
97     return pc;
98 }
99
100 static InstrPtr disConstInt  ( StgBCO *bco, InstrPtr pc, char* i )
101 {
102     StgInt x = bcoConstInt(bco,bcoInstr(bco,pc++));
103     fprintf(stderr,"%s %d",i,x);
104     return pc;
105 }
106
107 static InstrPtr disConstAddr ( StgBCO *bco, InstrPtr pc, char* i )
108 {
109     StgAddr x = bcoConstAddr(bco,bcoInstr(bco,pc++));
110     fprintf(stderr,"%s ",i);
111     printPtr(x);
112     return pc;
113 }
114
115 static InstrPtr disConstChar ( StgBCO *bco, InstrPtr pc, char* i )
116 {
117     StgChar x = bcoConstChar(bco,bcoInstr(bco,pc++));
118     fprintf(stderr,"%s '%c'",i,x);
119     return pc;
120 }
121
122 static InstrPtr disConstFloat ( StgBCO *bco, InstrPtr pc, char* i )
123 {
124     StgFloat x = bcoConstFloat(bco,bcoInstr(bco,pc++));
125     fprintf(stderr,"%s %f",i,x);
126     return pc;
127 }
128
129 static InstrPtr disConstDouble ( StgBCO *bco, InstrPtr pc, char* i )
130 {
131     StgDouble x = bcoConstDouble(bco,bcoInstr(bco,pc++));
132     fprintf(stderr,"%s %f",i,x);
133     return pc;
134 }
135
136 InstrPtr disInstr( StgBCO *bco, InstrPtr pc )
137 {
138     Instr in;
139     ASSERT(pc < bco->n_instrs);
140     in = bcoInstr(bco,pc++);
141     switch (in) {
142     case i_INTERNAL_ERROR:
143             return disNone(bco,pc,"INTERNAL_ERROR");
144     case i_PANIC:
145             return disNone(bco,pc,"PANIC");
146     case i_HP_CHECK:
147             return disInt(bco,pc,"HP_CHECK");
148     case i_STK_CHECK:
149             return disInt(bco,pc,"STK_CHECK");
150     case i_ARG_CHECK:
151             return disInt(bco,pc,"ARG_CHECK");
152     case i_ALLOC_AP:
153             return disInt(bco,pc,"ALLOC_AP");
154     case i_ALLOC_PAP:
155             return disInt(bco,pc,"ALLOC_PAP");
156     case i_ALLOC_CONSTR:
157             return disInfo(bco,pc,"ALLOC_CONSTR");
158     case i_MKAP:
159             return disIntInt(bco,pc,"MKAP");
160     case i_MKPAP:
161             return disIntInt(bco,pc,"MKPAP");
162     case i_PACK:
163             return disInt(bco,pc,"PACK");
164     case i_SLIDE:
165             return disIntInt(bco,pc,"SLIDE");
166     case i_ENTER:
167             return disNone(bco,pc,"ENTER");
168     case i_RETADDR:
169             return disConstPtr(bco,pc,"RETADDR");
170     case i_TEST:
171             return disIntPC(bco,pc,"TEST");
172     case i_UNPACK:
173             return disNone(bco,pc,"UNPACK");
174     case i_VAR:
175             return disInt(bco,pc,"VAR");
176     case i_CONST:
177             return disConstPtr(bco,pc,"CONST");
178     case i_CONST2:
179             return disConst2Ptr(bco,pc,"CONST2");
180
181     case i_VOID:
182             return disNone(bco,pc,"VOID");
183
184     case i_RETURN_GENERIC:
185             return disNone(bco,pc,"RETURN_GENERIC");
186
187     case i_VAR_INT:
188             return disInt(bco,pc,"VAR_INT");
189     case i_CONST_INT:
190             return disConstInt(bco,pc,"CONST_INT");
191     case i_RETURN_INT:
192             return disNone(bco,pc,"RETURN_INT");
193     case i_PACK_INT:
194             return disNone(bco,pc,"PACK_INT");
195     case i_UNPACK_INT:
196             return disNone(bco,pc,"UNPACK_INT");
197     case i_TEST_INT:
198             return disPC(bco,pc,"TEST_INT");
199
200 #ifdef PROVIDE_INT64
201     case i_VAR_INT64:
202             return disInt(bco,pc,"VAR_INT64");
203     case i_CONST_INT64:
204             return disConstInt(bco,pc,"CONST_INT64");
205     case i_RETURN_INT64:
206             return disNone(bco,pc,"RETURN_INT64");
207     case i_PACK_INT64:
208             return disNone(bco,pc,"PACK_INT64");
209     case i_UNPACK_INT64:
210             return disNone(bco,pc,"UNPACK_INT64");
211 #endif
212 #ifdef PROVIDE_INTEGER
213     case i_CONST_INTEGER:
214             return disConstAddr(bco,pc,"CONST_INTEGER");
215 #endif
216 #ifdef PROVIDE_WORD
217     case i_VAR_WORD:
218             return disInt(bco,pc,"VAR_WORD");
219     case i_CONST_WORD:
220             return disConstInt(bco,pc,"CONST_WORD");
221     case i_RETURN_WORD:
222             return disNone(bco,pc,"RETURN_WORD");
223     case i_PACK_WORD:
224             return disNone(bco,pc,"PACK_WORD");
225     case i_UNPACK_WORD:
226             return disNone(bco,pc,"UNPACK_WORD");
227 #endif
228 #ifdef PROVIDE_ADDR
229     case i_VAR_ADDR:
230             return disInt(bco,pc,"VAR_ADDR");
231     case i_CONST_ADDR:
232             return disConstAddr(bco,pc,"CONST_ADDR");
233     case i_RETURN_ADDR:
234             return disNone(bco,pc,"RETURN_ADDR");
235     case i_PACK_ADDR:
236             return disNone(bco,pc,"PACK_ADDR");
237     case i_UNPACK_ADDR:
238             return disNone(bco,pc,"UNPACK_ADDR");
239 #endif
240     case i_VAR_CHAR:
241             return disInt(bco,pc,"VAR_CHAR");
242     case i_CONST_CHAR:
243             return disConstChar(bco,pc,"CONST_CHAR");
244     case i_RETURN_CHAR:
245             return disNone(bco,pc,"RETURN_CHAR");
246     case i_PACK_CHAR:
247             return disNone(bco,pc,"PACK_CHAR");
248     case i_UNPACK_CHAR:
249             return disNone(bco,pc,"UNPACK_CHAR");
250
251     case i_VAR_FLOAT:
252             return disInt(bco,pc,"VAR_FLOAT");
253     case i_CONST_FLOAT:
254             return disConstFloat(bco,pc,"CONST_FLOAT");
255     case i_RETURN_FLOAT:
256             return disNone(bco,pc,"RETURN_FLOAT");
257     case i_PACK_FLOAT:
258             return disNone(bco,pc,"PACK_FLOAT");
259     case i_UNPACK_FLOAT:
260             return disNone(bco,pc,"UNPACK_FLOAT");
261
262     case i_VAR_DOUBLE:
263             return disInt(bco,pc,"VAR_DOUBLE");
264     case i_CONST_DOUBLE:
265             return disConstDouble(bco,pc,"CONST_DOUBLE");
266     case i_RETURN_DOUBLE:
267             return disNone(bco,pc,"RETURN_DOUBLE");
268     case i_PACK_DOUBLE:
269             return disNone(bco,pc,"PACK_DOUBLE");
270     case i_UNPACK_DOUBLE:
271             return disNone(bco,pc,"UNPACK_DOUBLE");
272
273 #ifdef PROVIDE_STABLE
274     case i_VAR_STABLE:
275             return disInt(bco,pc,"VAR_STABLE");
276     case i_RETURN_STABLE:
277             return disNone(bco,pc,"RETURN_STABLE");
278     case i_PACK_STABLE:
279             return disNone(bco,pc,"PACK_STABLE");
280     case i_UNPACK_STABLE:
281             return disNone(bco,pc,"UNPACK_STABLE");
282 #endif
283
284     case i_PRIMOP1:
285         {
286             Primop1 op = bcoInstr(bco,pc++);
287             switch (op) {
288             case i_INTERNAL_ERROR1:
289                     return disNone(bco,pc,"INTERNAL_ERROR1");
290             default:
291                 {
292                     const AsmPrim* p = asmFindPrimop(i_PRIMOP1,op);
293                     if (p) {
294                         return disNone(bco,pc,p->name);
295                     }
296                     barf("Unrecognised primop1 %d\n",op);
297                 }
298             }
299         }
300     case i_PRIMOP2:
301         {
302             Primop2 op = bcoInstr(bco,pc++);
303             switch (op) {
304             case i_INTERNAL_ERROR2:
305                     return disNone(bco,pc,"INTERNAL_ERROR2");
306             case i_ccall_Id:
307                     return disNone(bco,pc,"ccall_Id");
308             case i_ccall_IO:
309                     return disNone(bco,pc,"ccall_IO");
310             default:
311                 {
312                     const AsmPrim* p = asmFindPrimop(i_PRIMOP2,op);
313                     if (p) {
314                         return disNone(bco,pc,p->name);
315                     }
316                     barf("Unrecognised primop2 %d\n",op);
317                 }
318             }
319         }
320     default:
321             barf("Unrecognised instruction %d\n",in);
322     }
323 }
324
325 void  disassemble( StgBCO *bco, char* prefix )
326 {
327     int pc = 0;
328     int pcLim = bco->n_instrs;
329     ASSERT( get_itbl(bco)->type == BCO);
330     while (pc < pcLim) {
331         fprintf(stderr,"%s%d:\t",prefix,pc);
332         pc = disInstr(bco,pc);
333         fprintf(stderr,"\n");
334     }
335 }
336
337 #endif /* INTERPRETER */