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