1 // $Id: op.cpp,v 1.26 2004/01/20 04:10:26 ericb Exp $
2 //
3 // This software is subject to the terms of the IBM Jikes Compiler
4 // License Agreement available at the following URL:
5 // http://ibm.com/developerworks/opensource/jikes.
6 // Copyright (C) 1996, 2004 IBM Corporation and others.  All Rights Reserved.
7 // You must accept the terms of that agreement to use this software.
8 //
9 
10 #include "op.h"
11 #include "class.h"
12 
13 #ifdef HAVE_JIKES_NAMESPACE
14 namespace Jikes { // Open namespace Jikes block
15 #endif
16 
17 
18 #ifdef JIKES_DEBUG
OpDesc(Opcode opc,const char ** name,const char ** desc)19 int Operators::OpDesc(Opcode opc, const char** name, const char** desc)
20 {
21     struct OpEntry
22     {
23         const char* op_name;
24         const char* op_desc;
25         char arg_bytes;
26     };
27 
28     static struct OpEntry table[] =
29     {
30         {"nop", "do nothing", 0},
31         {"aconst_null", "push null", 0},
32         {"iconst_m1", "push int constant -1", 0},
33         {"iconst_0", "push int constant 0", 0},
34         {"iconst_1", "push int constant 1", 0},
35         {"iconst_2", "push int constant 2", 0},
36         {"iconst_3", "push int constant 3", 0},
37         {"iconst_4", "push int constant 4", 0},
38         {"iconst_5", "push int constant 5", 0},
39         {"lconst_0", "push long constant 0", 0},
40         {"lconst_1", "push long constant 1", 0},
41         {"fconst_0", "push float 0.0", 0},
42         {"fconst_1", "push float 1.0", 0},
43         {"fconst_2", "push float 2.0", 0},
44         {"dconst_0", "push double 0.0", 0},
45         {"dconst_1", "push double 1.0", 0},
46         {"bipush", "push byte", 1},
47         {"sipush", "push short", 2},
48         {"ldc", "push item from constant pool", 1},
49         {"ldc_w", "push item from constant pool (wide index)", 2},
50         {"ldc2_w", "push long or double from constant pool (wide index)", 2},
51         {"iload", "load int from local variable", 1},
52         {"lload", "load long from local variable", 1},
53         {"fload", "load float from local variable", 1},
54         {"dload", "load double from local variable", 1},
55         {"aload", "load reference from local variable", 1},
56         {"iload_0", "load int from local variable 0", 0},
57         {"iload_1", "load int from local variable 1", 0},
58         {"iload_2", "load int from local variable 2", 0},
59         {"iload_3", "load int from local variable 3", 0},
60         {"lload_0", "load long from local variable 0", 0},
61         {"lload_1", "load long from local variable 1", 0},
62         {"lload_2", "load long from local variable 2", 0},
63         {"lload_3", "load long from local variable 3", 0},
64         {"fload_0", "load float from local variable 0", 0},
65         {"fload_1", "load float from local variable 1", 0},
66         {"fload_2", "load float from local variable 2", 0},
67         {"fload_3", "load float from local variable 3", 0},
68         {"dload_0", "load double from local variable 0", 0},
69         {"dload_1", "load double from local variable 1", 0},
70         {"dload_2", "load double from local variable 2", 0},
71         {"dload_3", "load double from local variable 3", 0},
72         {"aload_0", "load reference from local variable 0", 0},
73         {"aload_1", "load reference from local variable 1", 0},
74         {"aload_2", "load reference from local variable 2", 0},
75         {"aload_3", "load reference from local variable 3", 0},
76         {"iaload", "load int from array", 0},
77         {"laload", "load long from array", 0},
78         {"faload", "load float from array", 0},
79         {"daload", "load double from array", 0},
80         {"aaload", "load reference from array", 0},
81         {"baload", "load byte or boolean from array", 0},
82         {"caload", "load char from array", 0},
83         {"saload", "load short from array", 0},
84         {"istore", "store int into local variable", 1},
85         {"lstore", "store long into local variable", 1},
86         {"fstore", "store float into local variable", 1},
87         {"dstore", "store double into local variable", 1},
88         {"astore", "store reference into local variable", 1},
89         {"istore_0", "store int into local variable 0", 0},
90         {"istore_1", "store int into local variable 1", 0},
91         {"istore_2", "store int into local variable 2", 0},
92         {"istore_3", "store int into local variable 3", 0},
93         {"lstore_0", "store long into local variable 0", 0},
94         {"lstore_1", "store long into local variable 1", 0},
95         {"lstore_2", "store long into local variable 2", 0},
96         {"lstore_3", "store long into local variable 3", 0},
97         {"fstore_0", "store float into local variable 0", 0},
98         {"fstore_1", "store float into local variable 1", 0},
99         {"fstore_2", "store float into local variable 2", 0},
100         {"fstore_3", "store float into local variable 3", 0},
101         {"dstore_0", "store double into local variable 0", 0},
102         {"dstore_1", "store double into local variable 1", 0},
103         {"dstore_2", "store double into local variable 2", 0},
104         {"dstore_3", "store double into local variable 3", 0},
105         {"astore_0", "store reference into local variable 0", 0},
106         {"astore_1", "store reference into local variable 1", 0},
107         {"astore_2", "store reference into local variable 2", 0},
108         {"astore_3", "store reference into local variable 3", 0},
109         {"iastore", "store into int array", 0},
110         {"lastore", "store into long array", 0},
111         {"fastore", "store into float array", 0},
112         {"dastore", "store into double array", 0},
113         {"aastore", "store into reference array", 0},
114         {"bastore", "store into byte or boolean array", 0},
115         {"castore", "store into char array", 0},
116         {"sastore", "store into short array", 0},
117         {"pop", "pop top operand stack byte", 0},
118         {"pop2", "pop top two operand stack bytes", 0},
119         {"dup", "duplicate top operand stack byte", 0},
120         {"dup_x1", "duplicate top operand stack byte under 1 byte", 0},
121         {"dup_x2", "duplicate top operand stack byte under 2 bytes", 0},
122         {"dup2", "duplicate top two operand stack bytes", 0},
123         {"dup2_x1", "duplicate top two operand stack bytes under 1 byte", 0},
124         {"dup2_x2", "duplicate top two operand stack bytes under 2 bytes", 0},
125         {"swap", "swap top two operand stack bytes", 0},
126         {"iadd", "add int", 0},
127         {"ladd", "add long", 0},
128         {"fadd", "add float", 0},
129         {"dadd", "add double", 0},
130         {"isub", "subtract int", 0},
131         {"lsub", "subtract long", 0},
132         {"fsub", "substract float", 0},
133         {"dsub", "subtract double", 0},
134         {"imul", "multiply int", 0},
135         {"lmul", "multiply long", 0},
136         {"fmul", "multiply float", 0},
137         {"dmul", "multiply double", 0},
138         {"idiv", "divide int", 0},
139         {"ldiv", "divide long", 0},
140         {"fdiv", "divide float", 0},
141         {"ddiv", "divide double", 0},
142         {"irem", "remainder int", 0},
143         {"lrem", "remainder long", 0},
144         {"frem", "remainder float", 0},
145         {"drem", "remainder double", 0},
146         {"ineg", "negate int", 0},
147         {"lneg", "negate long", 0},
148         {"fneg", "negate float", 0},
149         {"dneg", "negate double", 0},
150         {"ishl", "shift left int", 0},
151         {"lshl", "shift left long", 0},
152         {"ishr", "shift right int", 0},
153         {"lshr", "shift right long", 0},
154         {"iushr", "logical shift right int", 0},
155         {"lushr", "logical shift right long", 0},
156         {"iand", "boolean and int", 0},
157         {"land", "boolean and long", 0},
158         {"ior", "boolean or int", 0},
159         {"lor", "boolean or long", 0},
160         {"ixor", "boolean xor int", 0},
161         {"lxor", "boolean xor long", 0},
162         {"iinc", "increment local variable by constant", 2},
163         {"i2l", "convert int to long", 0},
164         {"i2f", "convert int to float", 0},
165         {"i2d", "convert int to double", 0},
166         {"l2i", "convert long to int", 0},
167         {"l2f", "convert long to float", 0},
168         {"l2d", "convert long to double", 0},
169         {"f2i", "convert float to int", 0},
170         {"f2l", "convert float to long", 0},
171         {"f2d", "convert float to double", 0},
172         {"d2i", "convert double to int", 0},
173         {"d2l", "convert double to long", 0},
174         {"d2f", "convert double to float", 0},
175         {"i2b", "convert int to byte", 0},
176         {"i2c", "convert int to char", 0},
177         {"i2s", "convert int to short", 0},
178         {"lcmp", "compare long", 0},
179         {"fcmpl", "compare float less", 0},
180         {"fcmpg", "compare float greater", 0},
181         {"dcmpl", "compare double less", 0},
182         {"dcmpg", "compare double greater", 0},
183         {"ifeq", "branch if int eq zero", 2},
184         {"ifne", "branch if int ne zero", 2},
185         {"iflt", "branch if int lt zero", 2},
186         {"ifge", "branch if int ge zero", 2},
187         {"ifgt", "branch if int gt zero", 2},
188         {"ifle", "branch if int le zero", 2},
189         {"if_icmpeq", "branch if int comparison eq", 2},
190         {"if_icmpne", "branch if int comparison ne", 2},
191         {"if_icmplt", "branch if int comparison lt", 2},
192         {"if_icmpge", "branch if int comparison ge", 2},
193         {"if_icmpgt", "branch if int comparison gt", 2},
194         {"if_icmple", "branch if int comparison le", 2},
195         {"if_acmpeq", "branch if reference comparison eq", 2},
196         {"if_acmpne", "branch if reference comparison ne", 2},
197         {"goto", "branch always", 2},
198         {"jsr", "jump subroutine, deprecated", 2},
199         {"ret", "return from subroutine, deprecated", 2},
200         {"tableswitch", "access jump table by index and jump", 12},
201         {"lookupswitch", "access jump table by key match and jump", 8},
202         {"ireturn", "return int from method", 0},
203         {"lreturn", "return long from method", 0},
204         {"freturn", "return float from method", 0},
205         {"dreturn", "return double from method", 0},
206         {"areturn", "return reference from method", 0},
207         {"return", "return void from method", 0},
208         {"getstatic", "get static field from class", 2},
209         {"putstatic", "set static field in class", 2},
210         {"getfield", "fetch field from object", 2},
211         {"putfield", "set field in object", 2},
212         {"invokevirtual", "invoke polymorphic instance method; dispatch based on runtime type", 2},
213         {"invokespecial", "invoke constructor, private, or superclass instance method; dispatch based on compile-time type", 2},
214         {"invokestatic", "invoke a class (static) method", 2},
215         {"invokeinterface", "invoke interface method", 4},
216         {"xxxunusedxxx", "xxxunusedxxx", 0},
217         {"new", "create new object", 2},
218         {"newarray", "create new array", 1},
219         {"anewarray", "create new array of references", 2},
220         {"arraylength", "get length of array", 0},
221         {"athrow", "throw exception or error", 0},
222         {"checkcast", "check whether object is of given type", 2},
223         {"instanceof", "determine if object is of given type", 2},
224         {"monitorenter", "enter monitor for object", 0},
225         {"monitorexit", "exit monitor for object", 0},
226         {"wide", "", 0}, // special cased elsewhere
227         {"multianewarray", "create new multidimensional array", 3},
228         {"ifnull", "branch if reference is null", 2},
229         {"ifnonnull", "branch if reference not null", 2},
230         {"goto_w", "branch always (wide index)", 4},
231         {"jsr_w", "jump subroutine (wide index), deprecated", 4}
232         // no need to list SOFTWARE and HARDWARE here
233     };
234 
235     if (opc == OP_SOFTWARE)
236     {
237         if (name)
238             *name = "software";
239         if (desc)
240             *desc = "reserved for software use";
241     }
242     else if (opc == OP_HARDWARE)
243     {
244         if (name)
245             *name = "hardware";
246         if (desc)
247             *desc = "reserved for hardware use";
248     }
249     else if (opc <= 0xc9)
250     {
251         if (name)
252             *name = table[opc].op_name;
253         if (desc)
254             *desc = table[opc].op_desc;
255         return table[opc].arg_bytes;
256     }
257     else
258     {
259         if (name)
260             *name = "illegal";
261         if (desc)
262             *desc = "illegal";
263     }
264     return 0;
265 }
266 
OpLine(const ConstantPool & constant_pool,char hdr,int pc,const char * name,char * args,const char * desc,OpInfo info_kind,unsigned info_index)267 void Operators::OpLine(const ConstantPool& constant_pool, char hdr, int pc,
268                        const char* name, char* args, const char* desc,
269                        OpInfo info_kind, unsigned info_index)
270 {
271     // Generate line of opcode dump, info is extra info.
272     Coutput << hdr;
273     Coutput.width(5);
274     int len = strlen(name);
275     Coutput << pc << '\t';
276     if (info_kind == INFO_WIDE)
277     {
278         len += 5;
279         Coutput << "wide ";
280     }
281     Coutput << name;
282     if (strlen(args))
283     {
284         Coutput << ' ' << args;
285         len += (strlen(args) + 1);
286     }
287     if (len < 8)
288         Coutput << "\t\t\t";
289     else if (len < 16)
290         Coutput << "\t\t";
291     else Coutput << "\t";
292 
293     switch (info_kind)
294     {
295     case INFO_CONST:
296         if (info_index <= constant_pool.Length())
297         {
298             Coutput << '(';
299             constant_pool[info_index] -> Describe(constant_pool);
300             Coutput << ')';
301         }
302         else Coutput << "(illegal)";
303         break;
304     case INFO_LOCAL:
305     case INFO_WIDE:
306         Coutput << "local#" << info_index;
307         break;
308     default:
309         ; // Do nothing.
310     }
311     //
312     // Skip desc for now: it's too long and should only
313     // be written at user request.
314     //  Coutput << ' ' << desc;
315     //
316     assert(desc);
317     Coutput << endl;
318 }
319 
OpDmp(const ConstantPool & constant_pool,const Tuple<u1> & code)320 void Operators::OpDmp(const ConstantPool& constant_pool, const Tuple<u1>& code)
321 {
322     assert(sizeof(int) == 4 && "Debugger must have 32-bit int");
323     unsigned pc = 0;
324     while (pc < code.Length())
325     {
326         OpInfo info_kind = INFO_NONE; // assume no extra info
327         unsigned info_index = 0;
328         unsigned pc_start = pc;
329         Opcode opc = (Opcode) GetAndSkipU1(code, pc);
330 
331         // Set name (mnemonic) and description of opcode. Also, ensure that
332         // enough bytes remain to complete the instruction.
333         const char* name;
334         const char* desc;
335         int need = OpDesc(opc, &name, &desc);
336         if (pc_start + need >= code.Length())
337         {
338             Coutput.width(5);
339             Coutput << pc_start << "  <incomplete: " << name << '>' << endl;
340             break;
341         }
342 
343         char argdesc[100];
344         argdesc[0] = U_NULL; // assume no argument description needed
345 
346         u1 au1;
347         i1 ai1;
348         i2 ai2;
349         i4 ai4;
350         switch (opc)
351         {
352         case OP_BIPUSH:
353             ai1 = GetAndSkipI1(code, pc);
354             sprintf(argdesc, "%d (%#02x)", ai1, ai1);
355             break;
356         case OP_SIPUSH:
357             ai2 = GetAndSkipI2(code, pc);
358             sprintf(argdesc, "%d (%#04x)", ai2, ai2);
359             break;
360         case OP_ILOAD: case OP_LLOAD: case OP_FLOAD: case OP_DLOAD:
361         case OP_ALOAD:
362         case OP_ISTORE: case OP_LSTORE: case OP_FSTORE: case OP_DSTORE:
363         case OP_ASTORE:
364         case OP_RET:
365             info_kind = INFO_LOCAL;
366             info_index = GetAndSkipU1(code, pc);
367             sprintf(argdesc, "%u", info_index);
368             break;
369         case OP_ILOAD_0: case OP_LLOAD_0: case OP_FLOAD_0: case OP_DLOAD_0:
370         case OP_ALOAD_0:
371         case OP_ISTORE_0: case OP_LSTORE_0: case OP_FSTORE_0: case OP_DSTORE_0:
372         case OP_ASTORE_0:
373             info_kind = INFO_LOCAL;
374             info_index = 0;
375             break;
376         case OP_ILOAD_1: case OP_LLOAD_1: case OP_FLOAD_1: case OP_DLOAD_1:
377         case OP_ALOAD_1:
378         case OP_ISTORE_1: case OP_LSTORE_1: case OP_FSTORE_1: case OP_DSTORE_1:
379         case OP_ASTORE_1:
380             info_kind = INFO_LOCAL;
381             info_index = 1;
382             break;
383         case OP_ILOAD_2: case OP_LLOAD_2: case OP_FLOAD_2: case OP_DLOAD_2:
384         case OP_ALOAD_2:
385         case OP_ISTORE_2: case OP_LSTORE_2: case OP_FSTORE_2: case OP_DSTORE_2:
386         case OP_ASTORE_2:
387             info_kind = INFO_LOCAL;
388             info_index = 2;
389             break;
390         case OP_ILOAD_3: case OP_LLOAD_3: case OP_FLOAD_3: case OP_DLOAD_3:
391         case OP_ALOAD_3:
392         case OP_ISTORE_3: case OP_LSTORE_3: case OP_FSTORE_3: case OP_DSTORE_3:
393         case OP_ASTORE_3:
394             info_kind = INFO_LOCAL;
395             info_index = 3;
396             break;
397         case OP_IINC:
398             info_index = GetAndSkipU1(code, pc);
399             ai1 = GetAndSkipI1(code, pc);
400             info_kind = INFO_LOCAL;
401             sprintf(argdesc, "%u, %d (%#02x)", info_index, ai1, ai1);
402             break;
403         case OP_IFEQ: case OP_IFNE:
404         case OP_IFLT: case OP_IFGE: case OP_IFGT: case OP_IFLE:
405         case OP_IF_ICMPEQ: case OP_IF_ICMPNE:
406         case OP_IF_ICMPLT: case OP_IF_ICMPGE:
407         case OP_IF_ICMPGT: case OP_IF_ICMPLE:
408         case OP_IF_ACMPEQ: case OP_IF_ACMPNE:
409         case OP_IFNULL: case OP_IFNONNULL:
410         case OP_GOTO:
411         case OP_JSR:
412             ai2 = GetAndSkipI2(code, pc);
413             // compute branch target
414             sprintf(argdesc, "%d (pc:%u)", ai2, ai2 + pc_start);
415             break;
416         case OP_TABLESWITCH:
417             {
418                 i4 def;
419                 i4 low;
420                 i4 high;
421                 i4 len;
422                 i4 val;
423                 unsigned pc_this;
424                 // account for padding
425                 while (pc % 4)
426                 {
427                     au1 = GetAndSkipU1(code, pc);
428                     if (au1)
429                         Coutput << "       <non-zero padding: " << au1 << '>'
430                                 << endl;
431                 }
432                 def = GetAndSkipI4(code, pc);
433                 low = GetAndSkipI4(code, pc);
434                 if (pc + 4 >= code.Length())
435                 {
436                     Coutput << "       <incomplete: " << name << '>' << endl;
437                     info_kind = INFO_DONE;
438                     break;
439                 }
440                 high = GetAndSkipI4(code, pc);
441                 sprintf(argdesc,
442                         "default:%d (pc:%u) low:%d (%#08x) high:%d (%#08x)",
443                         (int) def, (unsigned) def + pc_start,
444                         (int) low, (int) low, (int) high, (int) high);
445                 OpLine(constant_pool, ' ', pc_start, name,
446                        argdesc, desc, info_kind, info_index);
447                 len =  high - low + 1;
448                 while (len)
449                 {
450                     if (pc + 4 >= code.Length())
451                     {
452                         Coutput << "       <incomplete: " << name << '>'
453                                 << endl;
454                         break;
455                     }
456                     pc_this = pc;
457                     val = GetAndSkipI4(code, pc);
458                     low++;
459                     sprintf(argdesc, "match:%d (%#08x) offset:%d (pc:%u)",
460                             (int) low, (int) low,
461                             (int) val, (unsigned) val + pc_start);
462                     OpLine(constant_pool, '*', pc_this, name,
463                            argdesc, desc, INFO_NONE, 0);
464                     len--;
465                 }
466                 info_kind = INFO_DONE;
467             }
468             break;
469         case OP_LOOKUPSWITCH:
470             {
471                 i4 def;
472                 i4 npairs;
473                 i4 len;
474                 i4 match;
475                 i4 offset;
476                 // account for padding
477                 while (pc % 4)
478                 {
479                     au1 = GetAndSkipU1(code, pc);
480                     if (au1)
481                         Coutput << "       <non-zero padding: " << au1 << '>'
482                                 << endl;
483                 }
484                 def = GetAndSkipI4(code, pc);
485                 if (pc + 4 >= code.Length())
486                 {
487                     Coutput << "       <incomplete: " << name << '>' << endl;
488                     info_kind = INFO_DONE;
489                     break;
490                 }
491                 npairs = GetAndSkipI4(code, pc);
492                 sprintf(argdesc, "default:%d (pc:%u) npairs:%d",
493                         (int) def, (unsigned) def + pc_start, (int) npairs);
494                 OpLine(constant_pool, ' ', pc_start, name,
495                        argdesc, desc, info_kind, info_index);
496                 len = npairs;
497                 while (npairs)
498                 {
499                     unsigned pcb = pc;
500                     if (pc + 8 >= code.Length())
501                     {
502                         Coutput << "       <incomplete: " << name << '>'
503                                 << endl;
504                         break;
505                     }
506                     match = GetAndSkipI4(code, pc);
507                     offset = GetAndSkipI4(code, pc);
508                     sprintf(argdesc, "match:%d (%#08x) offset:%d (pc:%u)",
509                             (int) match, (int) match,
510                             (int) offset, (unsigned) offset + pc_start);
511                     OpLine(constant_pool, '*', pcb, name,
512                            argdesc, desc, INFO_NONE, 0);
513                     npairs--;
514                 }
515                 info_kind = INFO_DONE;
516             }
517             break;
518         case OP_LDC:
519             info_index = GetAndSkipU1(code, pc);
520             sprintf(argdesc, "%u", info_index);
521             info_kind = INFO_CONST;
522             break;
523         case OP_LDC_W: case OP_LDC2_W:
524         case OP_GETSTATIC: case OP_PUTSTATIC:
525         case OP_GETFIELD: case OP_PUTFIELD:
526         case OP_INVOKEVIRTUAL: case OP_INVOKESPECIAL: case OP_INVOKESTATIC:
527         case OP_NEW: case OP_ANEWARRAY:
528         case OP_CHECKCAST: case OP_INSTANCEOF:
529             info_index = GetAndSkipU2(code, pc);
530             sprintf(argdesc, "%u", info_index);
531             info_kind = INFO_CONST;
532             break;
533         case OP_INVOKEINTERFACE:
534             {
535                 info_index = GetAndSkipU2(code, pc);
536                 unsigned nargs = GetAndSkipU1(code, pc);
537                 au1 = GetAndSkipU1(code, pc);
538                 if (au1)
539                     Coutput << "       <non-zero padding: " << au1 << '>'
540                             << endl;
541                 sprintf(argdesc, "%u (%u args)", info_index, nargs);
542                 info_kind = INFO_CONST;
543             }
544             break;
545         case OP_NEWARRAY:
546             au1 = GetAndSkipU1(code, pc);
547             switch (au1)
548             {
549             case 4: sprintf(argdesc, "boolean[]"); break;
550             case 5: sprintf(argdesc, "char[]"); break;
551             case 6: sprintf(argdesc, "float[]"); break;
552             case 7: sprintf(argdesc, "double[]"); break;
553             case 8: sprintf(argdesc, "byte[]"); break;
554             case 9: sprintf(argdesc, "short[]"); break;
555             case 10: sprintf(argdesc, "int[]"); break;
556             case 11: sprintf(argdesc, "long[]"); break;
557             default:
558                 sprintf(argdesc, "<UNKNOWN:%u>", au1); break;
559             }
560             break;
561         case OP_WIDE:
562             {
563                 Opcode opc = (Opcode) GetAndSkipU1(code, pc);
564                 info_kind = INFO_WIDE;
565                 // Reset name (mnemonic) and description of modified opcode.
566                 need = OpDesc(opc, &name, &desc);
567                 if (pc_start + 1 + need * 2 >= code.Length())
568                 {
569                     Coutput.width(5);
570                     Coutput << pc_start << "  <incomplete: wide " << name
571                             << '>' << endl;
572                     info_kind = INFO_DONE;
573                     break;
574                 }
575                 switch (opc)
576                 {
577                 case OP_ILOAD: case OP_FLOAD: case OP_LLOAD: case OP_DLOAD:
578                 case OP_ALOAD:
579                 case OP_ISTORE: case OP_FSTORE: case OP_LSTORE: case OP_DSTORE:
580                 case OP_ASTORE:
581                 case OP_RET:
582                     info_index = GetAndSkipU2(code, pc);
583                     sprintf(argdesc, "%u", info_index);
584                     break;
585                 case OP_IINC:
586                     info_index = GetAndSkipU2(code, pc);
587                     ai2 = GetAndSkipI2(code, pc);
588                     sprintf(argdesc, "%u, %d (%#04x)", info_index, ai2, ai2);
589                     break;
590                 default:
591                     Coutput.width(5);
592                     Coutput << pc_start << "  <illegal wide instruction: "
593                             << name << '>' << endl;
594                     info_kind = INFO_DONE;
595                 }
596             }
597             break;
598         case OP_MULTIANEWARRAY:
599             info_index = GetAndSkipU2(code, pc);
600             au1 = GetAndSkipU1(code, pc);
601             info_kind = INFO_CONST;
602             // au1 gives dimensions
603             sprintf(argdesc, "%u, dims:%u", info_index, au1);
604             break;
605         case OP_GOTO_W: case OP_JSR_W:
606             ai4 = GetAndSkipI4(code, pc);
607             // ai4 gives offset (wide) of branch target
608             sprintf(argdesc, "%d (pc:%u)",
609                     (int) ai4, (unsigned) ai4 + pc_start);
610             break;
611         default:
612             ; // do nothing
613         }
614 
615         // output first part of description
616         if (info_kind != INFO_DONE)
617             OpLine(constant_pool, ' ', pc_start, name,
618                    argdesc, desc, info_kind, info_index);
619     }
620 }
621 #endif // JIKES_DEBUG
622 
623 
624 //
625 // stack_effect gives effect on stack of executing an opcode
626 //
627 int Operators::stack_effect[] =
628 {
629     0, // OP_NOP
630     1, // OP_ACONST_NULL
631     1, // OP_ICONST_M1
632     1, // OP_ICONST_0
633     1, // OP_ICONST_1
634     1, // OP_ICONST_2
635     1, // OP_ICONST_3
636     1, // OP_ICONST_4
637     1, // OP_ICONST_5
638     2, // OP_LCONST_0
639     2, // OP_LCONST_1
640     1, // OP_FCONST_0
641     1, // OP_FCONST_1
642     1, // OP_FCONST_2
643     2, // OP_DCONST_0
644     2, // OP_DCONST_1
645     1, // OP_BIPUSH
646     1, // OP_SIPUSH
647     1, // OP_LDC
648     1, // OP_LDC_W
649     2, // OP_LDC2_W
650     1, // OP_ILOAD
651     2, // OP_LLOAD
652     1, // OP_FLOAD
653     2, // OP_DLOAD
654     1, // OP_ALOAD
655     1, // OP_ILOAD_0
656     1, // OP_ILOAD_1
657     1, // OP_ILOAD_2
658     1, // OP_ILOAD_3
659     2, // OP_LLOAD_0
660     2, // OP_LLOAD_1
661     2, // OP_LLOAD_2
662     2, // OP_LLOAD_3
663     1, // OP_FLOAD_0
664     1, // OP_FLOAD_1
665     1, // OP_FLOAD_2
666     1, // OP_FLOAD_3
667     2, // OP_DLOAD_0
668     2, // OP_DLOAD_1
669     2, // OP_DLOAD_2
670     2, // OP_DLOAD_3
671     1, // OP_ALOAD_0
672     1, // OP_ALOAD_1
673     1, // OP_ALOAD_2
674     1, // OP_ALOAD_3
675    -1, // OP_IALOAD
676     0, // OP_LALOAD
677    -1, // OP_FALOAD
678     0, // OP_DALOAD
679    -1, // OP_AALOAD
680    -1, // OP_BALOAD
681    -1, // OP_CALOAD
682    -1, // OP_SALOAD
683    -1, // OP_ISTORE
684    -2, // OP_LSTORE
685    -1, // OP_FSTORE
686    -2, // OP_DSTORE
687    -1, // OP_ASTORE
688    -1, // OP_ISTORE_0
689    -1, // OP_ISTORE_1
690    -1, // OP_ISTORE_2
691    -1, // OP_ISTORE_3
692    -2, // OP_LSTORE_0
693    -2, // OP_LSTORE_1
694    -2, // OP_LSTORE_2
695    -2, // OP_LSTORE_3
696    -1, // OP_FSTORE_0
697    -1, // OP_FSTORE_1
698    -1, // OP_FSTORE_2
699    -1, // OP_FSTORE_3
700    -2, // OP_DSTORE_0
701    -2, // OP_DSTORE_1
702    -2, // OP_DSTORE_2
703    -2, // OP_DSTORE_3
704    -1, // OP_ASTORE_0
705    -1, // OP_ASTORE_1
706    -1, // OP_ASTORE_2
707    -1, // OP_ASTORE_3
708    -3, // OP_IASTORE
709    -4, // OP_LASTORE
710    -3, // OP_FASTORE
711    -4, // OP_DASTORE
712    -3, // OP_AASTORE
713    -3, // OP_BASTORE
714    -3, // OP_CASTORE
715    -3, // OP_SASTORE
716    -1, // OP_POP
717    -2, // OP_POP2
718     1, // OP_DUP
719     1, // OP_DUP_X1
720     1, // OP_DUP_X2
721     2, // OP_DUP2
722     2, // OP_DUP2_X1
723     2, // OP_DUP2_X2
724     0, // OP_SWAP
725    -1, // OP_IADD
726    -2, // OP_LADD
727    -1, // OP_FADD
728    -2, // OP_DADD
729    -1, // OP_ISUB
730    -2, // OP_LSUB
731    -1, // OP_FSUB
732    -2, // OP_DSUB
733    -1, // OP_IMUL
734    -2, // OP_LMUL
735    -1, // OP_FMUL
736    -2, // OP_DMUL
737    -1, // OP_IDIV
738    -2, // OP_LDIV
739    -1, // OP_FDIV
740    -2, // OP_DDIV
741    -1, // OP_IREM
742    -2, // OP_LREM
743    -1, // OP_FREM
744    -2, // OP_DREM
745     0, // OP_INEG
746     0, // OP_LNEG
747     0, // OP_FNEG
748     0, // OP_DNEG
749    -1, // OP_ISHL
750    -1, // OP_LSHL
751    -1, // OP_ISHR
752    -1, // OP_LSHR
753    -1, // OP_IUSHR
754    -1, // OP_LUSHR
755    -1, // OP_IAND
756    -2, // OP_LAND
757    -1, // OP_IOR
758    -2, // OP_LOR
759    -1, // OP_IXOR
760    -2, // OP_LXOR
761     0, // OP_IINC
762     1, // OP_I2L
763     0, // OP_I2F
764     1, // OP_I2D
765    -1, // OP_L2I
766    -1, // OP_L2F
767     0, // OP_L2D
768     0, // OP_F2I
769     1, // OP_F2L
770     1, // OP_F2D
771    -1, // OP_D2I
772     0, // OP_D2L
773    -1, // OP_D2F
774     0, // OP_I2B
775     0, // OP_I2C
776     0, // OP_I2S
777    -3, // OP_LCMP
778    -1, // OP_FCMPL
779    -1, // OP_FCMPG
780    -3, // OP_DCMPL
781    -3, // OP_DCMPG
782    -1, // OP_IFEQ
783    -1, // OP_IFNE
784    -1, // OP_IFLT
785    -1, // OP_IFGE
786    -1, // OP_IFGT
787    -1, // OP_IFLE
788    -2, // OP_IF_ICMPEQ
789    -2, // OP_IF_ICMPNE
790    -2, // OP_IF_ICMPLT
791    -2, // OP_IF_ICMPGE
792    -2, // OP_IF_ICMPGT
793    -2, // OP_IF_ICMPLE
794    -2, // OP_IF_ACMPEQ
795    -2, // OP_IF_ACMPNE
796     0, // OP_GOTO
797     0, // OP_JSR, caller must adjust stack by +1 at jsr target
798     0, // OP_RET
799    -1, // OP_TABLESWITCH
800    -1, // OP_LOOKUPSWITCH
801    -1, // OP_IRETURN
802    -2, // OP_LRETURN
803    -1, // OP_FRETURN
804    -2, // OP_DRETURN
805    -1, // OP_ARETURN
806     0, // OP_RETURN
807     1, // OP_GETSTATIC, caller must adjust +1 if long or double
808    -1, // OP_PUTSTATIC, caller must adjust -1 if long or double
809     0, // OP_GETFIELD, caller must adjust +1 if long or double
810    -2, // OP_PUTFIELD, caller must adjust -1 if long or double
811    -1, // OP_INVOKEVIRTUAL,  caller must adjust +return-args_length
812    -1, // OP_INVOKESPECIAL,  caller must adjust +return-args_length
813     0, // OP_INVOKESTATIC,   caller must adjust +return-args_length
814    -1, // OP_INVOKEINTERFACE, caller must adjust +return-args_length
815     0, // OP_XXXUNUSEDXXX
816     1, // OP_NEW
817     0, // OP_NEWARRAY
818     0, // OP_ANEWARRAY
819     0, // OP_ARRAYLENGTH
820    -1, // OP_ATHROW
821     0, // OP_CHECKCAST
822     0, // OP_INSTANCEOF
823    -1, // OP_MONITORENTER
824    -1, // OP_MONITOREXIT
825     0, // OP_WIDE
826     0, // OP_MULTIANEWARRAY, caller must adjust 1-dims
827    -1, // OP_IFNULL
828    -1, // OP_IFNONNULL
829     0, // OP_GOTO_W
830     0  // OP_JSR_W, caller must adjust stack by +1 at jsr target
831     // no need to list SOFTWARE and HARDWARE here
832 };
833 
834 #ifdef HAVE_JIKES_NAMESPACE
835 } // Close namespace Jikes block
836 #endif
837 
838