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