Disassembler.c 8.84 KB
Newer Older
1
/* -----------------------------------------------------------------------------
2
 * Bytecode disassembler
3
 *
4
 * Copyright (c) 1994-2002.
5
6
 *
 * $RCSfile: Disassembler.c,v $
7
8
 * $Revision: 1.29 $
 * $Date: 2004/09/03 15:28:19 $
9
10
 * ---------------------------------------------------------------------------*/

11
#ifdef DEBUG
12

13
#include "PosixSource.h"
14
#include "Rts.h"
15
#include "RtsAPI.h"
16
#include "RtsUtils.h"
17
18
19
20
#include "Closures.h"
#include "TSO.h"
#include "Schedule.h"

21
22
23
#include "Bytecodes.h"
#include "Printer.h"
#include "Disassembler.h"
24
#include "Interpreter.h"
25
26
27
28
29

/* --------------------------------------------------------------------------
 * Disassembler
 * ------------------------------------------------------------------------*/

30
31
int
disInstr ( StgBCO *bco, int pc )
32
{
33
   int i;
34
   StgWord16 instr;
35

sof's avatar
sof committed
36
   StgWord16*     instrs      = (StgWord16*)(bco->instrs->payload);
37
38
39
40
41
42
43

   StgArrWords*   literal_arr = bco->literals;
   StgWord*       literals    = (StgWord*)(&literal_arr->payload[0]);

   StgMutArrPtrs* ptrs_arr    = bco->ptrs;
   StgPtr*        ptrs        = (StgPtr*)(&ptrs_arr->payload[0]);

44
45
   instr = instrs[pc++];
   switch (instr) {
46
47
48
49
50
      case bci_BRK_FUN:
         debugBelch ("BRK_FUN  " );  printPtr( ptrs[instrs[pc]] ); 
         debugBelch (" %d ", instrs[pc+1]); printPtr( ptrs[instrs[pc+2]] ); debugBelch("\n" );
         pc += 3;
         break;
51
      case bci_SWIZZLE:
52
         debugBelch("SWIZZLE stkoff %d by %d\n",
53
54
                         instrs[pc], (signed int)instrs[pc+1]);
         pc += 2; break;
55
      case bci_CCALL:
Simon Marlow's avatar
Simon Marlow committed
56
         debugBelch("CCALL    marshaller at 0x%lx\n", 
57
                         literals[instrs[pc]] );
58
         pc += 1; break;
59
      case bci_STKCHECK: 
60
         debugBelch("STKCHECK %d\n", instrs[pc] );
61
         pc += 1; break;
62
      case bci_PUSH_L: 
63
         debugBelch("PUSH_L   %d\n", instrs[pc] );
64
         pc += 1; break;
65
      case bci_PUSH_LL:
66
         debugBelch("PUSH_LL  %d %d\n", instrs[pc], instrs[pc+1] ); 
67
         pc += 2; break;
68
      case bci_PUSH_LLL:
69
         debugBelch("PUSH_LLL %d %d %d\n", instrs[pc], instrs[pc+1], 
70
71
                                                            instrs[pc+2] ); 
         pc += 3; break;
72
      case bci_PUSH_G:
73
74
         debugBelch("PUSH_G   " ); printPtr( ptrs[instrs[pc]] );
         debugBelch("\n" );
75
         pc += 1; break;
76
77

      case bci_PUSH_ALTS:
78
79
         debugBelch("PUSH_ALTS  " ); printPtr( ptrs[instrs[pc]] );
         debugBelch("\n");
80
81
         pc += 1; break;
      case bci_PUSH_ALTS_P:
82
83
         debugBelch("PUSH_ALTS_P  " ); printPtr( ptrs[instrs[pc]] );
         debugBelch("\n");
84
85
         pc += 1; break;
      case bci_PUSH_ALTS_N:
86
87
         debugBelch("PUSH_ALTS_N  " ); printPtr( ptrs[instrs[pc]] );
         debugBelch("\n");
88
89
         pc += 1; break;
      case bci_PUSH_ALTS_F:
90
91
         debugBelch("PUSH_ALTS_F  " ); printPtr( ptrs[instrs[pc]] );
         debugBelch("\n");
92
93
         pc += 1; break;
      case bci_PUSH_ALTS_D:
94
95
         debugBelch("PUSH_ALTS_D  " ); printPtr( ptrs[instrs[pc]] );
         debugBelch("\n");
96
97
         pc += 1; break;
      case bci_PUSH_ALTS_L:
98
99
         debugBelch("PUSH_ALTS_L  " ); printPtr( ptrs[instrs[pc]] );
         debugBelch("\n");
100
101
         pc += 1; break;
      case bci_PUSH_ALTS_V:
102
103
         debugBelch("PUSH_ALTS_V  " ); printPtr( ptrs[instrs[pc]] );
         debugBelch("\n");
104
105
         pc += 1; break;

106
      case bci_PUSH_UBX:
107
         debugBelch("PUSH_UBX ");
108
         for (i = 0; i < instrs[pc+1]; i++) 
Simon Marlow's avatar
Simon Marlow committed
109
            debugBelch("0x%lx ", literals[i + instrs[pc]] );
110
         debugBelch("\n");
111
         pc += 2; break;
112
      case bci_PUSH_APPLY_N:
113
	  debugBelch("PUSH_APPLY_N\n");
114
115
	  break;
      case bci_PUSH_APPLY_V:
116
	  debugBelch("PUSH_APPLY_V\n");
117
118
	  break;
      case bci_PUSH_APPLY_F:
119
	  debugBelch("PUSH_APPLY_F\n");
120
121
	  break;
      case bci_PUSH_APPLY_D:
122
	  debugBelch("PUSH_APPLY_D\n");
123
124
	  break;
      case bci_PUSH_APPLY_L:
125
	  debugBelch("PUSH_APPLY_L\n");
126
127
	  break;
      case bci_PUSH_APPLY_P:
128
	  debugBelch("PUSH_APPLY_P\n");
129
130
	  break;
      case bci_PUSH_APPLY_PP:
131
	  debugBelch("PUSH_APPLY_PP\n");
132
133
	  break;
      case bci_PUSH_APPLY_PPP:
134
	  debugBelch("PUSH_APPLY_PPP\n");
135
136
	  break;
      case bci_PUSH_APPLY_PPPP:
137
	  debugBelch("PUSH_APPLY_PPPP\n");
138
139
	  break;
      case bci_PUSH_APPLY_PPPPP:
140
	  debugBelch("PUSH_APPLY_PPPPP\n");
141
142
	  break;
      case bci_PUSH_APPLY_PPPPPP:
143
	  debugBelch("PUSH_APPLY_PPPPPP\n");
144
	  break;
145
      case bci_SLIDE: 
146
         debugBelch("SLIDE     %d down by %d\n", instrs[pc], instrs[pc+1] );
147
         pc += 2; break;
148
      case bci_ALLOC_AP:
149
         debugBelch("ALLOC_AP  %d words\n", instrs[pc] );
150
         pc += 1; break;
151
152
153
      case bci_ALLOC_AP_NOUPD:
         debugBelch("ALLOC_AP_NOUPD %d words\n", instrs[pc] );
         pc += 1; break;
154
      case bci_ALLOC_PAP:
155
         debugBelch("ALLOC_PAP %d arity, %d words\n",
156
157
		 instrs[pc], instrs[pc+1] );
         pc += 2; break;
158
      case bci_MKAP:
159
         debugBelch("MKAP      %d words, %d stkoff\n", instrs[pc+1], 
160
161
                                                           instrs[pc] );
         pc += 2; break;
162
163
164
165
      case bci_MKPAP:
         debugBelch("MKPAP     %d words, %d stkoff\n", instrs[pc+1], 
                                                           instrs[pc] );
         pc += 2; break;
166
      case bci_UNPACK:
167
         debugBelch("UNPACK    %d\n", instrs[pc] );
168
         pc += 1; break;
169
      case bci_PACK:
170
         debugBelch("PACK      %d words with itbl ", instrs[pc+1] );
171
         printPtr( (StgPtr)literals[instrs[pc]] );
172
         debugBelch("\n");
173
         pc += 2; break;
174

175
      case bci_TESTLT_I:
Simon Marlow's avatar
Simon Marlow committed
176
         debugBelch("TESTLT_I  %ld, fail to %d\n", literals[instrs[pc]],
177
178
179
                                                      instrs[pc+1]);
         pc += 2; break;
      case bci_TESTEQ_I:
Simon Marlow's avatar
Simon Marlow committed
180
         debugBelch("TESTEQ_I  %ld, fail to %d\n", literals[instrs[pc]],
181
182
                                                      instrs[pc+1]);
         pc += 2; break;
183

184
      case bci_TESTLT_F:
Simon Marlow's avatar
Simon Marlow committed
185
         debugBelch("TESTLT_F  %ld, fail to %d\n", literals[instrs[pc]],
186
187
188
                                                      instrs[pc+1]);
         pc += 2; break;
      case bci_TESTEQ_F:
Simon Marlow's avatar
Simon Marlow committed
189
         debugBelch("TESTEQ_F  %ld, fail to %d\n", literals[instrs[pc]],
190
191
                                                      instrs[pc+1]);
         pc += 2; break;
192

193
      case bci_TESTLT_D:
Simon Marlow's avatar
Simon Marlow committed
194
         debugBelch("TESTLT_D  %ld, fail to %d\n", literals[instrs[pc]],
195
196
197
                                                      instrs[pc+1]);
         pc += 2; break;
      case bci_TESTEQ_D:
Simon Marlow's avatar
Simon Marlow committed
198
         debugBelch("TESTEQ_D  %ld, fail to %d\n", literals[instrs[pc]],
199
200
                                                      instrs[pc+1]);
         pc += 2; break;
201

202
      case bci_TESTLT_P:
203
         debugBelch("TESTLT_P  %d, fail to %d\n", instrs[pc],
204
205
206
                                                      instrs[pc+1]);
         pc += 2; break;
      case bci_TESTEQ_P:
207
         debugBelch("TESTEQ_P  %d, fail to %d\n", instrs[pc],
208
209
                                                      instrs[pc+1]);
         pc += 2; break;
210
      case bci_CASEFAIL: 
211
         debugBelch("CASEFAIL\n" );
212
213
         break;
      case bci_JMP:
214
         debugBelch("JMP to    %d\n", instrs[pc]);
215
         pc += 1; break;
216

217
      case bci_ENTER:
218
         debugBelch("ENTER\n");
219
         break;
220
221

      case bci_RETURN:
222
         debugBelch("RETURN\n" );
223
224
	 break;
      case bci_RETURN_P:
225
         debugBelch("RETURN_P\n" );
226
227
	 break;
      case bci_RETURN_N:
228
         debugBelch("RETURN_N\n" );
229
230
	 break;
      case bci_RETURN_F:
231
         debugBelch("RETURN_F\n" );
232
233
	 break;
      case bci_RETURN_D:
234
         debugBelch("RETURN_D\n" );
235
236
	 break;
      case bci_RETURN_L:
237
         debugBelch("RETURN_L\n" );
238
239
	 break;
      case bci_RETURN_V:
240
         debugBelch("RETURN_V\n" );
241
242
	 break;

243
      default:
244
         barf("disInstr: unknown opcode %u", (unsigned int) instr);
245
246
   }
   return pc;
247
248
}

249

250
251
252
253
254
255
/* Something of a kludge .. how do we know where the end of the insn
   array is, since it isn't recorded anywhere?  Answer: the first
   short is the number of bytecodes which follow it.  
   See ByteCodeGen.linkBCO.insns_arr for construction ...  
*/
void disassemble( StgBCO *bco )
256
{
257
   nat i, j;
sof's avatar
sof committed
258
   StgWord16*     instrs    = (StgWord16*)(bco->instrs->payload);
259
260
261
   StgMutArrPtrs* ptrs      = bco->ptrs;
   nat            nbcs      = (int)instrs[0];
   nat            pc        = 1;
262

263
   debugBelch("BCO\n" );
264
265
   pc = 1;
   while (pc <= nbcs) {
266
      debugBelch("\t%2d:  ", pc );
267
268
      pc = disInstr ( bco, pc );
   }
269

270
   debugBelch("INSTRS:\n   " );
271
272
   j = 16;
   for (i = 0; i < nbcs; i++) {
273
      debugBelch("%3d ", (int)instrs[i] );
274
      j--; 
275
      if (j == 0) { j = 16; debugBelch("\n   "); };
276
   }
277
   debugBelch("\n");
278

279
   debugBelch("PTRS:\n   " );
280
281
   j = 8;
   for (i = 0; i < ptrs->ptrs; i++) {
282
      debugBelch("%8p ", ptrs->payload[i] );
283
      j--; 
284
      if (j == 0) { j = 8; debugBelch("\n   "); };
285
   }
286
   debugBelch("\n");
287

288
   debugBelch("\n");
289
   ASSERT(pc == nbcs+1);
290
291
}

292
#endif /* DEBUG */