OSDN Git Service

2007-04-23 Kyle Galloway <kgallowa@redhat.com>
[pf3gnuchains/gcc-fork.git] / libjava / interpret-run.cc
1 // interpret-run.cc - Code to interpret bytecode
2
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 /* This file is meant only to be included in interpret.cc, it should not be
12  * compiled directly.   */
13
14   using namespace java::lang::reflect;
15   
16   pc_t pc = NULL;
17
18   // FRAME_DESC registers this particular invocation as the top-most
19   // interpreter frame.  This lets the stack tracing code (for
20   // Throwable) print information about the method being interpreted
21   // rather than about the interpreter itself.  FRAME_DESC has a
22   // destructor so it cleans up automatically when the interpreter
23   // returns.
24   java::lang::Thread *thread = java::lang::Thread::currentThread();
25   
26 #ifdef DEBUG
27   _Jv_InterpFrame frame_desc (meth, thread, NULL, &pc);
28 #else
29   _Jv_InterpFrame frame_desc (meth, thread);
30 #endif
31
32   _Jv_word stack[meth->max_stack];
33   _Jv_word *sp = stack;
34
35   _Jv_word locals[meth->max_locals];
36
37 #ifdef DEBUG
38   // This is the information needed to get and set local variables with
39   // proper type checking.
40   frame_desc.locals = locals;
41   char locals_type[meth->max_locals];
42   frame_desc.locals_type = locals_type;
43   
44   // Set all slots as invalid until they are written to.
45   memset (locals_type, 'x', meth->max_locals);
46   
47   // We need to set the local variable types for the method arguments since
48   // they are valid at invocation.
49   
50   _Jv_Method *method = meth->get_method ();
51   int type_ctr = 0;
52   
53   // If the method is non-static, we need to set the type for the "this" pointer.
54   if ((method->accflags & java::lang::reflect::Modifier::STATIC) == 0)
55     {
56       if (args)
57         {
58           // Set the "this" pointer for this frame.
59           _Jv_word *this_ptr = reinterpret_cast<_Jv_word *> (args);
60           frame_desc.obj_ptr = this_ptr[0].o;
61         }
62
63       frame_desc.locals_type[0] = 'o';
64       type_ctr++;
65     }
66   
67   // Now parse the method signature to set the types of the other arguments.  
68   int sig_len = method->signature->len ();
69   char *signature = method->signature->chars ();
70   for (int i = 1; signature[i] != ')' && i <= sig_len; i++)
71     {
72       if (signature[i] == 'Z' || signature[i] == 'B' || signature[i] == 'C' 
73           || signature[i] == 'S' || signature[i] == 'I')
74         {
75           frame_desc.locals_type[type_ctr] = 'i';
76           type_ctr++;
77           continue;
78         }
79       else if (signature[i] == 'F')
80         {
81           frame_desc.locals_type[type_ctr] = 'f';
82           type_ctr++;
83           continue;
84         }
85       else if (signature[i] == 'J')
86         {
87           frame_desc.locals_type[type_ctr] = 'l';
88           frame_desc.locals_type[type_ctr+1] = 'x';
89           type_ctr += 2;
90           continue;
91         }
92       else if (signature[i] == 'D')
93         {
94           frame_desc.locals_type[type_ctr] = 'd';
95           frame_desc.locals_type[type_ctr+1] = 'x';
96           type_ctr += 2;
97           continue;
98         }
99       else if (signature[i] == 'L')
100         {
101           frame_desc.locals_type[type_ctr] = 'o';
102           type_ctr++;
103           while (signature[i] != ';')
104             i++;
105           continue;
106         }
107       else if (signature[i] == '[')
108         {
109           frame_desc.locals_type[type_ctr] = 'o';
110           type_ctr++;
111           
112           // Ignore multi-dimensional arrays.
113           while (signature[i] == '[')
114             i++;
115           
116           // Check for an object array
117           if (signature[i] == 'L')
118             {
119               while (signature[i] != ';')
120                 i++;
121             }
122           continue;
123         }
124     }
125 #endif /* DEBUG */
126
127 #define INSN_LABEL(op) &&insn_##op
128
129   static const void *const insn_target[] = 
130   {
131     INSN_LABEL(nop),
132     INSN_LABEL(aconst_null),
133     INSN_LABEL(iconst_m1),
134     INSN_LABEL(iconst_0),
135     INSN_LABEL(iconst_1),
136     INSN_LABEL(iconst_2),
137     INSN_LABEL(iconst_3),
138     INSN_LABEL(iconst_4),
139     INSN_LABEL(iconst_5),
140     INSN_LABEL(lconst_0),
141     INSN_LABEL(lconst_1),
142     INSN_LABEL(fconst_0),
143     INSN_LABEL(fconst_1),
144     INSN_LABEL(fconst_2),
145     INSN_LABEL(dconst_0),
146     INSN_LABEL(dconst_1),
147     INSN_LABEL(bipush),
148     INSN_LABEL(sipush),
149     INSN_LABEL(ldc),
150     INSN_LABEL(ldc_w),
151     INSN_LABEL(ldc2_w),
152     INSN_LABEL(iload),
153     INSN_LABEL(lload),
154     INSN_LABEL(fload),
155     INSN_LABEL(dload),
156     INSN_LABEL(aload),
157     INSN_LABEL(iload_0),
158     INSN_LABEL(iload_1),
159     INSN_LABEL(iload_2),
160     INSN_LABEL(iload_3),
161     INSN_LABEL(lload_0),
162     INSN_LABEL(lload_1),
163     INSN_LABEL(lload_2),
164     INSN_LABEL(lload_3),
165     INSN_LABEL(fload_0),
166     INSN_LABEL(fload_1),
167     INSN_LABEL(fload_2),
168     INSN_LABEL(fload_3),
169     INSN_LABEL(dload_0),
170     INSN_LABEL(dload_1),
171     INSN_LABEL(dload_2),
172     INSN_LABEL(dload_3),
173     INSN_LABEL(aload_0),
174     INSN_LABEL(aload_1),
175     INSN_LABEL(aload_2),
176     INSN_LABEL(aload_3),
177     INSN_LABEL(iaload),
178     INSN_LABEL(laload),
179     INSN_LABEL(faload),
180     INSN_LABEL(daload),
181     INSN_LABEL(aaload),
182     INSN_LABEL(baload),
183     INSN_LABEL(caload),
184     INSN_LABEL(saload),
185     INSN_LABEL(istore),
186     INSN_LABEL(lstore),
187     INSN_LABEL(fstore),
188     INSN_LABEL(dstore),
189     INSN_LABEL(astore),
190     INSN_LABEL(istore_0),
191     INSN_LABEL(istore_1),
192     INSN_LABEL(istore_2),
193     INSN_LABEL(istore_3),
194     INSN_LABEL(lstore_0),
195     INSN_LABEL(lstore_1),
196     INSN_LABEL(lstore_2),
197     INSN_LABEL(lstore_3),
198     INSN_LABEL(fstore_0),
199     INSN_LABEL(fstore_1),
200     INSN_LABEL(fstore_2),
201     INSN_LABEL(fstore_3),
202     INSN_LABEL(dstore_0),
203     INSN_LABEL(dstore_1),
204     INSN_LABEL(dstore_2),
205     INSN_LABEL(dstore_3),
206     INSN_LABEL(astore_0),
207     INSN_LABEL(astore_1),
208     INSN_LABEL(astore_2),
209     INSN_LABEL(astore_3),
210     INSN_LABEL(iastore),
211     INSN_LABEL(lastore),
212     INSN_LABEL(fastore),
213     INSN_LABEL(dastore),
214     INSN_LABEL(aastore),
215     INSN_LABEL(bastore),
216     INSN_LABEL(castore),
217     INSN_LABEL(sastore),
218     INSN_LABEL(pop),
219     INSN_LABEL(pop2),
220     INSN_LABEL(dup),
221     INSN_LABEL(dup_x1),
222     INSN_LABEL(dup_x2),
223     INSN_LABEL(dup2),
224     INSN_LABEL(dup2_x1),
225     INSN_LABEL(dup2_x2),
226     INSN_LABEL(swap),
227     INSN_LABEL(iadd),
228     INSN_LABEL(ladd),
229     INSN_LABEL(fadd),
230     INSN_LABEL(dadd),
231     INSN_LABEL(isub),
232     INSN_LABEL(lsub),
233     INSN_LABEL(fsub),
234     INSN_LABEL(dsub),
235     INSN_LABEL(imul),
236     INSN_LABEL(lmul),
237     INSN_LABEL(fmul),
238     INSN_LABEL(dmul),
239     INSN_LABEL(idiv),
240     INSN_LABEL(ldiv),
241     INSN_LABEL(fdiv),
242     INSN_LABEL(ddiv),
243     INSN_LABEL(irem),
244     INSN_LABEL(lrem),
245     INSN_LABEL(frem),
246     INSN_LABEL(drem),
247     INSN_LABEL(ineg),
248     INSN_LABEL(lneg),
249     INSN_LABEL(fneg),
250     INSN_LABEL(dneg),
251     INSN_LABEL(ishl),
252     INSN_LABEL(lshl),
253     INSN_LABEL(ishr),
254     INSN_LABEL(lshr),
255     INSN_LABEL(iushr),
256     INSN_LABEL(lushr),
257     INSN_LABEL(iand),
258     INSN_LABEL(land),
259     INSN_LABEL(ior),
260     INSN_LABEL(lor),
261     INSN_LABEL(ixor),
262     INSN_LABEL(lxor),
263     INSN_LABEL(iinc),
264     INSN_LABEL(i2l),
265     INSN_LABEL(i2f),
266     INSN_LABEL(i2d),
267     INSN_LABEL(l2i),
268     INSN_LABEL(l2f),
269     INSN_LABEL(l2d),
270     INSN_LABEL(f2i),
271     INSN_LABEL(f2l),
272     INSN_LABEL(f2d),
273     INSN_LABEL(d2i),
274     INSN_LABEL(d2l),
275     INSN_LABEL(d2f),
276     INSN_LABEL(i2b),
277     INSN_LABEL(i2c),
278     INSN_LABEL(i2s),
279     INSN_LABEL(lcmp),
280     INSN_LABEL(fcmpl),
281     INSN_LABEL(fcmpg),
282     INSN_LABEL(dcmpl),
283     INSN_LABEL(dcmpg),
284     INSN_LABEL(ifeq),
285     INSN_LABEL(ifne),
286     INSN_LABEL(iflt),
287     INSN_LABEL(ifge),
288     INSN_LABEL(ifgt),
289     INSN_LABEL(ifle),
290     INSN_LABEL(if_icmpeq),
291     INSN_LABEL(if_icmpne),
292     INSN_LABEL(if_icmplt),
293     INSN_LABEL(if_icmpge),
294     INSN_LABEL(if_icmpgt),
295     INSN_LABEL(if_icmple),
296     INSN_LABEL(if_acmpeq),
297     INSN_LABEL(if_acmpne),
298     INSN_LABEL(goto), 
299     INSN_LABEL(jsr),
300     INSN_LABEL(ret),
301     INSN_LABEL(tableswitch),
302     INSN_LABEL(lookupswitch),
303     INSN_LABEL(ireturn),
304     INSN_LABEL(lreturn),
305     INSN_LABEL(freturn),
306     INSN_LABEL(dreturn),
307     INSN_LABEL(areturn),
308     INSN_LABEL(return),
309     INSN_LABEL(getstatic),
310     INSN_LABEL(putstatic),
311     INSN_LABEL(getfield),
312     INSN_LABEL(putfield),
313     INSN_LABEL(invokevirtual),
314     INSN_LABEL(invokespecial),
315     INSN_LABEL(invokestatic),
316     INSN_LABEL(invokeinterface),
317     INSN_LABEL(breakpoint),
318     INSN_LABEL(new),
319     INSN_LABEL(newarray),
320     INSN_LABEL(anewarray),
321     INSN_LABEL(arraylength),
322     INSN_LABEL(athrow),
323     INSN_LABEL(checkcast),
324     INSN_LABEL(instanceof),
325     INSN_LABEL(monitorenter),
326     INSN_LABEL(monitorexit),
327 #ifdef DIRECT_THREADED
328     0, // wide
329 #else
330     INSN_LABEL(wide),
331 #endif
332     INSN_LABEL(multianewarray),
333     INSN_LABEL(ifnull),
334     INSN_LABEL(ifnonnull),
335     INSN_LABEL(goto_w),
336     INSN_LABEL(jsr_w),
337 #ifdef DIRECT_THREADED
338     INSN_LABEL (ldc_class)
339 #else
340     0
341 #endif
342   };
343
344 #ifdef DIRECT_THREADED
345
346 #ifdef DEBUG
347 #undef NEXT_INSN
348 #define NEXT_INSN                                                       \
349   do                                                                    \
350     {                                                                   \
351       if (JVMTI_REQUESTED_EVENT (SingleStep))                           \
352         {                                                               \
353           JNIEnv *env = _Jv_GetCurrentJNIEnv ();                        \
354           jmethodID method = meth->self;                                \
355           jlocation loc = meth->insn_index (pc);                        \
356           _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread,         \
357                                env, method, loc);                       \
358         }                                                               \
359       goto *((pc++)->insn);                                             \
360     }                                                                   \
361   while (0)
362 #else
363 #undef NEXT_INSN
364 #define NEXT_INSN goto *((pc++)->insn)
365 #endif
366
367 #define INTVAL() ((pc++)->int_val)
368 #define AVAL() ((pc++)->datum)
369
370 #define GET1S() INTVAL ()
371 #define GET2S() INTVAL ()
372 #define GET1U() INTVAL ()
373 #define GET2U() INTVAL ()
374 #define AVAL1U() AVAL ()
375 #define AVAL2U() AVAL ()
376 #define AVAL2UP() AVAL ()
377 #define SKIP_GOTO ++pc
378 #define GOTO_VAL() (insn_slot *) pc->datum
379 #define PCVAL(unionval) unionval.p
380 #define AMPAMP(label) &&label
381
382   // Compile if we must. NOTE: Double-check locking.
383   if (meth->prepared == NULL)
384     {
385       _Jv_MutexLock (&compile_mutex);
386       if (meth->prepared == NULL)
387         meth->compile (insn_target);
388       _Jv_MutexUnlock (&compile_mutex);
389     }
390
391   // If we're only compiling, stop here
392   if (args == NULL)
393     return;
394
395   pc = (insn_slot *) meth->prepared;
396
397 #else
398
399 #ifdef DEBUG
400 #define NEXT_INSN                                                       \
401   do                                                                    \
402     {                                                                   \
403       if (JVMTI_REQUESTED_EVENT (SingleStep))                           \
404         {                                                               \
405           JNIEnv *env = _Jv_GetCurrentJNIEnv ();                        \
406           jmethodID method = meth->self;                                \
407           jlocation loc = meth->insn_index (pc);                        \
408           _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread,         \
409                                env, method, loc);                       \
410         }                                                               \
411       goto *(insn_target[*pc++])
412 #else
413 #define NEXT_INSN goto *(insn_target[*pc++])
414 #endif
415
416 #define GET1S() get1s (pc++)
417 #define GET2S() (pc += 2, get2s (pc- 2))
418 #define GET1U() get1u (pc++)
419 #define GET2U() (pc += 2, get2u (pc - 2))
420   // Note that these could be more efficient when not handling 'ldc
421   // class'.
422 #define AVAL1U()                                                \
423   ({ int index = get1u (pc++);                                  \
424     _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
425 #define AVAL2U()                                                \
426   ({ int index = get2u (pc); pc += 2;                           \
427     _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
428   // Note that we don't need to resolve the pool entry here as class
429   // constants are never wide.
430 #define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; })
431 #define SKIP_GOTO pc += 2
432 #define GOTO_VAL() pc - 1 + get2s (pc)
433 #define PCVAL(unionval) unionval.i
434 #define AMPAMP(label) NULL
435
436   pc = meth->bytecode ();
437
438 #endif /* DIRECT_THREADED */
439
440 #define TAKE_GOTO pc = GOTO_VAL ()
441
442   /* Go straight at it!  the ffi raw format matches the internal
443      stack representation exactly.  At least, that's the idea.
444   */
445   memcpy ((void*) locals, (void*) args, meth->args_raw_size);
446
447   _Jv_word *pool_data = meth->defining_class->constants.data;
448
449   /* These three are temporaries for common code used by several
450      instructions.  */
451   void (*fun)();
452   _Jv_ResolvedMethod* rmeth;
453   int tmpval;
454
455   try
456     {
457       // We keep nop around.  It is used if we're interpreting the
458       // bytecodes and not doing direct threading.
459     insn_nop:
460       NEXT_INSN;
461
462       /* The first few instructions here are ordered according to their
463          frequency, in the hope that this will improve code locality a
464          little.  */
465
466     insn_aload_0:               // 0x2a
467       LOADA (0);
468       NEXT_INSN;
469
470     insn_iload:         // 0x15
471       LOADI (GET1U ());
472       NEXT_INSN;
473
474     insn_iload_1:               // 0x1b
475       LOADI (1);
476       NEXT_INSN;
477
478     insn_invokevirtual: // 0xb6
479       {
480         SAVE_PC();
481         int index = GET2U ();
482
483         /* _Jv_Linker::resolve_pool_entry returns immediately if the
484          * value already is resolved.  If we want to clutter up the
485          * code here to gain a little performance, then we can check
486          * the corresponding bit JV_CONSTANT_ResolvedFlag in the tag
487          * directly.  For now, I don't think it is worth it.  */
488
489         rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
490                                                    index)).rmethod;
491
492         sp -= rmeth->stack_item_count;
493
494         if (rmeth->method->accflags & Modifier::FINAL)
495           {
496             // We can't rely on NULLCHECK working if the method is final.
497             if (! sp[0].o)
498               throw_null_pointer_exception ();
499
500             // Final methods might not appear in the vtable.
501             fun = (void (*)()) rmeth->method->ncode;
502           }
503         else
504           {
505             NULLCHECK (sp[0].o);
506             jobject rcv = sp[0].o;
507             _Jv_VTable *table = *(_Jv_VTable**) rcv;
508             fun = (void (*)()) table->get_method (rmeth->method->index);
509           }
510
511 #ifdef DIRECT_THREADED
512         // Rewrite instruction so that we use a faster pre-resolved
513         // method.
514         pc[-2].insn = &&invokevirtual_resolved;
515         pc[-1].datum = rmeth;
516 #endif /* DIRECT_THREADED */
517       }
518       goto perform_invoke;
519
520 #ifdef DIRECT_THREADED
521     invokevirtual_resolved:
522       {
523         SAVE_PC();
524         rmeth = (_Jv_ResolvedMethod *) AVAL ();
525         sp -= rmeth->stack_item_count;
526
527         if (rmeth->method->accflags & Modifier::FINAL)
528           {
529             // We can't rely on NULLCHECK working if the method is final.
530             if (! sp[0].o)
531               throw_null_pointer_exception ();
532
533             // Final methods might not appear in the vtable.
534             fun = (void (*)()) rmeth->method->ncode;
535           }
536         else
537           {
538             jobject rcv = sp[0].o;
539             _Jv_VTable *table = *(_Jv_VTable**) rcv;
540             fun = (void (*)()) table->get_method (rmeth->method->index);
541           }
542       }
543       goto perform_invoke;
544 #endif /* DIRECT_THREADED */
545
546     perform_invoke:
547       {
548         /* here goes the magic again... */
549         ffi_cif *cif = &rmeth->cif;
550         ffi_raw *raw = (ffi_raw*) sp;
551
552         _Jv_value rvalue;
553
554 #if FFI_NATIVE_RAW_API
555         /* We assume that this is only implemented if it's correct      */
556         /* to use it here.  On a 64 bit machine, it never is.           */
557         ffi_raw_call (cif, fun, (void*)&rvalue, raw);
558 #else
559         ffi_java_raw_call (cif, fun, (void*)&rvalue, raw);
560 #endif
561
562         int rtype = cif->rtype->type;
563
564         /* the likelyhood of object, int, or void return is very high,
565          * so those are checked before the switch */
566         if (rtype == FFI_TYPE_POINTER)
567           {
568             PUSHA (rvalue.object_value);
569           }
570         else if (rtype == FFI_TYPE_SINT32)
571           {
572             PUSHI (rvalue.int_value);
573           }
574         else if (rtype == FFI_TYPE_VOID)
575           {
576             /* skip */
577           }
578         else
579           {
580             switch (rtype)
581               {
582               case FFI_TYPE_SINT8:
583                 PUSHI ((jbyte)(rvalue.int_value & 0xff));
584                 break;
585
586               case FFI_TYPE_SINT16:
587                 PUSHI ((jshort)(rvalue.int_value & 0xffff));
588                 break;
589
590               case FFI_TYPE_UINT16:
591                 PUSHI (rvalue.int_value & 0xffff);
592                 break;
593
594               case FFI_TYPE_FLOAT:
595                 PUSHF (rvalue.float_value);
596                 break;
597
598               case FFI_TYPE_DOUBLE:
599                 PUSHD (rvalue.double_value);
600                 break;
601
602               case FFI_TYPE_SINT64:
603                 PUSHL (rvalue.long_value);
604                 break;
605
606               default:
607                 throw_internal_error ("unknown return type in invokeXXX");
608               }
609           }
610       }
611       NEXT_INSN;
612
613     insn_aconst_null:
614       PUSHA (NULL);
615       NEXT_INSN;
616
617     insn_iconst_m1:
618       PUSHI (-1);
619       NEXT_INSN;
620
621     insn_iconst_0:
622       PUSHI (0);
623       NEXT_INSN;
624
625     insn_iconst_1:
626       PUSHI (1);
627       NEXT_INSN;
628
629     insn_iconst_2:
630       PUSHI (2);
631       NEXT_INSN;
632
633     insn_iconst_3:
634       PUSHI (3);
635       NEXT_INSN;
636
637     insn_iconst_4:
638       PUSHI (4);
639       NEXT_INSN;
640
641     insn_iconst_5:
642       PUSHI (5);
643       NEXT_INSN;
644
645     insn_lconst_0:
646       PUSHL (0);
647       NEXT_INSN;
648
649     insn_lconst_1:
650       PUSHL (1);
651       NEXT_INSN;
652
653     insn_fconst_0:
654       PUSHF (0);
655       NEXT_INSN;
656
657     insn_fconst_1:
658       PUSHF (1);
659       NEXT_INSN;
660
661     insn_fconst_2:
662       PUSHF (2);
663       NEXT_INSN;
664
665     insn_dconst_0:
666       PUSHD (0);
667       NEXT_INSN;
668
669     insn_dconst_1:
670       PUSHD (1);
671       NEXT_INSN;
672
673     insn_bipush:
674       // For direct threaded, bipush and sipush are the same.
675 #ifndef DIRECT_THREADED
676       PUSHI (GET1S ());
677       NEXT_INSN;
678 #endif /* DIRECT_THREADED */
679     insn_sipush:
680       PUSHI (GET2S ());
681       NEXT_INSN;
682
683     insn_ldc:
684       // For direct threaded, ldc and ldc_w are the same.
685 #ifndef DIRECT_THREADED
686       PUSHA ((jobject) AVAL1U ());
687       NEXT_INSN;
688 #endif /* DIRECT_THREADED */
689     insn_ldc_w:
690       PUSHA ((jobject) AVAL2U ());
691       NEXT_INSN;
692
693 #ifdef DIRECT_THREADED
694       // For direct threaded we have a separate 'ldc class' operation.
695     insn_ldc_class:
696       {
697         SAVE_PC();
698         // We could rewrite the instruction at this point.
699         int index = INTVAL ();
700         jobject k = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
701                                                      index)).o;
702         PUSHA (k);
703       }
704       NEXT_INSN;
705 #endif /* DIRECT_THREADED */
706
707     insn_ldc2_w:
708       {
709         void *where = AVAL2UP ();
710         memcpy (sp, where, 2*sizeof (_Jv_word));
711         sp += 2;
712       }
713       NEXT_INSN;
714
715     insn_lload:
716       LOADL (GET1U ());
717       NEXT_INSN;
718
719     insn_fload:
720       LOADF (GET1U ());
721       NEXT_INSN;
722
723     insn_dload:
724       LOADD (GET1U ());
725       NEXT_INSN;
726
727     insn_aload:
728       LOADA (GET1U ());
729       NEXT_INSN;
730
731     insn_iload_0:
732       LOADI (0);
733       NEXT_INSN;
734
735     insn_iload_2:
736       LOADI (2);
737       NEXT_INSN;
738
739     insn_iload_3:
740       LOADI (3);
741       NEXT_INSN;
742
743     insn_lload_0:
744       LOADL (0);
745       NEXT_INSN;
746
747     insn_lload_1:
748       LOADL (1);
749       NEXT_INSN;
750
751     insn_lload_2:
752       LOADL (2);
753       NEXT_INSN;
754
755     insn_lload_3:
756       LOADL (3);
757       NEXT_INSN;
758
759     insn_fload_0:
760       LOADF (0);
761       NEXT_INSN;
762
763     insn_fload_1:
764       LOADF (1);
765       NEXT_INSN;
766
767     insn_fload_2:
768       LOADF (2);
769       NEXT_INSN;
770
771     insn_fload_3:
772       LOADF (3);
773       NEXT_INSN;
774
775     insn_dload_0:
776       LOADD (0);
777       NEXT_INSN;
778
779     insn_dload_1:
780       LOADD (1);
781       NEXT_INSN;
782
783     insn_dload_2:
784       LOADD (2);
785       NEXT_INSN;
786
787     insn_dload_3:
788       LOADD (3);
789       NEXT_INSN;
790
791     insn_aload_1:
792       LOADA(1);
793       NEXT_INSN;
794
795     insn_aload_2:
796       LOADA(2);
797       NEXT_INSN;
798
799     insn_aload_3:
800       LOADA(3);
801       NEXT_INSN;
802
803     insn_iaload:
804       {
805         jint index = POPI();
806         jintArray arr = (jintArray) POPA();
807         NULLARRAYCHECK (arr);
808         ARRAYBOUNDSCHECK (arr, index);
809         PUSHI( elements(arr)[index] );
810       }
811       NEXT_INSN;
812
813     insn_laload:
814       {
815         jint index = POPI();
816         jlongArray arr = (jlongArray) POPA();
817         NULLARRAYCHECK (arr);
818         ARRAYBOUNDSCHECK (arr, index);
819         PUSHL( elements(arr)[index] );
820       }
821       NEXT_INSN;
822
823     insn_faload:
824       {
825         jint index = POPI();
826         jfloatArray arr = (jfloatArray) POPA();
827         NULLARRAYCHECK (arr);
828         ARRAYBOUNDSCHECK (arr, index);
829         PUSHF( elements(arr)[index] );
830       }
831       NEXT_INSN;
832
833     insn_daload:
834       {
835         jint index = POPI();
836         jdoubleArray arr = (jdoubleArray) POPA();
837         NULLARRAYCHECK (arr);
838         ARRAYBOUNDSCHECK (arr, index);
839         PUSHD( elements(arr)[index] );
840       }
841       NEXT_INSN;
842
843     insn_aaload:
844       {
845         jint index = POPI();
846         jobjectArray arr = (jobjectArray) POPA();
847         NULLARRAYCHECK (arr);
848         ARRAYBOUNDSCHECK (arr, index);
849         PUSHA( elements(arr)[index] );
850       }
851       NEXT_INSN;
852
853     insn_baload:
854       {
855         jint index = POPI();
856         jbyteArray arr = (jbyteArray) POPA();
857         NULLARRAYCHECK (arr);
858         ARRAYBOUNDSCHECK (arr, index);
859         PUSHI( elements(arr)[index] );
860       }
861       NEXT_INSN;
862
863     insn_caload:
864       {
865         jint index = POPI();
866         jcharArray arr = (jcharArray) POPA();
867         NULLARRAYCHECK (arr);
868         ARRAYBOUNDSCHECK (arr, index);
869         PUSHI( elements(arr)[index] );
870       }
871       NEXT_INSN;
872
873     insn_saload:
874       {
875         jint index = POPI();
876         jshortArray arr = (jshortArray) POPA();
877         NULLARRAYCHECK (arr);
878         ARRAYBOUNDSCHECK (arr, index);
879         PUSHI( elements(arr)[index] );
880       }
881       NEXT_INSN;
882
883     insn_istore:
884       STOREI (GET1U ());
885       NEXT_INSN;
886
887     insn_lstore:
888       STOREL (GET1U ());
889       NEXT_INSN;
890
891     insn_fstore:
892       STOREF (GET1U ());
893       NEXT_INSN;
894
895     insn_dstore:
896       STORED (GET1U ());
897       NEXT_INSN;
898
899     insn_astore:
900       STOREA (GET1U ());
901       NEXT_INSN;
902
903     insn_istore_0:
904       STOREI (0);
905       NEXT_INSN;
906
907     insn_istore_1:
908       STOREI (1);
909       NEXT_INSN;
910
911     insn_istore_2:
912       STOREI (2);
913       NEXT_INSN;
914
915     insn_istore_3:
916       STOREI (3);
917       NEXT_INSN;
918
919     insn_lstore_0:
920       STOREL (0);
921       NEXT_INSN;
922
923     insn_lstore_1:
924       STOREL (1);
925       NEXT_INSN;
926
927     insn_lstore_2:
928       STOREL (2);
929       NEXT_INSN;
930
931     insn_lstore_3:
932       STOREL (3);
933       NEXT_INSN;
934
935     insn_fstore_0:
936       STOREF (0);
937       NEXT_INSN;
938
939     insn_fstore_1:
940       STOREF (1);
941       NEXT_INSN;
942
943     insn_fstore_2:
944       STOREF (2);
945       NEXT_INSN;
946
947     insn_fstore_3:
948       STOREF (3);
949       NEXT_INSN;
950
951     insn_dstore_0:
952       STORED (0);
953       NEXT_INSN;
954
955     insn_dstore_1:
956       STORED (1);
957       NEXT_INSN;
958
959     insn_dstore_2:
960       STORED (2);
961       NEXT_INSN;
962
963     insn_dstore_3:
964       STORED (3);
965       NEXT_INSN;
966
967     insn_astore_0:
968       STOREA(0);
969       NEXT_INSN;
970
971     insn_astore_1:
972       STOREA(1);
973       NEXT_INSN;
974
975     insn_astore_2:
976       STOREA(2);
977       NEXT_INSN;
978
979     insn_astore_3:
980       STOREA(3);
981       NEXT_INSN;
982
983     insn_iastore:
984       {
985         jint value = POPI();
986         jint index  = POPI();
987         jintArray arr = (jintArray) POPA();
988         NULLARRAYCHECK (arr);
989         ARRAYBOUNDSCHECK (arr, index);
990         elements(arr)[index] = value;
991       }
992       NEXT_INSN;
993
994     insn_lastore:
995       {
996         jlong value = POPL();
997         jint index  = POPI();
998         jlongArray arr = (jlongArray) POPA();
999         NULLARRAYCHECK (arr);
1000         ARRAYBOUNDSCHECK (arr, index);
1001         elements(arr)[index] = value;
1002       }
1003       NEXT_INSN;
1004
1005     insn_fastore:
1006       {
1007         jfloat value = POPF();
1008         jint index  = POPI();
1009         jfloatArray arr = (jfloatArray) POPA();
1010         NULLARRAYCHECK (arr);
1011         ARRAYBOUNDSCHECK (arr, index);
1012         elements(arr)[index] = value;
1013       }
1014       NEXT_INSN;
1015
1016     insn_dastore:
1017       {
1018         jdouble value = POPD();
1019         jint index  = POPI();
1020         jdoubleArray arr = (jdoubleArray) POPA();
1021         NULLARRAYCHECK (arr);
1022         ARRAYBOUNDSCHECK (arr, index);
1023         elements(arr)[index] = value;
1024       }
1025       NEXT_INSN;
1026
1027     insn_aastore:
1028       {
1029         jobject value = POPA();
1030         jint index  = POPI();
1031         jobjectArray arr = (jobjectArray) POPA();
1032         NULLARRAYCHECK (arr);
1033         ARRAYBOUNDSCHECK (arr, index);
1034         _Jv_CheckArrayStore (arr, value);
1035         elements(arr)[index] = value;
1036       }
1037       NEXT_INSN;
1038
1039     insn_bastore:
1040       {
1041         jbyte value = (jbyte) POPI();
1042         jint index  = POPI();
1043         jbyteArray arr = (jbyteArray) POPA();
1044         NULLARRAYCHECK (arr);
1045         ARRAYBOUNDSCHECK (arr, index);
1046         elements(arr)[index] = value;
1047       }
1048       NEXT_INSN;
1049
1050     insn_castore:
1051       {
1052         jchar value = (jchar) POPI();
1053         jint index  = POPI();
1054         jcharArray arr = (jcharArray) POPA();
1055         NULLARRAYCHECK (arr);
1056         ARRAYBOUNDSCHECK (arr, index);
1057         elements(arr)[index] = value;
1058       }
1059       NEXT_INSN;
1060
1061     insn_sastore:
1062       {
1063         jshort value = (jshort) POPI();
1064         jint index  = POPI();
1065         jshortArray arr = (jshortArray) POPA();
1066         NULLARRAYCHECK (arr);
1067         ARRAYBOUNDSCHECK (arr, index);
1068         elements(arr)[index] = value;
1069       }
1070       NEXT_INSN;
1071
1072     insn_pop:
1073       sp -= 1;
1074       NEXT_INSN;
1075
1076     insn_pop2:
1077       sp -= 2;
1078       NEXT_INSN;
1079
1080     insn_dup:
1081       sp[0] = sp[-1];
1082       sp += 1;
1083       NEXT_INSN;
1084
1085     insn_dup_x1:
1086       dupx (sp, 1, 1); sp+=1;
1087       NEXT_INSN;
1088
1089     insn_dup_x2:
1090       dupx (sp, 1, 2); sp+=1;
1091       NEXT_INSN;
1092
1093     insn_dup2:
1094       sp[0] = sp[-2];
1095       sp[1] = sp[-1];
1096       sp += 2;
1097       NEXT_INSN;
1098
1099     insn_dup2_x1:
1100       dupx (sp, 2, 1); sp+=2;
1101       NEXT_INSN;
1102
1103     insn_dup2_x2:
1104       dupx (sp, 2, 2); sp+=2;
1105       NEXT_INSN;
1106
1107     insn_swap:
1108       {
1109         jobject tmp1 = POPA();
1110         jobject tmp2 = POPA();
1111         PUSHA (tmp1);
1112         PUSHA (tmp2);
1113       }
1114       NEXT_INSN;
1115
1116     insn_iadd:
1117       BINOPI(+);
1118       NEXT_INSN;
1119
1120     insn_ladd:
1121       BINOPL(+);
1122       NEXT_INSN;
1123
1124     insn_fadd:
1125       BINOPF(+);
1126       NEXT_INSN;
1127
1128     insn_dadd:
1129       BINOPD(+);
1130       NEXT_INSN;
1131
1132     insn_isub:
1133       BINOPI(-);
1134       NEXT_INSN;
1135
1136     insn_lsub:
1137       BINOPL(-);
1138       NEXT_INSN;
1139
1140     insn_fsub:
1141       BINOPF(-);
1142       NEXT_INSN;
1143
1144     insn_dsub:
1145       BINOPD(-);
1146       NEXT_INSN;
1147
1148     insn_imul:
1149       BINOPI(*);
1150       NEXT_INSN;
1151
1152     insn_lmul:
1153       BINOPL(*);
1154       NEXT_INSN;
1155
1156     insn_fmul:
1157       BINOPF(*);
1158       NEXT_INSN;
1159
1160     insn_dmul:
1161       BINOPD(*);
1162       NEXT_INSN;
1163
1164     insn_idiv:
1165       {
1166         SAVE_PC();
1167         jint value2 = POPI();
1168         jint value1 = POPI();
1169         jint res = _Jv_divI (value1, value2);
1170         PUSHI (res);
1171       }
1172       NEXT_INSN;
1173
1174     insn_ldiv:
1175       {
1176         SAVE_PC();
1177         jlong value2 = POPL();
1178         jlong value1 = POPL();
1179         jlong res = _Jv_divJ (value1, value2);
1180         PUSHL (res);
1181       }
1182       NEXT_INSN;
1183
1184     insn_fdiv:
1185       {
1186         jfloat value2 = POPF();
1187         jfloat value1 = POPF();
1188         jfloat res = value1 / value2;
1189         PUSHF (res);
1190       }
1191       NEXT_INSN;
1192
1193     insn_ddiv:
1194       {
1195         jdouble value2 = POPD();
1196         jdouble value1 = POPD();
1197         jdouble res = value1 / value2;
1198         PUSHD (res);
1199       }
1200       NEXT_INSN;
1201
1202     insn_irem:
1203       {
1204         SAVE_PC();
1205         jint value2 = POPI();
1206         jint value1 =  POPI();
1207         jint res = _Jv_remI (value1, value2);
1208         PUSHI (res);
1209       }
1210       NEXT_INSN;
1211
1212     insn_lrem:
1213       {
1214         SAVE_PC();
1215         jlong value2 = POPL();
1216         jlong value1 = POPL();
1217         jlong res = _Jv_remJ (value1, value2);
1218         PUSHL (res);
1219       }
1220       NEXT_INSN;
1221
1222     insn_frem:
1223       {
1224         jfloat value2 = POPF();
1225         jfloat value1 = POPF();
1226         jfloat res    = __ieee754_fmod (value1, value2);
1227         PUSHF (res);
1228       }
1229       NEXT_INSN;
1230
1231     insn_drem:
1232       {
1233         jdouble value2 = POPD();
1234         jdouble value1 = POPD();
1235         jdouble res    = __ieee754_fmod (value1, value2);
1236         PUSHD (res);
1237       }
1238       NEXT_INSN;
1239
1240     insn_ineg:
1241       {
1242         jint value = POPI();
1243         PUSHI (value * -1);
1244       }
1245       NEXT_INSN;
1246
1247     insn_lneg:
1248       {
1249         jlong value = POPL();
1250         PUSHL (value * -1);
1251       }
1252       NEXT_INSN;
1253
1254     insn_fneg:
1255       {
1256         jfloat value = POPF();
1257         PUSHF (value * -1);
1258       }
1259       NEXT_INSN;
1260
1261     insn_dneg:
1262       {
1263         jdouble value = POPD();
1264         PUSHD (value * -1);
1265       }
1266       NEXT_INSN;
1267
1268     insn_ishl:
1269       {
1270         jint shift = (POPI() & 0x1f);
1271         jint value = POPI();
1272         PUSHI (value << shift);
1273       }
1274       NEXT_INSN;
1275
1276     insn_lshl:
1277       {
1278         jint shift = (POPI() & 0x3f);
1279         jlong value = POPL();
1280         PUSHL (value << shift);
1281       }
1282       NEXT_INSN;
1283
1284     insn_ishr:
1285       {
1286         jint shift = (POPI() & 0x1f);
1287         jint value = POPI();
1288         PUSHI (value >> shift);
1289       }
1290       NEXT_INSN;
1291
1292     insn_lshr:
1293       {
1294         jint shift = (POPI() & 0x3f);
1295         jlong value = POPL();
1296         PUSHL (value >> shift);
1297       }
1298       NEXT_INSN;
1299
1300     insn_iushr:
1301       {
1302         jint shift = (POPI() & 0x1f);
1303         _Jv_uint value = (_Jv_uint) POPI();
1304         PUSHI ((jint) (value >> shift));
1305       }
1306       NEXT_INSN;
1307
1308     insn_lushr:
1309       {
1310         jint shift = (POPI() & 0x3f);
1311         _Jv_ulong value = (_Jv_ulong) POPL();
1312         PUSHL ((jlong) (value >> shift));
1313       }
1314       NEXT_INSN;
1315
1316     insn_iand:
1317       BINOPI (&);
1318       NEXT_INSN;
1319
1320     insn_land:
1321       BINOPL (&);
1322       NEXT_INSN;
1323
1324     insn_ior:
1325       BINOPI (|);
1326       NEXT_INSN;
1327
1328     insn_lor:
1329       BINOPL (|);
1330       NEXT_INSN;
1331
1332     insn_ixor:
1333       BINOPI (^);
1334       NEXT_INSN;
1335
1336     insn_lxor:
1337       BINOPL (^);
1338       NEXT_INSN;
1339
1340     insn_iinc:
1341       {
1342         jint index  = GET1U ();
1343         jint amount = GET1S ();
1344         locals[index].i += amount;
1345       }
1346       NEXT_INSN;
1347
1348     insn_i2l:
1349       {jlong value = POPI(); PUSHL (value);}
1350       NEXT_INSN;
1351
1352     insn_i2f:
1353       {jfloat value = POPI(); PUSHF (value);}
1354       NEXT_INSN;
1355
1356     insn_i2d:
1357       {jdouble value = POPI(); PUSHD (value);}
1358       NEXT_INSN;
1359
1360     insn_l2i:
1361       {jint value = POPL(); PUSHI (value);}
1362       NEXT_INSN;
1363
1364     insn_l2f:
1365       {jfloat value = POPL(); PUSHF (value);}
1366       NEXT_INSN;
1367
1368     insn_l2d:
1369       {jdouble value = POPL(); PUSHD (value);}
1370       NEXT_INSN;
1371
1372     insn_f2i:
1373       {
1374         using namespace java::lang;
1375         jint value = convert (POPF (), Integer::MIN_VALUE, Integer::MAX_VALUE);
1376         PUSHI(value);
1377       }
1378       NEXT_INSN;
1379
1380     insn_f2l:
1381       {
1382         using namespace java::lang;
1383         jlong value = convert (POPF (), Long::MIN_VALUE, Long::MAX_VALUE);
1384         PUSHL(value);
1385       }
1386       NEXT_INSN;
1387
1388     insn_f2d:
1389       { jdouble value = POPF (); PUSHD(value); }
1390       NEXT_INSN;
1391
1392     insn_d2i:
1393       {
1394         using namespace java::lang;
1395         jint value = convert (POPD (), Integer::MIN_VALUE, Integer::MAX_VALUE);
1396         PUSHI(value);
1397       }
1398       NEXT_INSN;
1399
1400     insn_d2l:
1401       {
1402         using namespace java::lang;
1403         jlong value = convert (POPD (), Long::MIN_VALUE, Long::MAX_VALUE);
1404         PUSHL(value);
1405       }
1406       NEXT_INSN;
1407
1408     insn_d2f:
1409       { jfloat value = POPD (); PUSHF(value); }
1410       NEXT_INSN;
1411
1412     insn_i2b:
1413       { jbyte value = POPI (); PUSHI(value); }
1414       NEXT_INSN;
1415
1416     insn_i2c:
1417       { jchar value = POPI (); PUSHI(value); }
1418       NEXT_INSN;
1419
1420     insn_i2s:
1421       { jshort value = POPI (); PUSHI(value); }
1422       NEXT_INSN;
1423
1424     insn_lcmp:
1425       {
1426         jlong value2 = POPL ();
1427         jlong value1 = POPL ();
1428         if (value1 > value2)
1429           { PUSHI (1); }
1430         else if (value1 == value2)
1431           { PUSHI (0); }
1432         else
1433           { PUSHI (-1); }
1434       }
1435       NEXT_INSN;
1436
1437     insn_fcmpl:
1438       tmpval = -1;
1439       goto fcmp;
1440
1441     insn_fcmpg:
1442       tmpval = 1;
1443
1444     fcmp:
1445       {
1446         jfloat value2 = POPF ();
1447         jfloat value1 = POPF ();
1448         if (value1 > value2)
1449           PUSHI (1);
1450         else if (value1 == value2)
1451           PUSHI (0);
1452         else if (value1 < value2)
1453           PUSHI (-1);
1454         else
1455           PUSHI (tmpval);
1456       }
1457       NEXT_INSN;
1458
1459     insn_dcmpl:
1460       tmpval = -1;
1461       goto dcmp;
1462
1463     insn_dcmpg:
1464       tmpval = 1;
1465
1466     dcmp:
1467       {
1468         jdouble value2 = POPD ();
1469         jdouble value1 = POPD ();
1470         if (value1 > value2)
1471           PUSHI (1);
1472         else if (value1 == value2)
1473           PUSHI (0);
1474         else if (value1 < value2)
1475           PUSHI (-1);
1476         else
1477           PUSHI (tmpval);
1478       }
1479       NEXT_INSN;
1480
1481     insn_ifeq:
1482       {
1483         if (POPI() == 0)
1484           TAKE_GOTO;
1485         else
1486           SKIP_GOTO;
1487       }
1488       NEXT_INSN;
1489
1490     insn_ifne:
1491       {
1492         if (POPI() != 0)
1493           TAKE_GOTO;
1494         else
1495           SKIP_GOTO;
1496       }
1497       NEXT_INSN;
1498
1499     insn_iflt:
1500       {
1501         if (POPI() < 0)
1502           TAKE_GOTO;
1503         else
1504           SKIP_GOTO;
1505       }
1506       NEXT_INSN;
1507
1508     insn_ifge:
1509       {
1510         if (POPI() >= 0)
1511           TAKE_GOTO;
1512         else
1513           SKIP_GOTO;
1514       }
1515       NEXT_INSN;
1516
1517     insn_ifgt:
1518       {
1519         if (POPI() > 0)
1520           TAKE_GOTO;
1521         else
1522           SKIP_GOTO;
1523       }
1524       NEXT_INSN;
1525
1526     insn_ifle:
1527       {
1528         if (POPI() <= 0)
1529           TAKE_GOTO;
1530         else
1531           SKIP_GOTO;
1532       }
1533       NEXT_INSN;
1534
1535     insn_if_icmpeq:
1536       {
1537         jint value2 = POPI();
1538         jint value1 = POPI();
1539         if (value1 == value2)
1540           TAKE_GOTO;
1541         else
1542           SKIP_GOTO;
1543       }
1544       NEXT_INSN;
1545
1546     insn_if_icmpne:
1547       {
1548         jint value2 = POPI();
1549         jint value1 = POPI();
1550         if (value1 != value2)
1551           TAKE_GOTO;
1552         else
1553           SKIP_GOTO;
1554       }
1555       NEXT_INSN;
1556
1557     insn_if_icmplt:
1558       {
1559         jint value2 = POPI();
1560         jint value1 = POPI();
1561         if (value1 < value2)
1562           TAKE_GOTO;
1563         else
1564           SKIP_GOTO;
1565       }
1566       NEXT_INSN;
1567
1568     insn_if_icmpge:
1569       {
1570         jint value2 = POPI();
1571         jint value1 = POPI();
1572         if (value1 >= value2)
1573           TAKE_GOTO;
1574         else
1575           SKIP_GOTO;
1576       }
1577       NEXT_INSN;
1578
1579     insn_if_icmpgt:
1580       {
1581         jint value2 = POPI();
1582         jint value1 = POPI();
1583         if (value1 > value2)
1584           TAKE_GOTO;
1585         else
1586           SKIP_GOTO;
1587       }
1588       NEXT_INSN;
1589
1590     insn_if_icmple:
1591       {
1592         jint value2 = POPI();
1593         jint value1 = POPI();
1594         if (value1 <= value2)
1595           TAKE_GOTO;
1596         else
1597           SKIP_GOTO;
1598       }
1599       NEXT_INSN;
1600
1601     insn_if_acmpeq:
1602       {
1603         jobject value2 = POPA();
1604         jobject value1 = POPA();
1605         if (value1 == value2)
1606           TAKE_GOTO;
1607         else
1608           SKIP_GOTO;
1609       }
1610       NEXT_INSN;
1611
1612     insn_if_acmpne:
1613       {
1614         jobject value2 = POPA();
1615         jobject value1 = POPA();
1616         if (value1 != value2)
1617           TAKE_GOTO;
1618         else
1619           SKIP_GOTO;
1620       }
1621       NEXT_INSN;
1622
1623     insn_goto_w:
1624 #ifndef DIRECT_THREADED
1625       // For direct threaded, goto and goto_w are the same.
1626       pc = pc - 1 + get4 (pc);
1627       NEXT_INSN;
1628 #endif /* DIRECT_THREADED */
1629     insn_goto:
1630       TAKE_GOTO;
1631       NEXT_INSN;
1632
1633     insn_jsr_w:
1634 #ifndef DIRECT_THREADED
1635       // For direct threaded, jsr and jsr_w are the same.
1636       {
1637         pc_t next = pc - 1 + get4 (pc);
1638         pc += 4;
1639         PUSHA ((jobject) pc);
1640         pc = next;
1641       }
1642       NEXT_INSN;
1643 #endif /* DIRECT_THREADED */
1644     insn_jsr:
1645       {
1646         pc_t next = GOTO_VAL();
1647         SKIP_GOTO;
1648         PUSHA ((jobject) pc);
1649         pc = next;
1650       }
1651       NEXT_INSN;
1652
1653     insn_ret:
1654       {
1655         jint index = GET1U ();
1656         pc = (pc_t) PEEKA (index);
1657       }
1658       NEXT_INSN;
1659
1660     insn_tableswitch:
1661       {
1662 #ifdef DIRECT_THREADED
1663         void *def = (pc++)->datum;
1664
1665         int index = POPI();
1666
1667         jint low = INTVAL ();
1668         jint high = INTVAL ();
1669
1670         if (index < low || index > high)
1671           pc = (insn_slot *) def;
1672         else
1673           pc = (insn_slot *) ((pc + index - low)->datum);
1674 #else
1675         pc_t base_pc = pc - 1;
1676         int index = POPI ();
1677
1678         pc_t base = (pc_t) meth->bytecode ();
1679         while ((pc - base) % 4 != 0)
1680           ++pc;
1681
1682         jint def = get4 (pc);
1683         jint low = get4 (pc + 4);
1684         jint high = get4 (pc + 8);
1685         if (index < low || index > high)
1686           pc = base_pc + def;
1687         else
1688           pc = base_pc + get4 (pc + 4 * (index - low + 3));
1689 #endif /* DIRECT_THREADED */
1690       }
1691       NEXT_INSN;
1692
1693     insn_lookupswitch:
1694       {
1695 #ifdef DIRECT_THREADED
1696         void *def = (pc++)->insn;
1697
1698         int index = POPI();
1699
1700         jint npairs = INTVAL ();
1701
1702         int max = npairs - 1;
1703         int min = 0;
1704
1705         // Simple binary search...
1706         while (min < max)
1707           {
1708             int half = (min + max) / 2;
1709             int match = pc[2 * half].int_val;
1710
1711             if (index == match)
1712               {
1713                 // Found it.
1714                 pc = (insn_slot *) pc[2 * half + 1].datum;
1715                 NEXT_INSN;
1716               }
1717             else if (index < match)
1718               // We can use HALF - 1 here because we check again on
1719               // loop exit.
1720               max = half - 1;
1721             else
1722               // We can use HALF + 1 here because we check again on
1723               // loop exit.
1724               min = half + 1;
1725           }
1726         if (index == pc[2 * min].int_val)
1727           pc = (insn_slot *) pc[2 * min + 1].datum;
1728         else
1729           pc = (insn_slot *) def;
1730 #else
1731         unsigned char *base_pc = pc-1;
1732         int index = POPI();
1733
1734         unsigned char* base = meth->bytecode ();
1735         while ((pc-base) % 4 != 0)
1736           ++pc;
1737
1738         jint def     = get4 (pc);
1739         jint npairs  = get4 (pc+4);
1740
1741         int max = npairs-1;
1742         int min = 0;
1743
1744         // Simple binary search...
1745         while (min < max)
1746           {
1747             int half = (min+max)/2;
1748             int match = get4 (pc+ 4*(2 + 2*half));
1749
1750             if (index == match)
1751               min = max = half;
1752             else if (index < match)
1753               // We can use HALF - 1 here because we check again on
1754               // loop exit.
1755               max = half - 1;
1756             else
1757               // We can use HALF + 1 here because we check again on
1758               // loop exit.
1759               min = half + 1;
1760           }
1761
1762         if (index == get4 (pc+ 4*(2 + 2*min)))
1763           pc = base_pc + get4 (pc+ 4*(2 + 2*min + 1));
1764         else
1765           pc = base_pc + def;    
1766 #endif /* DIRECT_THREADED */
1767       }
1768       NEXT_INSN;
1769
1770     insn_areturn:
1771       *(jobject *) retp = POPA ();
1772       return;
1773
1774     insn_lreturn:
1775       *(jlong *) retp = POPL ();
1776       return;
1777
1778     insn_freturn:
1779       *(jfloat *) retp = POPF ();
1780       return;
1781
1782     insn_dreturn:
1783       *(jdouble *) retp = POPD ();
1784       return;
1785
1786     insn_ireturn:
1787       *(jint *) retp = POPI ();
1788       return;
1789
1790     insn_return:
1791       return;
1792
1793     insn_getstatic:
1794       {
1795         jint fieldref_index = GET2U ();
1796         SAVE_PC(); // Constant pool resolution could throw.
1797         _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
1798         _Jv_Field *field = pool_data[fieldref_index].field;
1799
1800         if ((field->flags & Modifier::STATIC) == 0)
1801           throw_incompatible_class_change_error 
1802             (JvNewStringLatin1 ("field no longer static"));
1803
1804         jclass type = field->type;
1805
1806         // We rewrite the instruction once we discover what it refers
1807         // to.
1808         void *newinsn = NULL;
1809         if (type->isPrimitive ())
1810           {
1811             switch (type->size_in_bytes)
1812               {
1813               case 1:
1814                 PUSHI (*field->u.byte_addr);
1815                 newinsn = AMPAMP (getstatic_resolved_1);
1816                 break;
1817
1818               case 2:
1819                 if (type == JvPrimClass (char))
1820                   {
1821                     PUSHI (*field->u.char_addr);
1822                     newinsn = AMPAMP (getstatic_resolved_char);
1823                   }
1824                 else
1825                   {
1826                     PUSHI (*field->u.short_addr);
1827                     newinsn = AMPAMP (getstatic_resolved_short);
1828                   }
1829                 break;
1830
1831               case 4:
1832                 PUSHI(*field->u.int_addr);
1833                 newinsn = AMPAMP (getstatic_resolved_4);
1834                 break;
1835
1836               case 8:
1837                 PUSHL(*field->u.long_addr);
1838                 newinsn = AMPAMP (getstatic_resolved_8);
1839                 break;
1840               }
1841           }
1842         else
1843           {
1844             PUSHA(*field->u.object_addr);
1845             newinsn = AMPAMP (getstatic_resolved_obj);
1846           }
1847
1848 #ifdef DIRECT_THREADED
1849         pc[-2].insn = newinsn;
1850         pc[-1].datum = field->u.addr;
1851 #endif /* DIRECT_THREADED */
1852       }
1853       NEXT_INSN;
1854
1855 #ifdef DIRECT_THREADED
1856     getstatic_resolved_1:
1857       PUSHI (*(jbyte *) AVAL ());
1858       NEXT_INSN;
1859
1860     getstatic_resolved_char:
1861       PUSHI (*(jchar *) AVAL ());
1862       NEXT_INSN;
1863
1864     getstatic_resolved_short:
1865       PUSHI (*(jshort *) AVAL ());
1866       NEXT_INSN;
1867
1868     getstatic_resolved_4:
1869       PUSHI (*(jint *) AVAL ());
1870       NEXT_INSN;
1871
1872     getstatic_resolved_8:
1873       PUSHL (*(jlong *) AVAL ());
1874       NEXT_INSN;
1875
1876     getstatic_resolved_obj:
1877       PUSHA (*(jobject *) AVAL ());
1878       NEXT_INSN;
1879 #endif /* DIRECT_THREADED */
1880
1881     insn_getfield:
1882       {
1883         SAVE_PC();
1884         jint fieldref_index = GET2U ();
1885         _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
1886         _Jv_Field *field = pool_data[fieldref_index].field;
1887
1888         if ((field->flags & Modifier::STATIC) != 0)
1889           throw_incompatible_class_change_error 
1890             (JvNewStringLatin1 ("field is static"));
1891
1892         jclass type = field->type;
1893         jint field_offset = field->u.boffset;
1894
1895         jobject obj   = POPA();
1896         NULLCHECK(obj);
1897
1898         void *newinsn = NULL;
1899         _Jv_value *val = (_Jv_value *) ((char *)obj + field_offset);
1900         if (type->isPrimitive ())
1901           {
1902             switch (type->size_in_bytes)
1903               {
1904               case 1:
1905                 PUSHI (val->byte_value);
1906                 newinsn = AMPAMP (getfield_resolved_1);
1907                 break;
1908
1909               case 2:
1910                 if (type == JvPrimClass (char))
1911                   {
1912                     PUSHI (val->char_value);
1913                     newinsn = AMPAMP (getfield_resolved_char);
1914                   }
1915                 else
1916                   {
1917                     PUSHI (val->short_value);
1918                     newinsn = AMPAMP (getfield_resolved_short);
1919                   }
1920                 break;
1921
1922               case 4:
1923                 PUSHI (val->int_value);
1924                 newinsn = AMPAMP (getfield_resolved_4);
1925                 break;
1926
1927               case 8:
1928                 PUSHL (val->long_value);
1929                 newinsn = AMPAMP (getfield_resolved_8);
1930                 break;
1931               }
1932           }
1933         else
1934           {
1935             PUSHA (val->object_value);
1936             newinsn = AMPAMP (getfield_resolved_obj);
1937           }
1938
1939 #ifdef DIRECT_THREADED
1940         pc[-2].insn = newinsn;
1941         pc[-1].int_val = field_offset;
1942 #endif /* DIRECT_THREADED */
1943       }
1944       NEXT_INSN;
1945
1946 #ifdef DIRECT_THREADED
1947     getfield_resolved_1:
1948       {
1949         char *obj = (char *) POPA ();
1950         NULLCHECK (obj);
1951         PUSHI (*(jbyte *) (obj + INTVAL ()));
1952       }
1953       NEXT_INSN;
1954
1955     getfield_resolved_char:
1956       {
1957         char *obj = (char *) POPA ();
1958         NULLCHECK (obj);
1959         PUSHI (*(jchar *) (obj + INTVAL ()));
1960       }
1961       NEXT_INSN;
1962
1963     getfield_resolved_short:
1964       {
1965         char *obj = (char *) POPA ();
1966         NULLCHECK (obj);
1967         PUSHI (*(jshort *) (obj + INTVAL ()));
1968       }
1969       NEXT_INSN;
1970
1971     getfield_resolved_4:
1972       {
1973         char *obj = (char *) POPA ();
1974         NULLCHECK (obj);
1975         PUSHI (*(jint *) (obj + INTVAL ()));
1976       }
1977       NEXT_INSN;
1978
1979     getfield_resolved_8:
1980       {
1981         char *obj = (char *) POPA ();
1982         NULLCHECK (obj);
1983         PUSHL (*(jlong *) (obj + INTVAL ()));
1984       }
1985       NEXT_INSN;
1986
1987     getfield_resolved_obj:
1988       {
1989         char *obj = (char *) POPA ();
1990         NULLCHECK (obj);
1991         PUSHA (*(jobject *) (obj + INTVAL ()));
1992       }
1993       NEXT_INSN;
1994 #endif /* DIRECT_THREADED */
1995
1996     insn_putstatic:
1997       {
1998         SAVE_PC();
1999         jint fieldref_index = GET2U ();
2000         _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
2001         _Jv_Field *field = pool_data[fieldref_index].field;
2002
2003         jclass type = field->type;
2004
2005         // ResolvePoolEntry cannot check this
2006         if ((field->flags & Modifier::STATIC) == 0)
2007           throw_incompatible_class_change_error 
2008             (JvNewStringLatin1 ("field no longer static"));
2009
2010         void *newinsn = NULL;
2011         if (type->isPrimitive ())
2012           {
2013             switch (type->size_in_bytes) 
2014               {
2015               case 1:
2016                 {
2017                   jint value = POPI();
2018                   *field->u.byte_addr = value;
2019                   newinsn = AMPAMP (putstatic_resolved_1);
2020                   break;
2021                 }
2022
2023               case 2:
2024                 {
2025                   jint value = POPI();
2026                   *field->u.char_addr = value;
2027                   newinsn = AMPAMP (putstatic_resolved_2);
2028                   break;
2029                 }
2030
2031               case 4:
2032                 {
2033                   jint value = POPI();
2034                   *field->u.int_addr = value;
2035                   newinsn = AMPAMP (putstatic_resolved_4);
2036                   break;
2037                 }
2038
2039               case 8:
2040                 {
2041                   jlong value = POPL();
2042                   *field->u.long_addr = value;
2043                   newinsn = AMPAMP (putstatic_resolved_8);
2044                   break;
2045                 }
2046               }
2047           }
2048         else
2049           {
2050             jobject value = POPA();
2051             *field->u.object_addr = value;
2052             newinsn = AMPAMP (putstatic_resolved_obj);
2053           }
2054
2055 #ifdef DIRECT_THREADED
2056         pc[-2].insn = newinsn;
2057         pc[-1].datum = field->u.addr;
2058 #endif /* DIRECT_THREADED */
2059       }
2060       NEXT_INSN;
2061
2062 #ifdef DIRECT_THREADED
2063     putstatic_resolved_1:
2064       *(jbyte *) AVAL () = POPI ();
2065       NEXT_INSN;
2066
2067     putstatic_resolved_2:
2068       *(jchar *) AVAL () = POPI ();
2069       NEXT_INSN;
2070
2071     putstatic_resolved_4:
2072       *(jint *) AVAL () = POPI ();
2073       NEXT_INSN;
2074
2075     putstatic_resolved_8:
2076       *(jlong *) AVAL () = POPL ();
2077       NEXT_INSN;
2078
2079     putstatic_resolved_obj:
2080       *(jobject *) AVAL () = POPA ();
2081       NEXT_INSN;
2082 #endif /* DIRECT_THREADED */
2083
2084     insn_putfield:
2085       {
2086         SAVE_PC();
2087         jint fieldref_index = GET2U ();
2088         _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
2089         _Jv_Field *field = pool_data[fieldref_index].field;
2090
2091         jclass type = field->type;
2092
2093         if ((field->flags & Modifier::STATIC) != 0)
2094           throw_incompatible_class_change_error 
2095             (JvNewStringLatin1 ("field is static"));
2096
2097         jint field_offset = field->u.boffset;
2098
2099         void *newinsn = NULL;
2100         if (type->isPrimitive ())
2101           {
2102             switch (type->size_in_bytes) 
2103               {
2104               case 1:
2105                 {
2106                   jint    value = POPI();
2107                   jobject obj   = POPA();
2108                   NULLCHECK(obj);
2109                   *(jbyte*) ((char*)obj + field_offset) = value;
2110                   newinsn = AMPAMP (putfield_resolved_1);
2111                   break;
2112                 }
2113
2114               case 2:
2115                 {
2116                   jint    value = POPI();
2117                   jobject obj   = POPA();
2118                   NULLCHECK(obj);
2119                   *(jchar*) ((char*)obj + field_offset) = value;
2120                   newinsn = AMPAMP (putfield_resolved_2);
2121                   break;
2122                 }
2123
2124               case 4:
2125                 {
2126                   jint    value = POPI();
2127                   jobject obj   = POPA();
2128                   NULLCHECK(obj);
2129                   *(jint*) ((char*)obj + field_offset) = value;
2130                   newinsn = AMPAMP (putfield_resolved_4);
2131                   break;
2132                 }
2133
2134               case 8:
2135                 {
2136                   jlong   value = POPL();
2137                   jobject obj   = POPA();
2138                   NULLCHECK(obj);
2139                   *(jlong*) ((char*)obj + field_offset) = value;
2140                   newinsn = AMPAMP (putfield_resolved_8);
2141                   break;
2142                 }
2143               }
2144           }
2145         else
2146           {
2147             jobject value = POPA();
2148             jobject obj   = POPA();
2149             NULLCHECK(obj);
2150             *(jobject*) ((char*)obj + field_offset) = value;
2151             newinsn = AMPAMP (putfield_resolved_obj);
2152           }
2153
2154 #ifdef DIRECT_THREADED
2155         pc[-2].insn = newinsn;
2156         pc[-1].int_val = field_offset;
2157 #endif /* DIRECT_THREADED */
2158       }
2159       NEXT_INSN;
2160
2161 #ifdef DIRECT_THREADED
2162     putfield_resolved_1:
2163       {
2164         jint val = POPI ();
2165         char *obj = (char *) POPA ();
2166         NULLCHECK (obj);
2167         *(jbyte *) (obj + INTVAL ()) = val;
2168       }
2169       NEXT_INSN;
2170
2171     putfield_resolved_2:
2172       {
2173         jint val = POPI ();
2174         char *obj = (char *) POPA ();
2175         NULLCHECK (obj);
2176         *(jchar *) (obj + INTVAL ()) = val;
2177       }
2178       NEXT_INSN;
2179
2180     putfield_resolved_4:
2181       {
2182         jint val = POPI ();
2183         char *obj = (char *) POPA ();
2184         NULLCHECK (obj);
2185         *(jint *) (obj + INTVAL ()) = val;
2186       }
2187       NEXT_INSN;
2188
2189     putfield_resolved_8:
2190       {
2191         jlong val = POPL ();
2192         char *obj = (char *) POPA ();
2193         NULLCHECK (obj);
2194         *(jlong *) (obj + INTVAL ()) = val;
2195       }
2196       NEXT_INSN;
2197
2198     putfield_resolved_obj:
2199       {
2200         jobject val = POPA ();
2201         char *obj = (char *) POPA ();
2202         NULLCHECK (obj);
2203         *(jobject *) (obj + INTVAL ()) = val;
2204       }
2205       NEXT_INSN;
2206 #endif /* DIRECT_THREADED */
2207
2208     insn_invokespecial:
2209       {
2210         SAVE_PC();
2211         int index = GET2U ();
2212
2213         rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2214                                                    index)).rmethod;
2215
2216         sp -= rmeth->stack_item_count;
2217
2218         // We don't use NULLCHECK here because we can't rely on that
2219         // working for <init>.  So instead we do an explicit test.
2220         if (! sp[0].o)
2221           {
2222             SAVE_PC();
2223             throw_null_pointer_exception ();
2224           }
2225
2226         fun = (void (*)()) rmeth->method->ncode;
2227
2228 #ifdef DIRECT_THREADED
2229         // Rewrite instruction so that we use a faster pre-resolved
2230         // method.
2231         pc[-2].insn = &&invokespecial_resolved;
2232         pc[-1].datum = rmeth;
2233 #endif /* DIRECT_THREADED */
2234       }
2235       goto perform_invoke;
2236
2237 #ifdef DIRECT_THREADED
2238     invokespecial_resolved:
2239       {
2240         SAVE_PC();
2241         rmeth = (_Jv_ResolvedMethod *) AVAL ();
2242         sp -= rmeth->stack_item_count;
2243         // We don't use NULLCHECK here because we can't rely on that
2244         // working for <init>.  So instead we do an explicit test.
2245         if (! sp[0].o)
2246           {
2247             throw_null_pointer_exception ();
2248           }
2249         fun = (void (*)()) rmeth->method->ncode;
2250       }
2251       goto perform_invoke;
2252 #endif /* DIRECT_THREADED */
2253
2254     insn_invokestatic:
2255       {
2256         SAVE_PC();
2257         int index = GET2U ();
2258
2259         rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2260                                                    index)).rmethod;
2261
2262         sp -= rmeth->stack_item_count;
2263
2264         fun = (void (*)()) rmeth->method->ncode;
2265
2266 #ifdef DIRECT_THREADED
2267         // Rewrite instruction so that we use a faster pre-resolved
2268         // method.
2269         pc[-2].insn = &&invokestatic_resolved;
2270         pc[-1].datum = rmeth;
2271 #endif /* DIRECT_THREADED */
2272       }
2273       goto perform_invoke;
2274
2275 #ifdef DIRECT_THREADED
2276     invokestatic_resolved:
2277       {
2278         SAVE_PC();
2279         rmeth = (_Jv_ResolvedMethod *) AVAL ();
2280         sp -= rmeth->stack_item_count;
2281         fun = (void (*)()) rmeth->method->ncode;
2282       }
2283       goto perform_invoke;
2284 #endif /* DIRECT_THREADED */
2285
2286     insn_invokeinterface:
2287       {
2288         SAVE_PC();
2289         int index = GET2U ();
2290
2291         rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2292                                                    index)).rmethod;
2293
2294         sp -= rmeth->stack_item_count;
2295
2296         jobject rcv = sp[0].o;
2297
2298         NULLCHECK (rcv);
2299
2300         fun = (void (*)())
2301           _Jv_LookupInterfaceMethod (rcv->getClass (),
2302                                      rmeth->method->name,
2303                                      rmeth->method->signature);
2304
2305 #ifdef DIRECT_THREADED
2306         // Rewrite instruction so that we use a faster pre-resolved
2307         // method.
2308         pc[-2].insn = &&invokeinterface_resolved;
2309         pc[-1].datum = rmeth;
2310 #else
2311         // Skip dummy bytes.
2312         pc += 2;
2313 #endif /* DIRECT_THREADED */
2314       }
2315       goto perform_invoke;
2316
2317 #ifdef DIRECT_THREADED
2318     invokeinterface_resolved:
2319       {
2320         SAVE_PC();
2321         rmeth = (_Jv_ResolvedMethod *) AVAL ();
2322         sp -= rmeth->stack_item_count;
2323         jobject rcv = sp[0].o;
2324         NULLCHECK (rcv);
2325         fun = (void (*)())
2326           _Jv_LookupInterfaceMethod (rcv->getClass (),
2327                                      rmeth->method->name,
2328                                      rmeth->method->signature);
2329       }
2330       goto perform_invoke;
2331 #endif /* DIRECT_THREADED */
2332
2333     insn_new:
2334       {
2335         SAVE_PC();
2336         int index = GET2U ();
2337         jclass klass = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2338                                                           index)).clazz;
2339         /* VM spec, section 3.11.5 */
2340         if ((klass->getModifiers() & Modifier::ABSTRACT)
2341             || klass->isInterface())
2342           throw new java::lang::InstantiationException;
2343         jobject res = _Jv_AllocObject (klass);
2344         PUSHA (res);
2345
2346 #ifdef DIRECT_THREADED
2347         pc[-2].insn = &&new_resolved;
2348         pc[-1].datum = klass;
2349 #endif /* DIRECT_THREADED */
2350       }
2351       NEXT_INSN;
2352
2353 #ifdef DIRECT_THREADED
2354     new_resolved:
2355       {
2356         jclass klass = (jclass) AVAL ();
2357         jobject res = _Jv_AllocObject (klass);
2358         PUSHA (res);
2359       }
2360       NEXT_INSN;
2361 #endif /* DIRECT_THREADED */
2362
2363     insn_newarray:
2364       {
2365         int atype = GET1U ();
2366         int size  = POPI();
2367         jobject result = _Jv_NewArray (atype, size);
2368         PUSHA (result);
2369       }
2370       NEXT_INSN;
2371
2372     insn_anewarray:
2373       {
2374         SAVE_PC();
2375         int index = GET2U ();
2376         jclass klass = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2377                                                           index)).clazz;
2378         int size  = POPI();
2379         jobject result = _Jv_NewObjectArray (size, klass, 0);
2380         PUSHA (result);
2381
2382 #ifdef DIRECT_THREADED
2383         pc[-2].insn = &&anewarray_resolved;
2384         pc[-1].datum = klass;
2385 #endif /* DIRECT_THREADED */
2386       }
2387       NEXT_INSN;
2388
2389 #ifdef DIRECT_THREADED
2390     anewarray_resolved:
2391       {
2392         jclass klass = (jclass) AVAL ();
2393         int size = POPI ();
2394         jobject result = _Jv_NewObjectArray (size, klass, 0);
2395         PUSHA (result);
2396       }
2397       NEXT_INSN;
2398 #endif /* DIRECT_THREADED */
2399
2400     insn_arraylength:
2401       {
2402         __JArray *arr = (__JArray*)POPA();
2403         NULLARRAYCHECK (arr);
2404         PUSHI (arr->length);
2405       }
2406       NEXT_INSN;
2407
2408     insn_athrow:
2409       {
2410         jobject value = POPA();
2411         throw static_cast<jthrowable>(value);
2412       }
2413       NEXT_INSN;
2414
2415     insn_checkcast:
2416       {
2417         SAVE_PC();
2418         jobject value = POPA();
2419         jint index = GET2U ();
2420         jclass to = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2421                                                        index)).clazz;
2422
2423         value = (jobject) _Jv_CheckCast (to, value);
2424
2425         PUSHA (value);
2426
2427 #ifdef DIRECT_THREADED
2428         pc[-2].insn = &&checkcast_resolved;
2429         pc[-1].datum = to;
2430 #endif /* DIRECT_THREADED */
2431       }
2432       NEXT_INSN;
2433
2434 #ifdef DIRECT_THREADED
2435     checkcast_resolved:
2436       {
2437         SAVE_PC();
2438         jobject value = POPA ();
2439         jclass to = (jclass) AVAL ();
2440         value = (jobject) _Jv_CheckCast (to, value);
2441         PUSHA (value);
2442       }
2443       NEXT_INSN;
2444 #endif /* DIRECT_THREADED */
2445
2446     insn_instanceof:
2447       {
2448         SAVE_PC();
2449         jobject value = POPA();
2450         jint index = GET2U ();
2451         jclass to = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2452                                                        index)).clazz;
2453         PUSHI (to->isInstance (value));
2454
2455 #ifdef DIRECT_THREADED
2456         pc[-2].insn = &&instanceof_resolved;
2457         pc[-1].datum = to;
2458 #endif /* DIRECT_THREADED */
2459       }
2460       NEXT_INSN;
2461
2462 #ifdef DIRECT_THREADED
2463     instanceof_resolved:
2464       {
2465         jobject value = POPA ();
2466         jclass to = (jclass) AVAL ();
2467         PUSHI (to->isInstance (value));
2468       }
2469       NEXT_INSN;
2470 #endif /* DIRECT_THREADED */
2471
2472     insn_monitorenter:
2473       {
2474         jobject value = POPA();
2475         NULLCHECK(value);
2476         _Jv_MonitorEnter (value);
2477       }
2478       NEXT_INSN;
2479
2480     insn_monitorexit:
2481       {
2482         jobject value = POPA();
2483         NULLCHECK(value);
2484         _Jv_MonitorExit (value);
2485       }
2486       NEXT_INSN;
2487
2488     insn_ifnull:
2489       {
2490         jobject val = POPA();
2491         if (val == NULL)
2492           TAKE_GOTO;
2493         else
2494           SKIP_GOTO;
2495       }
2496       NEXT_INSN;
2497
2498     insn_ifnonnull:
2499       {
2500         jobject val = POPA();
2501         if (val != NULL)
2502           TAKE_GOTO;
2503         else
2504           SKIP_GOTO;
2505       }
2506       NEXT_INSN;
2507
2508     insn_multianewarray:
2509       {
2510         SAVE_PC();
2511         int kind_index = GET2U ();
2512         int dim        = GET1U ();
2513
2514         jclass type    
2515           = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2516                                                kind_index)).clazz;
2517         jint *sizes    = (jint*) __builtin_alloca (sizeof (jint)*dim);
2518
2519         for (int i = dim - 1; i >= 0; i--)
2520           {
2521             sizes[i] = POPI ();
2522           }
2523
2524         jobject res    = _Jv_NewMultiArray (type,dim, sizes);
2525
2526         PUSHA (res);
2527       }
2528       NEXT_INSN;
2529
2530 #ifndef DIRECT_THREADED
2531     insn_wide:
2532       {
2533         jint the_mod_op = get1u (pc++);
2534         jint wide       = get2u (pc); pc += 2;
2535
2536         switch (the_mod_op)
2537           {
2538           case op_istore:
2539             STOREI (wide);
2540             NEXT_INSN;
2541
2542           case op_fstore:
2543             STOREF (wide);
2544             NEXT_INSN;
2545
2546           case op_astore:
2547             STOREA (wide);
2548             NEXT_INSN;
2549
2550           case op_lload:
2551             LOADL (wide);
2552             NEXT_INSN;
2553
2554           case op_dload:
2555             LOADD (wide);
2556             NEXT_INSN;
2557
2558           case op_iload:
2559             LOADI (wide);
2560             NEXT_INSN;
2561
2562           case op_fload:
2563             LOADF (wide);
2564             NEXT_INSN;
2565
2566           case op_aload:
2567             LOADA (wide);
2568             NEXT_INSN;
2569
2570           case op_lstore:
2571             STOREL (wide);
2572             NEXT_INSN;
2573
2574           case op_dstore:
2575             STORED (wide);
2576             NEXT_INSN;
2577
2578           case op_ret:
2579             pc = (unsigned char*) PEEKA (wide);
2580             NEXT_INSN;
2581
2582           case op_iinc:
2583             {
2584               jint amount = get2s (pc); pc += 2;
2585               jint value = PEEKI (wide);
2586               POKEI (wide, value+amount);
2587             }
2588             NEXT_INSN;
2589
2590           default:
2591             throw_internal_error ("illegal bytecode modified by wide");
2592           }
2593
2594       }
2595 #endif /* DIRECT_THREADED */
2596
2597     insn_breakpoint:
2598       {
2599         JvAssert (JVMTI_REQUESTED_EVENT (Breakpoint));
2600
2601         // Send JVMTI notification
2602         using namespace ::java::lang;
2603         jmethodID method = meth->self;
2604         jlocation location = meth->insn_index (pc - 1);
2605         Thread *thread = Thread::currentThread ();
2606         JNIEnv *jni_env = _Jv_GetCurrentJNIEnv ();
2607
2608         // Save the insn here since the breakpoint could be removed
2609         // before the JVMTI notification returns.
2610         using namespace gnu::gcj::jvmti;
2611         Breakpoint *bp
2612           = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
2613                                               location);
2614         JvAssert (bp != NULL);
2615         pc_t opc = reinterpret_cast<pc_t> (bp->getInsn ());
2616
2617         _Jv_JVMTI_PostEvent (JVMTI_EVENT_BREAKPOINT, thread, jni_env,
2618                              method, location);
2619
2620         // Continue execution
2621 #ifdef DIRECT_THREADED
2622         goto *(opc->insn);
2623 #else
2624         goto *(insn_target[*opc]);
2625 #endif
2626       }
2627     }
2628   catch (java::lang::Throwable *ex)
2629     {
2630 #ifdef DEBUG
2631        // This needs to be done before the pc is changed.
2632        jlong throw_loc = meth->insn_index (pc);
2633 #endif
2634       // Check if the exception is handled and, if so, set the pc to the start
2635       // of the appropriate catch block.
2636       if (meth->check_handler (&pc, meth, ex))
2637         {
2638           sp = stack;
2639           sp++->o = ex; // Push exception.
2640 #ifdef DEBUG
2641           if (JVMTI_REQUESTED_EVENT (Exception))
2642             {
2643               using namespace gnu::gcj::jvmti;
2644               jlong throw_meth = reinterpret_cast<jlong> (meth->get_method ());
2645               jlong catch_loc = meth->insn_index (pc);
2646               ExceptionEvent::postExceptionEvent (thread, throw_meth,
2647                                                   throw_loc, ex, throw_meth,
2648                                                   catch_loc);
2649             }
2650 #endif
2651           NEXT_INSN;
2652         }
2653 #ifdef DEBUG
2654       if (JVMTI_REQUESTED_EVENT (Exception))
2655         {
2656           using namespace gnu::gcj::jvmti;
2657           jlong throw_meth = reinterpret_cast<jlong> (meth->get_method ());
2658           ExceptionEvent::postExceptionEvent (thread, throw_meth, throw_loc,
2659                                               ex, NULL, NULL);
2660         }
2661 #endif
2662       // No handler, so re-throw.
2663       throw ex;
2664     }