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