[project @ 2002-07-17 09:21:48 by simonmar]
[ghc-hetmet.git] / ghc / rts / Disassembler.c
1
2 /* -----------------------------------------------------------------------------
3  * Bytecode disassembler
4  *
5  * Copyright (c) 1994-1998.
6  *
7  * $RCSfile: Disassembler.c,v $
8  * $Revision: 1.25 $
9  * $Date: 2002/07/17 09:21:49 $
10  * ---------------------------------------------------------------------------*/
11
12 #ifdef DEBUG
13
14 #include "PosixSource.h"
15 #include "Rts.h"
16 #include "RtsAPI.h"
17 #include "RtsUtils.h"
18 #include "Closures.h"
19 #include "TSO.h"
20 #include "Schedule.h"
21
22 #include "Bytecodes.h"
23 #include "Printer.h"
24 #include "Disassembler.h"
25 #include "Interpreter.h"
26
27 #include <stdio.h>
28
29 /* --------------------------------------------------------------------------
30  * Disassembler
31  * ------------------------------------------------------------------------*/
32
33 int disInstr ( StgBCO *bco, int pc )
34 {
35    int i;
36
37    StgArrWords*   instr_arr   = bco->instrs;
38    UShort*        instrs      = (UShort*)(&instr_arr->payload[0]);
39
40    StgArrWords*   literal_arr = bco->literals;
41    StgWord*       literals    = (StgWord*)(&literal_arr->payload[0]);
42
43    StgMutArrPtrs* ptrs_arr    = bco->ptrs;
44    StgPtr*        ptrs        = (StgPtr*)(&ptrs_arr->payload[0]);
45
46    StgArrWords*   itbls_arr   = bco->itbls;
47    StgInfoTable** itbls       = (StgInfoTable**)(&itbls_arr->payload[0]);
48
49    switch (instrs[pc++]) {
50       case bci_SWIZZLE:
51          fprintf(stderr, "SWIZZLE stkoff %d by %d\n",
52                          instrs[pc], (signed int)instrs[pc+1]);
53          pc += 2; break;
54       case bci_CCALL:
55          fprintf(stderr, "CCALL    marshaller at 0x%x\n", 
56                          literals[instrs[pc]] );
57          pc += 1; break;
58       case bci_STKCHECK: 
59          fprintf(stderr, "STKCHECK %d\n", instrs[pc] );
60          pc += 1; break;
61       case bci_ARGCHECK: 
62          fprintf(stderr, "ARGCHECK %d\n", instrs[pc] );
63          pc += 1; break;
64       case bci_PUSH_L: 
65          fprintf(stderr, "PUSH_L   %d\n", instrs[pc] );
66          pc += 1; break;
67       case bci_PUSH_LL:
68          fprintf(stderr, "PUSH_LL  %d %d\n", instrs[pc], instrs[pc+1] ); 
69          pc += 2; break;
70       case bci_PUSH_LLL:
71          fprintf(stderr, "PUSH_LLL %d %d %d\n", instrs[pc], instrs[pc+1], 
72                                                             instrs[pc+2] ); 
73          pc += 3; break;
74       case bci_PUSH_G:
75          fprintf(stderr, "PUSH_G   " ); printPtr( ptrs[instrs[pc]] );
76          fprintf(stderr, "\n" );
77          pc += 1; break;
78       case bci_PUSH_AS:
79          fprintf(stderr, "PUSH_AS  " ); printPtr( ptrs[instrs[pc]] );
80          fprintf(stderr, " 0x%x", literals[instrs[pc+1]] );
81          fprintf(stderr, "\n");
82          pc += 2; break;
83       case bci_PUSH_UBX:
84          fprintf(stderr, "PUSH_UBX ");
85          for (i = 0; i < instrs[pc+1]; i++) 
86             fprintf(stderr, "0x%x ", literals[i + instrs[pc]] );
87          fprintf(stderr, "\n");
88          pc += 2; break;
89       case bci_PUSH_TAG:
90          fprintf(stderr, "PUSH_TAG %d\n", instrs[pc] );
91          pc += 1; break;
92       case bci_SLIDE: 
93          fprintf(stderr, "SLIDE    %d down by %d\n", instrs[pc], instrs[pc+1] );
94          pc += 2; break;
95       case bci_ALLOC:
96          fprintf(stderr, "ALLOC    %d words\n", instrs[pc] );
97          pc += 1; break;
98       case bci_MKAP:
99          fprintf(stderr, "MKAP     %d words, %d stkoff\n", instrs[pc+1], 
100                                                            instrs[pc] );
101          pc += 2; break;
102       case bci_UNPACK:
103          fprintf(stderr, "UNPACK   %d\n", instrs[pc] );
104          pc += 1; break;
105       case bci_UPK_TAG:
106          fprintf(stderr, "UPK_TAG  %d words, %d conoff, %d stkoff\n",
107                          instrs[pc], instrs[pc+1], instrs[pc+2] );
108          pc += 3; break;
109       case bci_PACK:
110          fprintf(stderr, "PACK     %d words with itbl ", instrs[pc+1] );
111          printPtr( (StgPtr)itbls[instrs[pc]] );
112          fprintf(stderr, "\n");
113          pc += 2; break;
114
115       case bci_CASEFAIL: 
116          fprintf(stderr, "CASEFAIL\n" );
117          break;
118       case bci_JMP:
119          fprintf(stderr, "JMP to   %d\n", instrs[pc]);
120          pc += 1; break;
121
122       case bci_TESTLT_I:
123          fprintf(stderr, "TESTLT_I %d, fail to %d\n", literals[instrs[pc]],
124                                                       instrs[pc+1]);
125          pc += 2; break;
126       case bci_TESTEQ_I:
127          fprintf(stderr, "TESTEQ_I %d, fail to %d\n", literals[instrs[pc]],
128                                                       instrs[pc+1]);
129          pc += 2; break;
130
131       case bci_TESTLT_F:
132          fprintf(stderr, "TESTLT_F %d, fail to %d\n", literals[instrs[pc]],
133                                                       instrs[pc+1]);
134          pc += 2; break;
135       case bci_TESTEQ_F:
136          fprintf(stderr, "TESTEQ_F %d, fail to %d\n", literals[instrs[pc]],
137                                                       instrs[pc+1]);
138          pc += 2; break;
139
140       case bci_TESTLT_D:
141          fprintf(stderr, "TESTLT_D %d, fail to %d\n", literals[instrs[pc]],
142                                                       instrs[pc+1]);
143          pc += 2; break;
144       case bci_TESTEQ_D:
145          fprintf(stderr, "TESTEQ_D %d, fail to %d\n", literals[instrs[pc]],
146                                                       instrs[pc+1]);
147          pc += 2; break;
148
149       case bci_TESTLT_P:
150          fprintf(stderr, "TESTLT_P %d, fail to %d\n", instrs[pc],
151                                                       instrs[pc+1]);
152          pc += 2; break;
153       case bci_TESTEQ_P:
154          fprintf(stderr, "TESTEQ_P %d, fail to %d\n", instrs[pc],
155                                                       instrs[pc+1]);
156          pc += 2; break;
157       case bci_RETURN:
158          fprintf(stderr, "RETURN  " ); printPtr( (StgPtr)itbls[instrs[pc]] );
159          fprintf(stderr, "\n");
160          pc += 1; break;
161       case bci_ENTER:
162          fprintf(stderr, "ENTER\n");
163          break;
164       default:
165          barf("disInstr: unknown opcode");
166    }
167    return pc;
168 }
169
170
171 /* Something of a kludge .. how do we know where the end of the insn
172    array is, since it isn't recorded anywhere?  Answer: the first
173    short is the number of bytecodes which follow it.  
174    See ByteCodeGen.linkBCO.insns_arr for construction ...  
175 */
176 void disassemble( StgBCO *bco )
177 {
178    nat i, j;
179    StgArrWords*   instr_arr = bco->instrs;
180    UShort*        instrs    = (UShort*)(&instr_arr->payload[0]);
181    StgMutArrPtrs* ptrs      = bco->ptrs;
182    nat            nbcs      = (int)instrs[0];
183    nat            pc        = 1;
184
185    fprintf(stderr, "BCO\n" );
186    pc = 1;
187    while (pc <= nbcs) {
188       fprintf(stderr, "\t%2d:  ", pc );
189       pc = disInstr ( bco, pc );
190    }
191
192    fprintf(stderr, "INSTRS:\n   " );
193    j = 16;
194    for (i = 0; i < nbcs; i++) {
195       fprintf(stderr, "%3d ", (int)instrs[i] );
196       j--; 
197       if (j == 0) { j = 16; fprintf(stderr, "\n   "); };
198    }
199    fprintf(stderr, "\n");
200
201    fprintf(stderr, "PTRS:\n   " );
202    j = 8;
203    for (i = 0; i < ptrs->ptrs; i++) {
204       fprintf(stderr, "%8p ", ptrs->payload[i] );
205       j--; 
206       if (j == 0) { j = 8; fprintf(stderr, "\n   "); };
207    }
208    fprintf(stderr, "\n");
209
210    fprintf(stderr, "\n");
211    ASSERT(pc == nbcs+1);
212 }
213
214 #endif /* DEBUG */