newcomp moved to jit
authorcacao <none@none>
Mon, 9 Nov 1998 20:35:11 +0000 (20:35 +0000)
committercacao <none@none>
Mon, 9 Nov 1998 20:35:11 +0000 (20:35 +0000)
29 files changed:
Makefile
alpha/asmpart.c
alpha/defines.h
alpha/disass.c
alpha/gen.c
alpha/native-math.h
alpha/ngen.c
alpha/types.h
compiler.c
compiler.h
global.h
headers.c
jit.c [new file with mode: 0644]
jit.h [new file with mode: 0644]
jit/jitdef.h [new file with mode: 0644]
jit/mcode.c [new file with mode: 0644]
jit/parse.c [new file with mode: 0644]
jit/reg.c [new file with mode: 0644]
jit/stack.c [new file with mode: 0644]
loader.c
main.c
mm/heap.old.c
newcomp.c [deleted file]
src/cacao/cacao.c
src/cacaoh/headers.c
src/vm/global.h
src/vm/jit/parse.c [new file with mode: 0644]
src/vm/jit/stack.c [new file with mode: 0644]
src/vm/loader.c

index b3b46150d57dc845e2f838731bb50d098ad1d896..b6fcb3e8176ba15c6ab1bde6c57fdbb3296cec9b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -58,7 +58,7 @@ LFLAGS = -lm
 #CFLAGS = -O2 -OPT:Olimit=0 $(THREAD_CFLAGS) -DMAP_ANONYMOUS=0
 #LFLAGS = -lm -lelfutil
 
-OBJ = main.o tables.o loader.o compiler.o newcomp.o builtin.o asmpart.o \
+OBJ = main.o tables.o loader.o compiler.o jit.o builtin.o asmpart.o \
        toolbox/toolbox.a native.o $(THREAD_OBJ) mm/mm.o
 OBJH = headers.o tables.o loader.o builtin.o toolbox/toolbox.a $(THREAD_OBJ) \
 mm/mm.o
@@ -68,7 +68,7 @@ cacao: $(OBJ)
 cacaoh: $(OBJH)
        $(CC) $(CFLAGS) -o cacaoh $(OBJH) $(LFLAGS)
 
-main.o: main.c global.h tables.h compiler.h ncomp/ncomp.h loader.h \
+main.o: main.c global.h tables.h loader.h jit.h compiler.h \
         asmpart.h builtin.h native.h
 
 headers.o:  headers.c global.h tables.h loader.h
@@ -78,8 +78,8 @@ loader.o:   loader.c global.h loader.h tables.h native.h asmpart.h
 compiler.o: builtin.h compiler.h global.h loader.h tables.h native.h \
             asmpart.h compiler.c comp/*.c sysdep/gen.c sysdep/disass.c
 
-newcomp.o:  builtin.h ncomp/ncomp.h global.h loader.h tables.h native.h \
-            asmpart.h ncomp/ncompdef.h ncomp/*.c sysdep/ngen.h sysdep/ngen.c sysdep/disass.c
+jit.o:  builtin.h jit.h global.h loader.h tables.h native.h asmpart.h \
+            jit/jitdef.h jit/*.c sysdep/ngen.h sysdep/ngen.c sysdep/disass.c
 
 builtin.o: builtin.c global.h loader.h builtin.h tables.h sysdep/native-math.h
 
index 2e79948cc11a6fdaf94d8452c8f6c3608b10a47e..8948813c03c47d96ada1cb5d072d9469d0f640fb 100644 (file)
 
 /*************************** imported functions *******************************/
 
-       .globl compiler_compile
+       .globl jit_compile
        .globl builtin_monitorexit
        .globl builtin_throw_exception
        .globl builtin_trace_exception
@@ -305,7 +305,7 @@ noregchange:
        stq     ra,13*8(sp)           /* save return address                      */
 
        ldq     a0,0(v0)              /* pass 'methodinfo' pointer to             */
-       jsr     ra,compiler_compile   /* compiler                                 */
+       jsr     ra,jit_compile        /* jit compiler                             */
        ldgp    gp,0(ra)
 
        call_pal PAL_imb              /* synchronise instruction cache            */
@@ -1015,6 +1015,7 @@ initialize_thread_stack:
 /******************* function perform_alpha_threadswitch ***********************
 *                                                                              *
 *   void perform_alpha_threadswitch (u1 **from, u1 **to, u1 **stackTop);       *
+*                                                                              *
 *   performs a threadswitch                                                    *
 *                                                                              *
 *******************************************************************************/
@@ -1066,6 +1067,8 @@ perform_alpha_threadswitch:
 
 /********************* function asm_switchstackandcall *************************
 *                                                                              *
+*   void asm_switchstackandcall (void *stack, void *func);                     *
+*                                                                              *
 *   Switches to a new stack, calls a function and switches back.               *
 *       a0      new stack pointer                                              *
 *       a1      function pointer                                               *
index e64e10b18d9a9381661165749e3ad9c7427b60ce..dc60708b56fcd149f019e429aee3bbdbf189a2df 100644 (file)
@@ -1,4 +1,4 @@
-/*************************** alpha/defines.h ***********************************
+/* alpha/defines.h *************************************************************
 
        Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
 
@@ -6,8 +6,7 @@
 
        system-dependent definitions
 
-       Authors: Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
-                Mark Probst         EMAIL: cacao@complang.tuwien.ac.at
+       Authors: Mark Probst         EMAIL: cacao@complang.tuwien.ac.at
 
        Last Change: 1997/09/11
 
index ce48f99555d4e88095f0590882f27c12ce3339da..38ec1bfa84d1888332691ae4c908545e1b1e2765 100644 (file)
@@ -214,7 +214,7 @@ static struct { u2 op, fun; char *name; }  op3s[] = {
 };
 
 
-/* function disassemble ********************************************************
+/* function disassinstr ********************************************************
 
        outputs a disassembler listing of one machine code instruction on 'stdout'
        c:   instructions machine code
@@ -222,7 +222,7 @@ static struct { u2 op, fun; char *name; }  op3s[] = {
 
 *******************************************************************************/
 
-static void disasscmd (int c, int pos)
+static void disassinstr(int c, int pos)
 {
        int op;                     /* 6 bit op code                              */
        int opfun;                  /* 7 bit function code                        */
@@ -328,13 +328,13 @@ static void disasscmd (int c, int pos)
 
 *******************************************************************************/
 
-static void disassemble (int *code, int len)
+static void disassemble(int *code, int len)
 {
        int p;
 
        printf ("  --- disassembler listing ---\n");    
        for (p = 0; p < len; p += 4, code++)
-               disasscmd (*code, p); 
+               disassinstr(*code, p); 
 }
 
 
index 996225d8dc6c35177903973e56abc6edb69888b8..3d752568f5b20e1101bfb95d616d50eb7bca4b37 100644 (file)
@@ -1818,7 +1818,7 @@ void removenativestub (u1 *stub)
 
 #define NATIVESTUBSIZE 11
 
-u1 *createnativestub (functionptr f, methodinfo *m)
+u1 *oldcreatenativestub (functionptr f, methodinfo *m)
 {
        u8 *s = CNEW (u8, NATIVESTUBSIZE);  /* memory to hold the stub      */
        s4 *p = (s4*) s;                    /* code generation pointer      */
index 4e87509b0eeca58607688168e01675e15df873e9..1c0193af3ee4b023c087809038acf18e520d7e4c 100644 (file)
@@ -1,4 +1,4 @@
-/************************* alpha/native-math.h *********************************
+/* alpha/native-math.h *********************************************************
 
        Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
 
index 943edc74b28766da71bf04155f38d5a4356c86af..db61e1996a983b6b78ab3e2b2771d50af489a2ba 100644 (file)
@@ -3589,7 +3589,7 @@ void removecompilerstub (u1 *stub)
 }
 
 
-/* function: ncreatenativestub *************************************************
+/* function: createnativestub **************************************************
 
        creates a stub routine which calls a native method
        
@@ -3597,7 +3597,7 @@ void removecompilerstub (u1 *stub)
 
 #define NATIVESTUBSIZE 11
 
-u1 *ncreatenativestub (functionptr f, methodinfo *m)
+u1 *createnativestub (functionptr f, methodinfo *m)
 {
        u8 *s = CNEW (u8, NATIVESTUBSIZE);  /* memory to hold the stub            */
        s4 *p = (s4*) s;                    /* code generation pointer            */
index 8325c8cf812d251c2a94d382a23a55cf105ac1bc..464e71041fb044aab84e36be9d39936fef45cf5b 100644 (file)
@@ -1,4 +1,4 @@
-/*************************** alpha/types.h *************************************
+/* alpha/types.h ***************************************************************
 
        Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
 
index 18f0949c6fadaece16ecb02259f6642646eb27b9..0f6b55e544b564b0bdf8bba4f4608085fb672aec 100644 (file)
 
 /*************************** globale Schalter ********************************/
 
-extern int newcompiler;                
-methodptr new_compile (methodinfo *m);  /* compile a method with new compiler */
-
-/**************************  no all in newcomp.c
+/**************************  now all in newcomp.c
 
 bool compileverbose = false;
 bool showstack = false;
@@ -181,9 +178,6 @@ methodptr compiler_compile (methodinfo *m)
        long int starttime=0,stoptime=0;
        long int dumpsize;
        
-       if (newcompiler) {
-               return new_compile(m);
-               }
 
        /*** Wenn schon ein Maschinencode vorliegt, dann sofort beenden ****/
 
index 86c8f6d5e71a66fa5a0ddae8b3aeaab817753570..dbd8184da9ec5c4954e29d7aac867149fb4f0979 100644 (file)
@@ -78,10 +78,12 @@ methodptr compiler_compile (methodinfo *m);
 void compiler_init ();
 void compiler_close ();
 
+u1 *oldcreatenativestub (functionptr f, methodinfo *m);
+
+/*
 u1 *createcompilerstub (methodinfo *m);
-u1 *createnativestub (functionptr f, methodinfo *m);
-u1 *ncreatenativestub (functionptr f, methodinfo *m);
 
 void removecompilerstub (u1 *stub);
 void removenativestub (u1 *stub);
+*/
 
index df11a012c4a2ad86fb0d07dd80c6efe41fc6a3de..dc791983d4c9915d6e5923262094b6a2635d78f8 100644 (file)
--- a/global.h
+++ b/global.h
 *******************************************************************************/
 
 #ifndef __global_h_
-#define __global_h_                        /* schani */
+#define __global_h_
 
-#define STATISTICS                         /* andi   */
+#define OLD_COMPILER        /* if enabled makes old compiler available        */
+
+#define STATISTICS          /* if enabled collects program statistics         */
 
 /* JIT_MARKER_SUPPORT is the define used to toggle Just-in-time generated
-   marker functions on and off. */
-#undef JIT_MARKER_SUPPORT                  /* phil   */
+       marker functions on and off.
+*/
+#undef  JIT_MARKER_SUPPORT  /* phil   */
 
 /* standard includes **********************************************************/
 
index d28baccef059f4b3304d5a341bf8a6197ffcf88c..6f95bdca5868fca891cc39aaf42f030eb53e3160 100644 (file)
--- a/headers.c
+++ b/headers.c
@@ -1,5 +1,4 @@
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
-/****************************** headers.c **************************************
+/* headers.c *******************************************************************
 
        Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
 
@@ -62,7 +61,7 @@ void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {
 
 u1 *createcompilerstub (methodinfo *m) {return NULL;}
 u1 *createnativestub (functionptr f, methodinfo *m) {return NULL;}
-u1 *ncreatenativestub (functionptr f, methodinfo *m) {return NULL;}
+u1 *oldcreatenativestub (functionptr f, methodinfo *m) {return NULL;}
 
 void removecompilerstub (u1 *stub) {}
 void removenativestub (u1 *stub) {}
@@ -474,3 +473,15 @@ int main(int argc, char **argv)
 }
 
 
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff --git a/jit.c b/jit.c
new file mode 100644 (file)
index 0000000..2d42e9d
--- /dev/null
+++ b/jit.c
@@ -0,0 +1,463 @@
+/* jit.c ***********************************************************************
+
+       Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+       See file COPYRIGHT for information on usage and disclaimer of warranties.
+
+       Contains the functions which translates a JavaVM method into native code.
+       This is the new version of the compiler which is a lot faster and has new
+       exception handling schemes. The main function is new_comp.
+
+       Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
+                Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
+
+       Last Change: 1997/11/05
+
+*******************************************************************************/
+
+#include "signal.h"
+#include "global.h"
+
+#include "tables.h"
+#include "loader.h"
+#include "jit.h"
+#include "builtin.h"
+#include "native.h"
+#include "asmpart.h"
+
+#include "threads/thread.h"
+
+
+/* global switches ************************************************************/
+
+bool compileverbose = false;
+bool showstack = false;
+bool showdisassemble = false; 
+bool showddatasegment = false; 
+bool showintermediate = false;
+int  optimizelevel = 0;
+
+bool checkbounds = true;
+bool checknull = true;
+bool checkfloats = true;
+bool checksync = true;
+
+bool getcompilingtime = false;
+long compilingtime = 0;
+
+int  has_ext_instr_set = 0;
+
+bool statistics = false;         
+
+int count_jit_calls = 0;
+int count_methods = 0;
+int count_spills = 0;
+int count_pcmd_activ = 0;
+int count_pcmd_drop = 0;
+int count_pcmd_zero = 0;
+int count_pcmd_const_store = 0;
+int count_pcmd_const_alu = 0;
+int count_pcmd_const_bra = 0;
+int count_pcmd_load = 0;
+int count_pcmd_move = 0;
+int count_load_instruction = 0;
+int count_pcmd_store = 0;
+int count_pcmd_store_comb = 0;
+int count_dup_instruction = 0;
+int count_pcmd_op = 0;
+int count_pcmd_mem = 0;
+int count_pcmd_met = 0;
+int count_pcmd_bra = 0;
+int count_pcmd_table = 0;
+int count_pcmd_return = 0;
+int count_pcmd_returnx = 0;
+int count_check_null = 0;
+int count_check_bound = 0;
+int count_max_basic_blocks = 0;
+int count_basic_blocks = 0;
+int count_javainstr = 0;
+int count_max_javainstr = 0;
+int count_javacodesize = 0;
+int count_javaexcsize = 0;
+int count_calls = 0;
+int count_tryblocks = 0;
+int count_code_len = 0;
+int count_data_len = 0;
+int count_cstub_len = 0;
+int count_nstub_len = 0;
+int count_max_new_stack = 0;
+int count_upper_bound_new_stack = 0;
+static int count_block_stack_init[11] = {0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0};
+int *count_block_stack = count_block_stack_init;
+static int count_analyse_iterations_init[5] = {0, 0, 0, 0, 0};
+int *count_analyse_iterations = count_analyse_iterations_init;
+static int count_method_bb_distribution_init[9] = {0, 0, 0, 0, 0,  0, 0, 0, 0};
+int *count_method_bb_distribution = count_method_bb_distribution_init;
+static int count_block_size_distribution_init[18] = {0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,   0, 0, 0, 0, 0,   0, 0, 0};
+int *count_block_size_distribution = count_block_size_distribution_init;
+static int count_store_length_init[21] = {0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+                                          0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0};
+int *count_store_length = count_store_length_init;
+static int count_store_depth_init[11] = {0, 0, 0, 0, 0,  0, 0, 0, 0, 0,   0};
+int *count_store_depth = count_store_depth_init;
+
+
+/* include compiler data types ************************************************/ 
+
+#include "jit/jitdef.h"
+
+
+/* global compiler variables **************************************************/
+
+                                /* data about the currently compiled method   */
+
+static classinfo  *class;       /* class the compiled method belongs to       */
+static methodinfo *method;      /* pointer to method info of compiled method  */
+static unicode    *descriptor;  /* type descriptor of compiled method         */
+static u2         mparamcount;  /* number of parameters (incl. this)          */
+static u1         *mparamtypes; /* types of all parameters (TYPE_INT, ...)    */
+static u2         mreturntype;  /* return type of method                      */
+       
+static int maxstack;            /* maximal JavaVM stack size                  */
+static int maxlocals;           /* maximal number of local JavaVM variables   */
+static int jcodelength;         /* length of JavaVM-codes                     */
+static u1 *jcode;               /* pointer to start of JavaVM-code            */
+static int exceptiontablelength;/* length of exception table                  */
+static exceptiontable *extable; /* pointer to start of exception table        */
+
+static int block_count;         /* number of basic blocks                     */
+static basicblock *block;       /* points to basic block array                */
+static int *block_index;        /* a table which contains for every byte of   */
+                                /* JavaVM code a basic block index if at this */
+                                /* byte there is the start of a basic block   */
+
+static int instr_count;         /* number of JavaVM instructions              */
+static instruction *instr;      /* points to intermediate code instructions   */
+
+static int stack_count;         /* number of stack elements                   */
+static stackelement *stack;     /* points to intermediate code instructions   */
+
+static bool isleafmethod;       /* true if a method doesn't call subroutines  */
+
+/* list of all classes used by the compiled method which have to be           */
+/* initialised (if not already done) before execution of this method          */
+
+static chain *uninitializedclasses;  
+                                
+
+/* include compiler subsystems ************************************************/
+
+#include "sysdep/ngen.h"        /* code generator header file                 */ 
+#include "sysdep/disass.c"      /* disassembler (for debug purposes only)     */ 
+#include "jit/mcode.c"          /* code generation tool functions             */ 
+#include "jit/parse.c"          /* parsing of JavaVM code                     */ 
+#include "jit/reg.c"            /* register allocation and support routines   */ 
+#include "jit/stack.c"          /* analysing the stack operations             */ 
+#include "sysdep/ngen.c"        /* code generator                             */ 
+
+
+
+
+/* dummy function, used when there is no JavaVM code available                */
+
+static void* do_nothing_function() 
+{
+       return NULL;
+}
+
+
+#ifdef OLD_COMPILER
+extern bool newcompiler;
+methodptr compiler_compile (methodinfo *m); /* compile method with old compiler*/
+#endif
+
+
+/* jit_compile *****************************************************************
+
+       jit_compile, new version of compiler, translates one method to machine code
+
+*******************************************************************************/
+
+methodptr jit_compile(methodinfo *m)
+{
+       int  dumpsize;
+       long starttime = 0;
+       long stoptime  = 0;
+
+#ifdef OLD_COMPILER
+       if (!newcompiler) {
+               return compiler_compile(m);
+               }
+#endif
+
+       /* if method has been already compiled return immediately */
+
+       count_jit_calls++;
+
+       if (m->entrypoint)
+               return m->entrypoint;
+
+       count_methods++;
+
+       intsDisable();      /* disable interrupts */
+       
+
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size ();
+
+       /* measure time */
+
+       if (getcompilingtime)
+               starttime = getcputime();
+
+       /* if there is no javacode print error message and return empty method    */
+
+       if (! m->jcode) {
+               sprintf(logtext, "No code given for: ");
+               unicode_sprint(logtext+strlen(logtext), m->class->name);
+               strcpy(logtext+strlen(logtext), ".");
+               unicode_sprint(logtext+strlen(logtext), m->name);
+               unicode_sprint(logtext+strlen(logtext), m->descriptor);
+               dolog();
+               intsRestore();                             /* enable interrupts again */
+               return (methodptr) do_nothing_function;    /* return empty method     */
+               }
+
+       /* print log message for compiled method */
+
+       if (compileverbose) {
+               sprintf(logtext, "Compiling: ");
+               unicode_sprint(logtext+strlen(logtext), m->class->name);
+               strcpy(logtext+strlen(logtext), ".");
+               unicode_sprint(logtext+strlen(logtext), m->name);
+               unicode_sprint(logtext+strlen(logtext), m->descriptor);
+               dolog ();
+               }
+
+
+       /* initialisation of variables and subsystems */
+
+       isleafmethod = true;
+
+       method = m;
+       class = m->class;
+       descriptor = m->descriptor;
+       maxstack = m->maxstack;
+       maxlocals = m->maxlocals;
+       jcodelength = m->jcodelength;
+       jcode = m->jcode;
+       exceptiontablelength = m->exceptiontablelength;
+       extable = m->exceptiontable;
+
+#ifdef STATISTICS
+       count_tryblocks += exceptiontablelength;
+       count_javacodesize += jcodelength + 18;
+       count_javaexcsize += exceptiontablelength * 8;
+#endif
+
+       /* initialise parameter type descriptor */
+
+       descriptor2types (m);
+       mreturntype = m->returntype;
+       mparamcount = m->paramcount;
+       mparamtypes = m->paramtypes;
+
+       /* initialize class list with class the compiled method belongs to */
+
+       uninitializedclasses = chain_new(); 
+       compiler_addinitclass (m->class);
+
+
+       /* call the compiler passes ***********************************************/
+       
+       reg_init();
+       local_init();
+       mcode_init();
+
+       if (runverbose)
+               allocate_literals();
+
+       parse();
+
+       analyse_stack();
+
+       interface_regalloc();
+
+       allocate_scratch_registers();
+       
+       local_regalloc();
+       
+       gen_mcode();
+
+       
+       /* intermediate and assembly code listings ********************************/
+               
+       if (showintermediate)
+               show_icmd_method();
+       else if (showdisassemble)
+               disassemble((void*) (m->mcode + dseglen), m->mcodelength - dseglen);
+
+       if (showddatasegment)
+               dseg_display((void*) (m->mcode));
+
+
+
+       /* release dump area */
+
+       dump_release (dumpsize);
+
+       /* measure time */
+
+       if (getcompilingtime) {
+               stoptime = getcputime();
+               compilingtime += (stoptime-starttime); 
+               }
+
+       /* initialize all used classes */
+       /* because of reentrant code global variables are not allowed here        */
+
+       {
+       chain *ul = uninitializedclasses;   /* list of uninitialized classes      */ 
+       classinfo *c;                       /* single class                       */
+
+       while ((c = chain_first(ul)) != NULL) {
+               chain_remove (ul);
+               class_init (c);                         /* may again call the compiler        */
+               }
+       chain_free (ul);
+       }
+
+       intsRestore();    /* enable interrupts again */
+
+       /* return pointer to the methods entry point */
+       
+       return m -> entrypoint;
+}
+
+
+/* functions for compiler initialisation and finalisation *********************/
+
+void jit_init ()
+{
+       int i;
+
+       has_ext_instr_set = ! has_no_x_instr_set();
+
+       for (i = 0; i < 256; i++)
+               stackreq[i] = 1;
+
+       stackreq[JAVA_NOP]          = 0;
+       stackreq[JAVA_ISTORE]       = 0;
+       stackreq[JAVA_LSTORE]       = 0;
+       stackreq[JAVA_FSTORE]       = 0;
+       stackreq[JAVA_DSTORE]       = 0;
+       stackreq[JAVA_ASTORE]       = 0;
+       stackreq[JAVA_ISTORE_0]     = 0;
+       stackreq[JAVA_ISTORE_1]     = 0;
+       stackreq[JAVA_ISTORE_2]     = 0;
+       stackreq[JAVA_ISTORE_3]     = 0;
+       stackreq[JAVA_LSTORE_0]     = 0;
+       stackreq[JAVA_LSTORE_1]     = 0;
+       stackreq[JAVA_LSTORE_2]     = 0;
+       stackreq[JAVA_LSTORE_3]     = 0;
+       stackreq[JAVA_FSTORE_0]     = 0;
+       stackreq[JAVA_FSTORE_1]     = 0;
+       stackreq[JAVA_FSTORE_2]     = 0;
+       stackreq[JAVA_FSTORE_3]     = 0;
+       stackreq[JAVA_DSTORE_0]     = 0;
+       stackreq[JAVA_DSTORE_1]     = 0;
+       stackreq[JAVA_DSTORE_2]     = 0;
+       stackreq[JAVA_DSTORE_3]     = 0;
+       stackreq[JAVA_ASTORE_0]     = 0;
+       stackreq[JAVA_ASTORE_1]     = 0;
+       stackreq[JAVA_ASTORE_2]     = 0;
+       stackreq[JAVA_ASTORE_3]     = 0;
+       stackreq[JAVA_IASTORE]      = 0;
+       stackreq[JAVA_LASTORE]      = 0;
+       stackreq[JAVA_FASTORE]      = 0;
+       stackreq[JAVA_DASTORE]      = 0;
+       stackreq[JAVA_AASTORE]      = 0;
+       stackreq[JAVA_BASTORE]      = 0;
+       stackreq[JAVA_CASTORE]      = 0;
+       stackreq[JAVA_SASTORE]      = 0;
+       stackreq[JAVA_POP]          = 0;
+       stackreq[JAVA_POP2]         = 0;
+       stackreq[JAVA_IINC]         = 0;
+       stackreq[JAVA_IFEQ]         = 0;
+       stackreq[JAVA_IFNE]         = 0;
+       stackreq[JAVA_IFLT]         = 0;
+       stackreq[JAVA_IFGE]         = 0;
+       stackreq[JAVA_IFGT]         = 0;
+       stackreq[JAVA_IFLE]         = 0;
+       stackreq[JAVA_IF_ICMPEQ]    = 0;
+       stackreq[JAVA_IF_ICMPNE]    = 0;
+       stackreq[JAVA_IF_ICMPLT]    = 0;
+       stackreq[JAVA_IF_ICMPGE]    = 0;
+       stackreq[JAVA_IF_ICMPGT]    = 0;
+       stackreq[JAVA_IF_ICMPLE]    = 0;
+       stackreq[JAVA_IF_ACMPEQ]    = 0;
+       stackreq[JAVA_IF_ACMPNE]    = 0;
+       stackreq[JAVA_GOTO]         = 0;
+       stackreq[JAVA_RET]          = 0;
+       stackreq[JAVA_TABLESWITCH]  = 0;
+       stackreq[ICMD_LOOKUPSWITCH] = 0;
+       stackreq[JAVA_IRETURN]      = 0;
+       stackreq[JAVA_LRETURN]      = 0;
+       stackreq[JAVA_FRETURN]      = 0;
+       stackreq[JAVA_DRETURN]      = 0;
+       stackreq[JAVA_ARETURN]      = 0;
+       stackreq[JAVA_RETURN]       = 0;
+       stackreq[JAVA_PUTSTATIC]    = 0;
+       stackreq[JAVA_PUTFIELD]     = 0;
+       stackreq[JAVA_MONITORENTER] = 0;
+       stackreq[ICMD_MONITOREXIT]  = 0;
+       stackreq[JAVA_WIDE]         = 0;
+       stackreq[JAVA_IFNULL]       = 0;
+       stackreq[JAVA_IFNONNULL]    = 0;
+       stackreq[JAVA_GOTO_W]       = 0;
+       stackreq[JAVA_BREAKPOINT]   = 0;
+
+       stackreq[JAVA_SWAP] = 2;
+       stackreq[JAVA_DUP2] = 2;
+       stackreq[JAVA_DUP_X1] = 3;
+       stackreq[JAVA_DUP_X2] = 4;
+       stackreq[JAVA_DUP2_X1] = 3;
+       stackreq[JAVA_DUP2_X2] = 4;
+       
+       for (i = 0; i < 256; i++) stdopdescriptors[i] = NULL;
+
+       for (i = 0; i < sizeof(stdopdescriptortable)/sizeof(stdopdescriptor); i++) {
+               
+               if (stdopdescriptortable[i].isfloat && checkfloats) {
+                       stdopdescriptortable[i].supported = false;
+                       }
+
+               stdopdescriptors[stdopdescriptortable[i].opcode] = 
+                  &(stdopdescriptortable[i]);
+               }
+
+       init_exceptions();
+}
+
+
+void jit_close()
+{
+       mcode_close();
+       reg_close();
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff --git a/jit.h b/jit.h
new file mode 100644 (file)
index 0000000..236b0bd
--- /dev/null
+++ b/jit.h
@@ -0,0 +1,107 @@
+/* jit.h ***********************************************************************
+
+       Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+       See file COPYRIGHT for information on usage and disclaimer of warranties
+
+       new compiler header file for inclusion in other moduls.
+
+       Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
+                Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
+
+       Last Change: 1997/11/05
+
+*******************************************************************************/
+
+/* compiler switches (set by main function) ***********************************/
+
+extern bool runverbose;         /* trace all method invocation                */
+extern bool compileverbose;     /* trace compiler actions                     */
+extern bool showdisassemble;    /* generate disassembler listing              */
+extern bool showddatasegment;   /* generate data segment listing              */
+extern bool showintermediate;   /* generate intermediate code listing         */
+extern int  optimizelevel;      /* optimzation level  (0 = no optimization)   */
+
+extern bool checkbounds;        /* check array bounds                         */
+extern bool checknull;          /* check null pointers                        */
+extern bool checkfloats;        /* implement ieee compliant floats            */
+extern bool checksync;          /* do synchronization                         */
+
+extern bool getcompilingtime;   /* compute compile time                       */
+extern long compilingtime;      /* accumulated compile time                   */
+
+extern int  has_ext_instr_set;  /* has instruction set extensions */
+
+extern bool statistics;         
+
+extern int count_jit_calls;
+extern int count_methods;
+extern int count_spills;
+extern int count_pcmd_activ;
+extern int count_pcmd_drop;
+extern int count_pcmd_zero;
+extern int count_pcmd_const_store;
+extern int count_pcmd_const_alu;
+extern int count_pcmd_const_bra;
+extern int count_pcmd_load;
+extern int count_pcmd_move;
+extern int count_load_instruction;
+extern int count_pcmd_store;
+extern int count_pcmd_store_comb;
+extern int count_dup_instruction;
+extern int count_pcmd_op;
+extern int count_pcmd_mem;
+extern int count_pcmd_met;
+extern int count_pcmd_bra;
+extern int count_pcmd_table;
+extern int count_pcmd_return;
+extern int count_pcmd_returnx;
+extern int count_check_null;
+extern int count_check_bound;
+extern int count_max_basic_blocks;
+extern int count_basic_blocks;
+extern int count_max_javainstr;
+extern int count_javainstr;
+extern int count_javacodesize;
+extern int count_javaexcsize;
+extern int count_calls;
+extern int count_tryblocks;
+extern int count_code_len;
+extern int count_data_len;
+extern int count_cstub_len;
+extern int count_nstub_len;
+extern int count_max_new_stack;
+extern int count_upper_bound_new_stack;
+extern int *count_block_stack;
+extern int *count_analyse_iterations;
+extern int *count_method_bb_distribution;
+extern int *count_block_size_distribution;
+extern int *count_store_length;
+extern int *count_store_depth;
+
+/* prototypes *****************************************************************/
+
+methodptr jit_compile (methodinfo *m);  /* compile a method with jit compiler */
+
+void jit_init();                        /* compiler initialisation            */
+void jit_close();                       /* compiler finalisation              */
+
+u1 *createcompilerstub (methodinfo *m);
+u1 *createnativestub (functionptr f, methodinfo *m);
+
+void removecompilerstub (u1 *stub);
+void removenativestub (u1 *stub);
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff --git a/jit/jitdef.h b/jit/jitdef.h
new file mode 100644 (file)
index 0000000..ae092f1
--- /dev/null
@@ -0,0 +1,1120 @@
+/******************************* ncomp/compdef.h *******************************
+
+       Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+       See file COPYRIGHT for information on usage and disclaimer of warranties
+
+       defines all the constants and data structures of the compiler 
+       
+       Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
+                  
+       Last Change: 1998/11/03
+
+*******************************************************************************/
+
+#include "../sysdep/types.h"
+
+/**************************** resolve typedef-cycles **************************/
+
+typedef struct stackelement stackelement;
+typedef stackelement *stackptr;
+typedef struct basicblock basicblock;
+typedef struct instruction instruction;
+typedef struct subroutineinfo subroutineinfo;
+typedef struct varinfo varinfo;
+typedef struct branchref branchref;
+typedef struct jumpref jumpref;
+typedef varinfo *varinfoptr;
+
+
+/************************** stack element structure ***************************/
+
+/*                    slot types                                              */
+
+#define TYPE_INT   0            /* the stack slot types must numbered in the  */
+#define TYPE_LNG   1            /* same order as the ICMD_Ixxx to ICMD_Axxx   */
+#define TYPE_FLT   2            /* instructions (LOAD and STORE)              */
+#define TYPE_DBL   3            /* integer, long, float, double, address      */
+#define TYPE_ADR   4
+
+#define IS_INT_LNG_TYPE(a)      (!((a)&TYPE_FLT))
+#define IS_FLT_DBL_TYPE(a)      ((a)&TYPE_FLT)
+#define IS_2_WORD_TYPE(a)       ((a)&TYPE_LNG)
+
+
+/*                    flags                                                   */
+
+#define SAVEDVAR   1            /* variable has to survive method invocations */
+#define INMEMORY   2            /* variable stored in memory                  */
+
+/*                    variable types                                          */
+
+#define UNDEFVAR   0            /* stack slot will become temp during regalloc*/
+#define TEMPVAR    1            /* stack slot is temp register                */
+#define STACKVAR   2            /* stack slot is numbered stack slot          */
+#define LOCALVAR   3            /* stack slot is local variable               */
+#define ARGVAR     4            /* stack slot is argument variable            */
+
+struct stackelement {
+       stackptr prev;              /* pointer to next element towards bottom     */
+       int type;                   /* data type of stack element                 */
+       int flags;                  /* flags (SAVED, INMEMORY)                    */
+       int varkind;                /* kind of variable or register               */
+       int varnum;                 /* number of variable                         */
+       int regoff;                 /* register number or memory offset           */
+       };
+
+
+/**************************** instruction structure ***************************/
+
+struct instruction {
+       stackptr dst;               /* stack index of destination operand stack   */
+       u2  opc;                    /* opcode of intermediate code command        */
+       s4  op1;                    /* first operand, usually variable number     */
+
+       union {
+               s4 i;                   /* integer operand    */
+               s8 l;                   /* long operand       */
+               float f;                /* float operand      */
+               double d;               /* double operand     */
+               void *a;                /* address operand    */
+               } val;                  /* immediate constant */
+       };
+
+
+/**************************** basic block structure ***************************/
+/*                    flags                                                   */
+
+#define BBDELETED  -2
+#define BBUNDEF    -1
+#define BBREACHED  0
+#define BBFINISHED 1
+
+#define BBTYPE_STD 0            /* standard basic block type                  */
+#define BBTYPE_EXH 1            /* exception handler basic block type         */
+#define BBTYPE_SBR 2            /* subroutine basic block type                */
+
+struct basicblock { 
+       int          flags;         /* used during stack analysis, init with -1   */
+       int          type;          /* basic block type (std, xhandler, subroutine*/
+       instruction *iinstr;        /* pointer to intermediate code instructions  */
+       int          icount;        /* number of intermediate code instructions   */
+       int          mpc;           /* machine code pc at start of block          */
+       stackptr     instack;       /* stack at begin of basic block              */
+       stackptr     outstack;      /* stack at end of basic block                */
+       int          indepth;       /* stack depth at begin of basic block        */
+       int          outdepth;      /* stack depth end of basic block             */
+       int          pre_count;     /* count of predecessor basic blocks          */
+       branchref   *branchrefs;    /* list of branches to be patched             */
+       };
+
+
+/************************* pseudo variable structure **************************/
+
+struct varinfo {
+       int type;                   /* basic type of variable                     */
+       int flags;                  /* flags (SAVED, INMEMORY)                    */
+       int regoff;                 /* register number or memory offset           */
+       };
+
+typedef varinfo varinfo5[5];
+
+
+/***************** forward references in branch instructions ******************/
+
+struct branchref {
+       s4 branchpos;               /* patching position in code segment          */
+       branchref *next;            /* next element in branchref list             */
+       };
+
+
+/******************** forward references in tables  ***************************/
+
+struct jumpref {
+       s4 tablepos;                /* patching position in data segment          */
+       basicblock *target;         /* target basic block                         */
+       jumpref *next;              /* next element in jumpref list               */
+       };
+
+
+/********** JavaVM operation codes (sorted) and instruction lengths ***********/
+
+static int stackreq[256];
+
+static int jcommandsize[256] = {
+
+#define JAVA_NOP               0
+#define ICMD_NOP               0
+        1,
+#define JAVA_ACONST_NULL       1
+#define ICMD_ACONST            1        /* val.a = constant                   */
+        1,
+#define JAVA_ICONST_M1         2
+#define ICMD_NULLCHECKPOP      2
+        1,
+#define JAVA_ICONST_0          3
+#define ICMD_ICONST            3        /* val.i = constant                   */
+        1,
+#define JAVA_ICONST_1          4
+#define ICMD_IREM0X10001       4
+        1,
+#define JAVA_ICONST_2          5
+#define ICMD_IDIVPOW2          5        /* val.i = constant                   */
+        1,
+#define JAVA_ICONST_3          6
+#define ICMD_LDIVPOW2          6        /* val.l = constant                   */
+        1,
+#define JAVA_ICONST_4          7
+        1,
+#define JAVA_ICONST_5          8
+#define ICMD_LREM0X10001       8
+        1,
+#define JAVA_LCONST_0          9
+#define ICMD_LCONST            9        /* val.l = constant                   */
+        1,
+#define JAVA_LCONST_1         10
+#define ICMD_LCMPCONST        10        /* val.l = constant                   */
+        1,
+#define JAVA_FCONST_0         11
+#define ICMD_FCONST           11        /* val.f = constant                   */
+        1,
+#define JAVA_FCONST_1         12
+        1,
+#define JAVA_FCONST_2         13
+#define ICMD_ELSE_ICONST      13
+        1,
+#define JAVA_DCONST_0         14
+#define ICMD_DCONST           14        /* val.d = constant                   */
+        1,
+#define JAVA_DCONST_1         15
+#define ICMD_IFEQ_ICONST      15
+        1,
+#define JAVA_BIPUSH           16
+#define ICMD_IFNE_ICONST      16
+        2,
+#define JAVA_SIPUSH           17
+#define ICMD_IFLT_ICONST      17
+        3,
+#define JAVA_LDC1             18
+#define ICMD_IFGE_ICONST      18
+        2,
+#define JAVA_LDC2             19
+#define ICMD_IFGT_ICONST      19
+        3,
+#define JAVA_LDC2W            20
+#define ICMD_IFLE_ICONST      20
+        3,
+                                        /* order of LOAD instructions must be */
+                                        /* equal to order of TYPE_XXX defines */
+#define JAVA_ILOAD            21
+#define ICMD_ILOAD            21        /* op1 = local variable               */
+        2,                      
+#define JAVA_LLOAD            22
+#define ICMD_LLOAD            22        /* op1 = local variable               */
+        2,
+#define JAVA_FLOAD            23
+#define ICMD_FLOAD            23        /* op1 = local variable               */
+        2,
+#define JAVA_DLOAD            24
+#define ICMD_DLOAD            24        /* op1 = local variable               */
+        2,
+#define JAVA_ALOAD            25
+#define ICMD_ALOAD            25        /* op1 = local variable               */
+        2,
+#define JAVA_ILOAD_0          26
+#define ICMD_IADDCONST        26        /* val.i = constant                   */
+        1,
+#define JAVA_ILOAD_1          27
+#define ICMD_ISUBCONST        27        /* val.i = constant                   */
+        1,
+#define JAVA_ILOAD_2          28
+#define ICMD_IMULCONST        28        /* val.i = constant                   */
+        1,
+#define JAVA_ILOAD_3          29
+#define ICMD_IANDCONST        29        /* val.i = constant                   */
+        1,
+#define JAVA_LLOAD_0          30
+#define ICMD_IORCONST         30        /* val.i = constant                   */
+        1,
+#define JAVA_LLOAD_1          31
+#define ICMD_IXORCONST        31        /* val.i = constant                   */
+        1,
+#define JAVA_LLOAD_2          32
+#define ICMD_ISHLCONST        32        /* val.i = constant                   */
+        1,
+#define JAVA_LLOAD_3          33
+#define ICMD_ISHRCONST        33        /* val.i = constant                   */
+        1,
+#define JAVA_FLOAD_0          34
+#define ICMD_IUSHRCONST       34        /* val.i = constant                   */
+        1,
+#define JAVA_FLOAD_1          35
+#define ICMD_IREMPOW2         35        /* val.i = constant                   */
+        1,
+#define JAVA_FLOAD_2          36
+#define ICMD_LADDCONST        36        /* val.l = constant                   */
+        1,
+#define JAVA_FLOAD_3          37
+#define ICMD_LSUBCONST        37        /* val.l = constant                   */
+        1,
+#define JAVA_DLOAD_0          38
+#define ICMD_LMULCONST        38        /* val.l = constant                   */
+        1,
+#define JAVA_DLOAD_1          39
+#define ICMD_LANDCONST        39        /* val.l = constant                   */
+        1,
+#define JAVA_DLOAD_2          40
+#define ICMD_LORCONST         40        /* val.l = constant                   */
+        1,
+#define JAVA_DLOAD_3          41
+#define ICMD_LXORCONST        41        /* val.l = constant                   */
+        1,
+#define JAVA_ALOAD_0          42
+#define ICMD_LSHLCONST        42        /* val.l = constant                   */
+        1,
+#define JAVA_ALOAD_1          43
+#define ICMD_LSHRCONST        43        /* val.l = constant                   */
+        1,
+#define JAVA_ALOAD_2          44
+#define ICMD_LUSHRCONST       44        /* val.l = constant                   */
+        1,
+#define JAVA_ALOAD_3          45
+#define ICMD_LREMPOW2         45        /* val.l = constant                   */
+        1,
+#define JAVA_IALOAD           46
+#define ICMD_IALOAD           46
+        1,
+#define JAVA_LALOAD           47
+#define ICMD_LALOAD           47
+        1,
+#define JAVA_FALOAD           48
+#define ICMD_FALOAD           48
+        1,
+#define JAVA_DALOAD           49
+#define ICMD_DALOAD           49
+        1,
+#define JAVA_AALOAD           50
+#define ICMD_AALOAD           50
+        1,
+#define JAVA_BALOAD           51
+#define ICMD_BALOAD           51
+        1,
+#define JAVA_CALOAD           52
+#define ICMD_CALOAD           52
+        1,
+#define JAVA_SALOAD           53
+#define ICMD_SALOAD           53
+        1,
+                                        /* order of STORE instructions must be*/
+                                        /* equal to order of TYPE_XXX defines */
+#define JAVA_ISTORE           54
+#define ICMD_ISTORE           54        /* op1 = local variable               */
+        2,
+#define JAVA_LSTORE           55
+#define ICMD_LSTORE           55        /* op1 = local variable               */
+        2,
+#define JAVA_FSTORE           56
+#define ICMD_FSTORE           56        /* op1 = local variable               */
+        2,
+#define JAVA_DSTORE           57
+#define ICMD_DSTORE           57        /* op1 = local variable               */
+        2,
+#define JAVA_ASTORE           58
+#define ICMD_ASTORE           58        /* op1 = local variable               */
+        2,
+#define JAVA_ISTORE_0         59
+#define ICMD_IF_LEQ           59        /* op1 = target JavaVM pc, val.l      */
+        1,
+#define JAVA_ISTORE_1         60
+#define ICMD_IF_LNE           60        /* op1 = target JavaVM pc, val.l      */
+        1,
+#define JAVA_ISTORE_2         61
+#define ICMD_IF_LLT           61        /* op1 = target JavaVM pc, val.l      */
+        1,
+#define JAVA_ISTORE_3         62
+#define ICMD_IF_LGE           62        /* op1 = target JavaVM pc, val.l      */
+        1,
+#define JAVA_LSTORE_0         63
+#define ICMD_IF_LGT           63        /* op1 = target JavaVM pc, val.l      */
+        1,
+#define JAVA_LSTORE_1         64
+#define ICMD_IF_LLE           64        /* op1 = target JavaVM pc, val.l      */
+        1,
+#define JAVA_LSTORE_2         65
+#define ICMD_IF_LCMPEQ        65        /* op1 = target JavaVM pc             */
+        1,
+#define JAVA_LSTORE_3         66
+#define ICMD_IF_LCMPNE        66        /* op1 = target JavaVM pc             */
+        1,
+#define JAVA_FSTORE_0         67
+#define ICMD_IF_LCMPLT        67        /* op1 = target JavaVM pc             */
+        1,
+#define JAVA_FSTORE_1         68
+#define ICMD_IF_LCMPGE        68        /* op1 = target JavaVM pc             */
+        1,
+#define JAVA_FSTORE_2         69
+#define ICMD_IF_LCMPGT        69        /* op1 = target JavaVM pc             */
+        1,
+#define JAVA_FSTORE_3         70
+#define ICMD_IF_LCMPLE        70        /* op1 = target JavaVM pc             */
+        1,
+#define JAVA_DSTORE_0         71
+        1,
+#define JAVA_DSTORE_1         72
+        1,
+#define JAVA_DSTORE_2         73
+        1,
+#define JAVA_DSTORE_3         74
+        1,
+#define JAVA_ASTORE_0         75
+        1,
+#define JAVA_ASTORE_1         76
+        1,
+#define JAVA_ASTORE_2         77
+        1,
+#define JAVA_ASTORE_3         78
+        1,
+#define JAVA_IASTORE          79
+#define ICMD_IASTORE          79
+        1,
+#define JAVA_LASTORE          80
+#define ICMD_LASTORE          80
+        1,
+#define JAVA_FASTORE          81
+#define ICMD_FASTORE          81
+        1,
+#define JAVA_DASTORE          82
+#define ICMD_DASTORE          82
+        1,
+#define JAVA_AASTORE          83
+#define ICMD_AASTORE          83
+        1,
+#define JAVA_BASTORE          84
+#define ICMD_BASTORE          84
+        1,
+#define JAVA_CASTORE          85
+#define ICMD_CASTORE          85
+        1,
+#define JAVA_SASTORE          86
+#define ICMD_SASTORE          86
+        1,
+#define JAVA_POP              87
+#define ICMD_POP              87
+        1,
+#define JAVA_POP2             88
+#define ICMD_POP2             88
+        1,
+#define JAVA_DUP              89
+#define ICMD_DUP              89
+        1,
+#define JAVA_DUP_X1           90
+#define ICMD_DUP_X1           90
+        1,
+#define JAVA_DUP_X2           91
+#define ICMD_DUP_X2           91
+        1,
+#define JAVA_DUP2             92
+#define ICMD_DUP2             92
+        1,
+#define JAVA_DUP2_X1          93
+#define ICMD_DUP2_X1          93
+        1,
+#define JAVA_DUP2_X2          94
+#define ICMD_DUP2_X2          94
+        1,
+#define JAVA_SWAP             95
+#define ICMD_SWAP             95
+        1,
+#define JAVA_IADD             96
+#define ICMD_IADD             96
+        1,
+#define JAVA_LADD             97
+#define ICMD_LADD             97
+        1,
+#define JAVA_FADD             98
+#define ICMD_FADD             98
+        1,
+#define JAVA_DADD             99
+#define ICMD_DADD             99
+        1,
+#define JAVA_ISUB             100
+#define ICMD_ISUB             100
+        1,
+#define JAVA_LSUB             101
+#define ICMD_LSUB             101
+        1,
+#define JAVA_FSUB             102
+#define ICMD_FSUB             102
+        1,
+#define JAVA_DSUB             103
+#define ICMD_DSUB             103
+        1,
+#define JAVA_IMUL             104
+#define ICMD_IMUL             104
+        1,
+#define JAVA_LMUL             105
+#define ICMD_LMUL             105
+        1,
+#define JAVA_FMUL             106
+#define ICMD_FMUL             106
+        1,
+#define JAVA_DMUL             107
+#define ICMD_DMUL             107
+        1,
+#define JAVA_IDIV             108
+#define ICMD_IDIV             108
+        1,
+#define JAVA_LDIV             109
+#define ICMD_LDIV             109
+        1,
+#define JAVA_FDIV             110
+#define ICMD_FDIV             110
+        1,
+#define JAVA_DDIV             111
+#define ICMD_DDIV             111
+        1,
+#define JAVA_IREM             112
+#define ICMD_IREM             112
+        1,
+#define JAVA_LREM             113
+#define ICMD_LREM             113
+        1,
+#define JAVA_FREM             114
+#define ICMD_FREM             114
+        1,
+#define JAVA_DREM             115
+#define ICMD_DREM             115
+        1,
+#define JAVA_INEG             116
+#define ICMD_INEG             116
+        1,
+#define JAVA_LNEG             117
+#define ICMD_LNEG             117
+        1,
+#define JAVA_FNEG             118
+#define ICMD_FNEG             118
+        1,
+#define JAVA_DNEG             119
+#define ICMD_DNEG             119
+        1,
+#define JAVA_ISHL             120
+#define ICMD_ISHL             120
+        1,
+#define JAVA_LSHL             121
+#define ICMD_LSHL             121
+        1,
+#define JAVA_ISHR             122
+#define ICMD_ISHR             122
+        1,
+#define JAVA_LSHR             123
+#define ICMD_LSHR             123
+        1,
+#define JAVA_IUSHR            124
+#define ICMD_IUSHR            124
+        1,
+#define JAVA_LUSHR            125
+#define ICMD_LUSHR            125
+        1,
+#define JAVA_IAND             126
+#define ICMD_IAND             126
+        1,
+#define JAVA_LAND             127
+#define ICMD_LAND             127
+        1,
+#define JAVA_IOR              128
+#define ICMD_IOR              128
+        1,
+#define JAVA_LOR              129
+#define ICMD_LOR              129
+        1,
+#define JAVA_IXOR             130
+#define ICMD_IXOR             130
+        1,
+#define JAVA_LXOR             131
+#define ICMD_LXOR             131
+        1,
+#define JAVA_IINC             132
+#define ICMD_IINC             132   /* op1 = local variable, val.i = constant */
+        3,
+#define JAVA_I2L              133
+#define ICMD_I2L              133
+        1,
+#define JAVA_I2F              134
+#define ICMD_I2F              134
+        1,
+#define JAVA_I2D              135
+#define ICMD_I2D              135
+        1,
+#define JAVA_L2I              136
+#define ICMD_L2I              136
+        1,
+#define JAVA_L2F              137
+#define ICMD_L2F              137
+        1,
+#define JAVA_L2D              138
+#define ICMD_L2D              138
+        1,
+#define JAVA_F2I              139
+#define ICMD_F2I              139
+        1,
+#define JAVA_F2L              140
+#define ICMD_F2L              140
+        1,
+#define JAVA_F2D              141
+#define ICMD_F2D              141
+        1,
+#define JAVA_D2I              142
+#define ICMD_D2I              142
+        1,
+#define JAVA_D2L              143
+#define ICMD_D2L              143
+        1,
+#define JAVA_D2F              144
+#define ICMD_D2F              144
+        1,
+#define JAVA_INT2BYTE         145
+#define ICMD_INT2BYTE         145
+        1,
+#define JAVA_INT2CHAR         146
+#define ICMD_INT2CHAR         146
+        1,
+#define JAVA_INT2SHORT        147
+#define ICMD_INT2SHORT        147
+        1,
+#define JAVA_LCMP             148
+#define ICMD_LCMP             148
+        1,
+#define JAVA_FCMPL            149
+#define ICMD_FCMPL            149
+        1,
+#define JAVA_FCMPG            150
+#define ICMD_FCMPG            150
+        1,
+#define JAVA_DCMPL            151
+#define ICMD_DCMPL            151
+        1,
+#define JAVA_DCMPG            152
+#define ICMD_DCMPG            152
+        1,
+#define JAVA_IFEQ             153
+#define ICMD_IFEQ             153       /* op1 = target JavaVM pc, val.i      */
+        3,
+#define JAVA_IFNE             154
+#define ICMD_IFNE             154       /* op1 = target JavaVM pc, val.i      */
+        3,
+#define JAVA_IFLT             155
+#define ICMD_IFLT             155       /* op1 = target JavaVM pc, val.i      */
+        3,
+#define JAVA_IFGE             156
+#define ICMD_IFGE             156       /* op1 = target JavaVM pc, val.i      */
+        3,
+#define JAVA_IFGT             157
+#define ICMD_IFGT             157       /* op1 = target JavaVM pc, val.i      */
+        3,
+#define JAVA_IFLE             158
+#define ICMD_IFLE             158       /* op1 = target JavaVM pc, val.i      */
+        3,
+#define JAVA_IF_ICMPEQ        159
+#define ICMD_IF_ICMPEQ        159       /* op1 = target JavaVM pc             */
+        3,
+#define JAVA_IF_ICMPNE        160
+#define ICMD_IF_ICMPNE        160       /* op1 = target JavaVM pc             */
+        3,
+#define JAVA_IF_ICMPLT        161
+#define ICMD_IF_ICMPLT        161       /* op1 = target JavaVM pc             */
+        3,
+#define JAVA_IF_ICMPGE        162
+#define ICMD_IF_ICMPGE        162       /* op1 = target JavaVM pc             */
+        3,
+#define JAVA_IF_ICMPGT        163
+#define ICMD_IF_ICMPGT        163       /* op1 = target JavaVM pc             */
+        3,
+#define JAVA_IF_ICMPLE        164
+#define ICMD_IF_ICMPLE        164       /* op1 = target JavaVM pc             */
+        3,
+#define JAVA_IF_ACMPEQ        165
+#define ICMD_IF_ACMPEQ        165       /* op1 = target JavaVM pc             */
+        3,
+#define JAVA_IF_ACMPNE        166
+#define ICMD_IF_ACMPNE        166       /* op1 = target JavaVM pc             */
+        3,
+#define JAVA_GOTO             167
+#define ICMD_GOTO             167       /* op1 = target JavaVM pc             */
+        3,
+#define JAVA_JSR              168
+#define ICMD_JSR              168       /* op1 = target JavaVM pc             */
+        3,
+#define JAVA_RET              169
+#define ICMD_RET              169       /* op1 = local variable               */
+        2,
+#define JAVA_TABLESWITCH      170
+#define ICMD_TABLESWITCH      170       /* val.a = pointer to s4 table        */
+        0,                              /* length must be computed            */
+#define JAVA_LOOKUPSWITCH     171
+#define ICMD_LOOKUPSWITCH     171       /* val.a = pointer to s4 table        */
+        0,                              /* length must be computed            */
+#define JAVA_IRETURN          172
+#define ICMD_IRETURN          172
+        1,
+#define JAVA_LRETURN          173
+#define ICMD_LRETURN          173
+        1,
+#define JAVA_FRETURN          174
+#define ICMD_FRETURN          174
+        1,
+#define JAVA_DRETURN          175
+#define ICMD_DRETURN          175
+        1,
+#define JAVA_ARETURN          176
+#define ICMD_ARETURN          176
+        1,
+#define JAVA_RETURN           177
+#define ICMD_RETURN           177
+        1,
+#define JAVA_GETSTATIC        178
+#define ICMD_GETSTATIC        178       /* op1 = type, val.a = field address  */
+        3,
+#define JAVA_PUTSTATIC        179
+#define ICMD_PUTSTATIC        179       /* op1 = type, val.a = field address  */
+        3,
+#define JAVA_GETFIELD         180
+#define ICMD_GETFIELD         180       /* op1 = type, val.i = field offset   */
+        3,
+#define JAVA_PUTFIELD         181
+#define ICMD_PUTFIELD         181       /* op1 = type, val.i = field offset   */
+        3,
+#define JAVA_INVOKEVIRTUAL    182
+#define ICMD_INVOKEVIRTUAL    182       /* val.a = method info pointer        */
+        3,
+#define JAVA_INVOKESPECIAL    183
+#define ICMD_INVOKESPECIAL    183       /* val.a = method info pointer        */
+        3,
+#define JAVA_INVOKESTATIC     184
+#define ICMD_INVOKESTATIC     184       /* val.a = method info pointer        */
+        3,
+#define JAVA_INVOKEINTERFACE  185
+#define ICMD_INVOKEINTERFACE  185       /* val.a = method info pointer        */
+        5,
+#define ICMD_CHECKASIZE       186       /*                                    */
+        1, /* unused */
+#define JAVA_NEW              187
+#define ICMD_NEW              187       /* op1 = 1, val.a = class pointer     */
+        3,
+#define JAVA_NEWARRAY         188
+#define ICMD_NEWARRAY         188       /* op1 = basic type                   */
+        2,
+#define JAVA_ANEWARRAY        189
+#define ICMD_ANEWARRAY        189       /* op1 = 0, val.a = array pointer     */
+        3,                              /* op1 = 1, val.a = class pointer     */
+#define JAVA_ARRAYLENGTH      190
+#define ICMD_ARRAYLENGTH      190
+        1,
+#define JAVA_ATHROW           191
+#define ICMD_ATHROW           191
+        1,
+#define JAVA_CHECKCAST        192
+#define ICMD_CHECKCAST        192       /* op1 = 0, val.a = array pointer     */
+        3,                              /* op1 = 1, val.a = class pointer     */
+#define JAVA_INSTANCEOF       193
+#define ICMD_INSTANCEOF       193       /* op1 = 0, val.a = array pointer     */
+        3,                              /* op1 = 1, val.a = class pointer     */
+#define JAVA_MONITORENTER     194
+#define ICMD_MONITORENTER     194
+        1,
+#define JAVA_MONITOREXIT      195
+#define ICMD_MONITOREXIT      195
+        1,
+#define JAVA_WIDE             196
+        0,       /* length must be computed */
+#define JAVA_MULTIANEWARRAY   197
+#define ICMD_MULTIANEWARRAY   197       /* op1 = dimension, val.a = array     */
+        4,                              /* pointer                            */
+#define JAVA_IFNULL           198
+#define ICMD_IFNULL           198       /* op1 = target JavaVM pc             */
+        3,
+#define JAVA_IFNONNULL        199
+#define ICMD_IFNONNULL        199       /* op1 = target JavaVM pc             */
+        3,
+#define JAVA_GOTO_W           200
+        5,
+#define JAVA_JSR_W            201
+        5,
+#define JAVA_BREAKPOINT       202
+        1,
+
+            1,1,1,1,1,1,1,1,            /* unused */
+        1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1
+    };
+
+#define ICMD_BUILTIN3         253       /* internal opcode */
+#define ICMD_BUILTIN2         254       /* internal opcode */
+#define ICMD_BUILTIN1         255       /* internal opcode */
+
+
+/******************* description of JavaVM instructions ***********************/
+
+typedef struct {
+       u1 opcode;
+       u1 type_s1;
+       u1 type_s2;
+       u1 type_d;      
+       functionptr builtin;
+       bool supported;
+       bool isfloat;
+} stdopdescriptor;
+
+static stdopdescriptor *stdopdescriptors[256];
+
+static stdopdescriptor stdopdescriptortable[] = {
+       { JAVA_IADD,   TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+       { JAVA_ISUB,   TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+       { JAVA_IMUL,   TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+       { JAVA_ISHL,   TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+       { JAVA_ISHR,   TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+       { JAVA_IUSHR,  TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+       { JAVA_IAND,   TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+       { JAVA_IOR,    TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+       { JAVA_IXOR,   TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+       { JAVA_INEG,   TYPE_INT, TYPE_VOID,TYPE_INT, NULL, true, false },
+
+       { JAVA_LADD,   TYPE_LONG, TYPE_LONG, TYPE_LONG, 
+              (functionptr) builtin_ladd , SUPPORT_LONG && SUPPORT_LONG_ADD, false },
+       { JAVA_LSUB,   TYPE_LONG, TYPE_LONG, TYPE_LONG,
+              (functionptr) builtin_lsub , SUPPORT_LONG && SUPPORT_LONG_ADD, false },
+       { JAVA_LMUL,   TYPE_LONG, TYPE_LONG, TYPE_LONG,
+              (functionptr) builtin_lmul , SUPPORT_LONG && SUPPORT_LONG_MULDIV, false },
+       { JAVA_LSHL,   TYPE_LONG, TYPE_INT,  TYPE_LONG,
+              (functionptr) builtin_lshl , SUPPORT_LONG && SUPPORT_LONG_SHIFT, false },
+       { JAVA_LSHR,   TYPE_LONG, TYPE_INT,  TYPE_LONG,
+              (functionptr) builtin_lshr, SUPPORT_LONG && SUPPORT_LONG_SHIFT, false },
+       { JAVA_LUSHR,  TYPE_LONG, TYPE_INT,  TYPE_LONG,
+              (functionptr) builtin_lushr, SUPPORT_LONG && SUPPORT_LONG_SHIFT, false },
+       { JAVA_LAND,   TYPE_LONG, TYPE_LONG, TYPE_LONG,
+              (functionptr) builtin_land, SUPPORT_LONG && SUPPORT_LONG_LOG, false },
+       { JAVA_LOR,    TYPE_LONG, TYPE_LONG, TYPE_LONG,
+              (functionptr) builtin_lor , SUPPORT_LONG && SUPPORT_LONG_LOG, false },
+       { JAVA_LXOR,   TYPE_LONG, TYPE_LONG, TYPE_LONG,
+              (functionptr) builtin_lxor, SUPPORT_LONG && SUPPORT_LONG_LOG, false },
+       { JAVA_LNEG,   TYPE_LONG, TYPE_VOID, TYPE_LONG,
+              (functionptr) builtin_lneg, SUPPORT_LONG && SUPPORT_LONG_ADD, false },
+       { JAVA_LCMP,   TYPE_LONG, TYPE_LONG, TYPE_INT,
+              (functionptr) builtin_lcmp, SUPPORT_LONG && SUPPORT_LONG_CMP, false },
+
+       { JAVA_FADD,   TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, 
+              (functionptr) builtin_fadd, SUPPORT_FLOAT, true },
+       { JAVA_FSUB,   TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, 
+              (functionptr) builtin_fsub, SUPPORT_FLOAT, true },
+       { JAVA_FMUL,   TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, 
+              (functionptr) builtin_fmul, SUPPORT_FLOAT, true },
+       { JAVA_FDIV,   TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, 
+              (functionptr) builtin_fdiv, SUPPORT_FLOAT, true },
+       { JAVA_FREM,   TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, 
+              (functionptr) builtin_frem, SUPPORT_FLOAT, true },
+       { JAVA_FNEG,   TYPE_FLOAT, TYPE_VOID,  TYPE_FLOAT, 
+              (functionptr) builtin_fneg, SUPPORT_FLOAT, true },
+       { JAVA_FCMPL,  TYPE_FLOAT, TYPE_FLOAT, TYPE_INT,   
+              (functionptr) builtin_fcmpl, SUPPORT_FLOAT, true },
+       { JAVA_FCMPG,  TYPE_FLOAT, TYPE_FLOAT, TYPE_INT,   
+              (functionptr) builtin_fcmpg, SUPPORT_FLOAT, true },
+
+       { JAVA_DADD,   TYPE_DOUBLE, TYPE_DOUBLE, TYPE_DOUBLE, 
+              (functionptr) builtin_dadd, SUPPORT_DOUBLE, true },
+       { JAVA_DSUB,   TYPE_DOUBLE, TYPE_DOUBLE, TYPE_DOUBLE, 
+              (functionptr) builtin_dsub, SUPPORT_DOUBLE, true },
+       { JAVA_DMUL,   TYPE_DOUBLE, TYPE_DOUBLE, TYPE_DOUBLE, 
+              (functionptr) builtin_dmul, SUPPORT_DOUBLE, true },
+       { JAVA_DDIV,   TYPE_DOUBLE, TYPE_DOUBLE, TYPE_DOUBLE, 
+              (functionptr) builtin_ddiv, SUPPORT_DOUBLE, true },
+       { JAVA_DREM,   TYPE_DOUBLE, TYPE_DOUBLE, TYPE_DOUBLE, 
+              (functionptr) builtin_drem, SUPPORT_DOUBLE, true },
+       { JAVA_DNEG,   TYPE_DOUBLE, TYPE_VOID,  TYPE_DOUBLE, 
+              (functionptr) builtin_dneg, SUPPORT_DOUBLE, true },
+       { JAVA_DCMPL,  TYPE_DOUBLE, TYPE_DOUBLE, TYPE_INT, 
+              (functionptr) builtin_dcmpl, SUPPORT_DOUBLE, true },
+       { JAVA_DCMPG,  TYPE_DOUBLE, TYPE_DOUBLE, TYPE_INT, 
+              (functionptr) builtin_dcmpg, SUPPORT_DOUBLE, true },
+
+       { JAVA_INT2BYTE, TYPE_INT, TYPE_VOID, TYPE_INT, NULL, true,false },
+       { JAVA_INT2CHAR, TYPE_INT, TYPE_VOID, TYPE_INT, NULL, true,false },
+       { JAVA_INT2SHORT, TYPE_INT, TYPE_VOID, TYPE_INT, NULL, true,false },
+       { JAVA_I2L,    TYPE_INT,  TYPE_VOID, TYPE_LONG,   
+           (functionptr) builtin_i2l, SUPPORT_LONG && SUPPORT_LONG_ICVT, false },
+       { JAVA_I2F,    TYPE_INT,  TYPE_VOID, TYPE_FLOAT,  
+              (functionptr) builtin_i2f, SUPPORT_FLOAT, true },
+       { JAVA_I2D,    TYPE_INT,  TYPE_VOID, TYPE_DOUBLE, 
+              (functionptr) builtin_i2d, SUPPORT_DOUBLE, true },
+       { JAVA_L2I,    TYPE_LONG, TYPE_VOID, TYPE_INT,    
+              (functionptr) builtin_l2i, SUPPORT_LONG && SUPPORT_LONG_ICVT, false },
+       { JAVA_L2F,    TYPE_LONG, TYPE_VOID, TYPE_FLOAT,  
+              (functionptr) builtin_l2f, SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_LONG_FCVT, true },
+       { JAVA_L2D,    TYPE_LONG, TYPE_VOID, TYPE_DOUBLE, 
+              (functionptr) builtin_l2d, SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_LONG_FCVT, true },
+       { JAVA_F2I,    TYPE_FLOAT, TYPE_VOID, TYPE_INT,   
+              (functionptr) builtin_f2i, SUPPORT_FLOAT, true },
+       { JAVA_F2L,    TYPE_FLOAT, TYPE_VOID, TYPE_LONG,   
+              (functionptr) builtin_f2l, SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_LONG_FCVT, true },
+       { JAVA_F2D,    TYPE_FLOAT, TYPE_VOID, TYPE_DOUBLE, 
+              (functionptr) builtin_f2d, SUPPORT_FLOAT && SUPPORT_DOUBLE, true },
+       { JAVA_D2I,    TYPE_DOUBLE, TYPE_VOID, TYPE_INT,   
+              (functionptr) builtin_d2i, SUPPORT_DOUBLE, true },
+       { JAVA_D2L,    TYPE_DOUBLE, TYPE_VOID, TYPE_LONG,   
+              (functionptr) builtin_d2l, SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_LONG_FCVT, true },
+       { JAVA_D2F,    TYPE_DOUBLE, TYPE_VOID, TYPE_FLOAT, 
+              (functionptr) builtin_d2f, SUPPORT_DOUBLE && SUPPORT_FLOAT, true },
+       
+};
+
+static char *icmd_names[256] = {
+       "NOP          ", /*               0 */
+       "ACONST       ", /*               1 */
+       "NULLCHECKPOP ", /* ICONST_M1     2 */
+       "ICONST       ", /*               3 */
+       "IREM0X10001  ", /* ICONST_1      4 */
+       "IDIVPOW2     ", /* ICONST_2      5 */
+       "LDIVPOW2     ", /* ICONST_3      6 */
+       "UNDEF__7     ", /* ICONST_4      7 */
+       "LREM0X10001  ", /* ICONST_5      8 */
+       "LCONST       ", /*               9 */
+       "LCMPCONST    ", /* LCONST_1     10 */
+       "FCONST       ", /*              11 */
+       "UNDEF_12     ", /* FCONST_1     12 */
+       "ELSE_ICONST  ", /* FCONST_2     13 */
+       "DCONST       ", /*              14 */
+       "IFEQ_ICONST  ", /* DCONST_1     15 */
+       "IFNE_ICONST  ", /* BIPUSH       16 */
+       "IFLT_ICONST  ", /* SIPUSH       17 */
+       "IFGE_ICONST  ", /* LDC1         18 */
+       "IFGT_ICONST  ", /* LDC2         19 */
+       "IFLE_ICONST  ", /* LDC2W        20 */
+       "ILOAD        ", /*              21 */
+       "LLOAD        ", /*              22 */
+       "FLOAD        ", /*              23 */
+       "DLOAD        ", /*              24 */
+       "ALOAD        ", /*              25 */
+       "IADDCONST    ", /* ILOAD_0      26 */
+       "ISUBCONST    ", /* ILOAD_1      27 */
+       "IMULCONST    ", /* ILOAD_2      28 */
+       "IANDCONST    ", /* ILOAD_3      29 */
+       "IORCONST     ", /* LLOAD_0      30 */
+       "IXORCONST    ", /* LLOAD_1      31 */
+       "ISHLCONST    ", /* LLOAD_2      32 */
+       "ISHRCONST    ", /* LLOAD_3      33 */
+       "IUSHRCONST   ", /* FLOAD_0      34 */
+       "IREMPOW2     ", /* FLOAD_1      35 */
+       "LADDCONST    ", /* FLOAD_2      36 */
+       "LSUBCONST    ", /* FLOAD_3      37 */
+       "LMULCONST    ", /* DLOAD_0      38 */
+       "LANDCONST    ", /* DLOAD_1      39 */
+       "LORCONST     ", /* DLOAD_2      40 */
+       "LXORCONST    ", /* DLOAD_3      41 */
+       "LSHLCONST    ", /* ALOAD_0      42 */
+       "LSHRCONST    ", /* ALOAD_1      43 */
+       "LUSHRCONST   ", /* ALOAD_2      44 */
+       "LREMPOW2     ", /* ALOAD_3      45 */
+       "IALOAD       ", /*              46 */
+       "LALOAD       ", /*              47 */
+       "FALOAD       ", /*              48 */
+       "DALOAD       ", /*              49 */
+       "AALOAD       ", /*              50 */
+       "BALOAD       ", /*              51 */
+       "CALOAD       ", /*              52 */
+       "SALOAD       ", /*              53 */
+       "ISTORE       ", /*              54 */
+       "LSTORE       ", /*              55 */
+       "FSTORE       ", /*              56 */
+       "DSTORE       ", /*              57 */
+       "ASTORE       ", /*              58 */
+       "IF_LEQ       ", /* ISTORE_0     59 */
+       "IF_LNE       ", /* ISTORE_1     60 */
+       "IF_LLT       ", /* ISTORE_2     61 */
+       "IF_LGE       ", /* ISTORE_3     62 */
+       "IF_LGT       ", /* LSTORE_0     63 */
+       "IF_LLE       ", /* LSTORE_1     64 */
+       "IF_LCMPEQ    ", /* LSTORE_2     65 */
+       "IF_LCMPNE    ", /* LSTORE_3     66 */
+       "IF_LCMPLT    ", /* FSTORE_0     67 */
+       "IF_LCMPGE    ", /* FSTORE_1     68 */
+       "IF_LCMPGT    ", /* FSTORE_2     69 */
+       "IF_LCMPLE    ", /* FSTORE_3     70 */
+       "UNDEF_71     ", /* DSTORE_0     71 */
+       "UNDEF_72     ", /* DSTORE_1     72 */
+       "UNDEF_73     ", /* DSTORE_2     73 */
+       "UNDEF_74     ", /* DSTORE_3     74 */
+       "UNDEF_75     ", /* ASTORE_0     75 */
+       "UNDEF_76     ", /* ASTORE_1     76 */
+       "UNDEF_77     ", /* ASTORE_2     77 */
+       "UNDEF_78     ", /* ASTORE_3     78 */
+       "IASTORE      ", /*              79 */
+       "LASTORE      ", /*              80 */
+       "FASTORE      ", /*              81 */
+       "DASTORE      ", /*              82 */
+       "AASTORE      ", /*              83 */
+       "BASTORE      ", /*              84 */
+       "CASTORE      ", /*              85 */
+       "SASTORE      ", /*              86 */
+       "POP          ", /*              87 */
+       "POP2         ", /*              88 */
+       "DUP          ", /*              89 */
+       "DUP_X1       ", /*              90 */
+       "DUP_X2       ", /*              91 */
+       "DUP2         ", /*              92 */
+       "DUP2_X1      ", /*              93 */
+       "DUP2_X2      ", /*              94 */
+       "SWAP         ", /*              95 */
+       "IADD         ", /*              96 */
+       "LADD         ", /*              97 */
+       "FADD         ", /*              98 */
+       "DADD         ", /*              99 */
+       "ISUB         ", /*             100 */
+       "LSUB         ", /*             101 */
+       "FSUB         ", /*             102 */
+       "DSUB         ", /*             103 */
+       "IMUL         ", /*             104 */
+       "LMUL         ", /*             105 */
+       "FMUL         ", /*             106 */
+       "DMUL         ", /*             107 */
+       "IDIV         ", /*             108 */
+       "LDIV         ", /*             109 */
+       "FDIV         ", /*             110 */
+       "DDIV         ", /*             111 */
+       "IREM         ", /*             112 */
+       "LREM         ", /*             113 */
+       "FREM         ", /*             114 */
+       "DREM         ", /*             115 */
+       "INEG         ", /*             116 */
+       "LNEG         ", /*             117 */
+       "FNEG         ", /*             118 */
+       "DNEG         ", /*             119 */
+       "ISHL         ", /*             120 */
+       "LSHL         ", /*             121 */
+       "ISHR         ", /*             122 */
+       "LSHR         ", /*             123 */
+       "IUSHR        ", /*             124 */
+       "LUSHR        ", /*             125 */
+       "IAND         ", /*             126 */
+       "LAND         ", /*             127 */
+       "IOR          ", /*             128 */
+       "LOR          ", /*             129 */
+       "IXOR         ", /*             130 */
+       "LXOR         ", /*             131 */
+       "IINC         ", /*             132 */
+       "I2L          ", /*             133 */
+       "I2F          ", /*             134 */
+       "I2D          ", /*             135 */
+       "L2I          ", /*             136 */
+       "L2F          ", /*             137 */
+       "L2D          ", /*             138 */
+       "F2I          ", /*             139 */
+       "F2L          ", /*             140 */
+       "F2D          ", /*             141 */
+       "D2I          ", /*             142 */
+       "D2L          ", /*             143 */
+       "D2F          ", /*             144 */
+       "INT2BYTE     ", /*             145 */
+       "INT2CHAR     ", /*             146 */
+       "INT2SHORT    ", /*             147 */
+       "LCMP         ", /*             148 */
+       "FCMPL        ", /*             149 */
+       "FCMPG        ", /*             150 */
+       "DCMPL        ", /*             151 */
+       "DCMPG        ", /*             152 */
+       "IFEQ         ", /*             153 */
+       "IFNE         ", /*             154 */
+       "IFLT         ", /*             155 */
+       "IFGE         ", /*             156 */
+       "IFGT         ", /*             157 */
+       "IFLE         ", /*             158 */
+       "IF_ICMPEQ    ", /*             159 */
+       "IF_ICMPNE    ", /*             160 */
+       "IF_ICMPLT    ", /*             161 */
+       "IF_ICMPGE    ", /*             162 */
+       "IF_ICMPGT    ", /*             163 */
+       "IF_ICMPLE    ", /*             164 */
+       "IF_ACMPEQ    ", /*             165 */
+       "IF_ACMPNE    ", /*             166 */
+       "GOTO         ", /*             167 */
+       "JSR          ", /*             168 */
+       "RET          ", /*             169 */
+       "TABLESWITCH  ", /*             170 */
+       "LOOKUPSWITCH ", /*             171 */
+       "IRETURN      ", /*             172 */
+       "LRETURN      ", /*             173 */
+       "FRETURN      ", /*             174 */
+       "DRETURN      ", /*             175 */
+       "ARETURN      ", /*             176 */
+       "RETURN       ", /*             177 */
+       "GETSTATIC    ", /*             178 */
+       "PUTSTATIC    ", /*             179 */
+       "GETFIELD     ", /*             180 */
+       "PUTFIELD     ", /*             181 */
+       "INVOKEVIRTUAL", /*             182 */
+       "INVOKESPECIAL", /*             183 */
+       "INVOKESTATIC ", /*             184 */
+       "INVOKEINTERFACE",/*            185 */
+       "CHECKASIZE   ", /* UNDEF186    186 */
+       "NEW          ", /*             187 */
+       "NEWARRAY     ", /*             188 */
+       "ANEWARRAY    ", /*             189 */
+       "ARRAYLENGTH  ", /*             190 */
+       "ATHROW       ", /*             191 */
+       "CHECKCAST    ", /*             192 */
+       "INSTANCEOF   ", /*             193 */
+       "MONITORENTER ", /*             194 */
+       "MONITOREXIT  ", /*             195 */
+       "UNDEF196     ", /* WIDE        196 */
+       "MULTIANEWARRAY",/*             197 */
+       "IFNULL       ", /*             198 */
+       "IFNONNULL    ", /*             199 */
+       "UNDEF200     ", /* GOTO_W      200 */
+       "UNDEF201     ", /* JSR_W       201 */
+       "UNDEF202     ", /* BREAKPOINT  202 */
+
+                             "UNDEF203","UNDEF204","UNDEF205",
+       "UNDEF206","UNDEF207","UNDEF208","UNDEF209","UNDEF210",
+       "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
+       "UNDEF216","UNDEF217","UNDEF218","UNDEF219","UNDEF220",
+       "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
+       "UNDEF226","UNDEF227","UNDEF228","UNDEF229","UNDEF230",
+       "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
+       "UNDEF236","UNDEF237","UNDEF238","UNDEF239","UNDEF240",
+       "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
+       "UNDEF246","UNDEF247","UNDEF248","UNDEF249","UNDEF250",
+       "UNDEF251","UNDEF252",
+       "BUILTIN3     ", /*             253 */
+       "BUILTIN2     ", /*             254 */
+       "BUILTIN1     "  /*             255 */
+    };
+
+
+
+/***************************** register types *********************************/
+
+#define REG_RES   0         /* reserved register for OS or code generator     */
+#define REG_RET   1         /* return value register                          */
+#define REG_EXC   2         /* exception value register                       */
+#define REG_SAV   3         /* (callee) saved register                        */
+#define REG_TMP   4         /* scratch temporary register (caller saved)      */
+#define REG_ARG   5         /* argument register (caller saved)               */
+
+#define REG_END   -1        /* last entry in tables                           */
+#define PARAMMODE_NUMBERED  0 
+#define PARAMMODE_STUFFED   1
+
+/***************************** register info block ****************************/
+
+extern int nregdescint[];   /* description of integer registers               */
+extern int nregdescfloat[]; /* description of floating point registers        */
+
+extern int nreg_parammode;
+
+void asm_handle_exception();
+void asm_handle_nat_exception();
+
+static void disassinstr (int c, int pos);       /* disassemble an instruction */
+static void disassemble (int *code, int len);   /* disassemble a code block   */
diff --git a/jit/mcode.c b/jit/mcode.c
new file mode 100644 (file)
index 0000000..ce46018
--- /dev/null
@@ -0,0 +1,346 @@
+/***************************** comp/mcode.c ************************************
+
+       Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+       See file COPYRIGHT for information on usage and disclaimer of warranties
+
+       This file is an include file for "compiler.c" . It contains (mostly)
+       architecture independent functions for writing instructions into the
+       code area and constants into the data area.
+
+       Authors: Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
+                Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
+       Changes: Micheal Gschwind    EMAIL: cacao@complang.tuwien.ac.at
+
+       Last Change: 1998/08/10
+
+
+       All functions assume the following code area / data area layout:
+
+       +-----------+
+       |           |
+       | code area | code area grows to higher addresses
+       |           |
+       +-----------+ <-- start of procedure
+       |           |
+       | data area | data area grows to lower addresses
+       |           |
+       +-----------+
+
+       The functions first write into a temporary code/data area allocated by
+       "mcode_init". "mcode_finish" copies the code and data area into permanent
+       memory. All functions writing values into the data area return the offset
+       relative the begin of the code area (start of procedure).       
+
+*******************************************************************************/
+
+#define MCODEINITSIZE (1<<15)       /* 32 Kbyte code area initialization size */
+#define DSEGINITSIZE  (1<<12)       /*  4 Kbyte data area initialization size */
+
+static u1* mcodebase = NULL;        /* base pointer of code area              */
+static s4* mcodeend  = NULL;        /* pointer to end of code area            */
+static int mcodesize;               /* complete size of code area (bytes)     */
+
+static u1* dsegtop = NULL;          /* pointer to top (end) of data area      */
+static int dsegsize;                /* complete size of data area (bytes)     */
+static int dseglen;                 /* used size of data area (bytes)         */
+                                    /* data area grows from top to bottom     */
+
+static jumpref *jumpreferences;     /* list of jumptable target addresses     */
+static branchref *xboundrefs;       /* list of bound check branches           */
+static branchref *xcheckarefs;      /* list of array size check branches      */
+static branchref *xnullrefs;        /* list of null check branches            */
+static branchref *xcastrefs;        /* list of cast check branches            */
+
+static void mcode_init();           /* allocates code and data area           */
+static void mcode_close();          /* releases temporary storage             */
+static void mcode_finish();         /* makes code and data area permanent and */
+                                    /* updates branch references to code/data */
+
+static s4 dseg_adds4(s4 value);         /* adds an int to data area           */
+static s4 dseg_adds8(s8 value);         /* adds an long to data area          */
+static s4 dseg_addfloat (float value);  /* adds an float to data area         */
+static s4 dseg_adddouble(double value); /* adds an double to data area        */
+
+#if POINTERSIZE==8
+#define dseg_addaddress(value)      dseg_adds8((s8)(value))
+#else
+#define dseg_addaddress(value)      dseg_adds4((s4)(value))
+#endif
+
+static void dseg_addtarget(basicblock *target);
+static void mcode_addreference(basicblock *target, void *branchptr);
+static void mcode_addxboundrefs(void *branchptr);
+static void mcode_addxnullrefs(void *branchptr);
+static void mcode_addxcastrefs(void *branchptr);
+
+static void dseg_display(s4 *s4ptr);
+
+/* mcode_init allocates and initialises code area, data area and references   */
+
+static void mcode_init()
+{
+       if (!mcodebase) {
+               mcodebase = MNEW (u1, MCODEINITSIZE);
+               mcodesize = MCODEINITSIZE;
+               }
+
+       if (!dsegtop) {
+               dsegtop = MNEW (u1, DSEGINITSIZE);
+               dsegsize = DSEGINITSIZE;
+               dsegtop += dsegsize;
+               }
+
+       dseglen = 0;
+
+       jumpreferences = NULL;
+       xboundrefs = NULL;
+       xnullrefs = NULL;
+       xcastrefs = NULL;
+}
+
+
+/* mcode_close releases temporary code and data area                          */
+
+static void mcode_close()
+{
+       if (mcodebase) {
+               MFREE (mcodebase, u1, mcodesize);
+               mcodebase = NULL;
+               }
+       if (dsegtop) {
+               MFREE (dsegtop - dsegsize, u1, dsegsize);
+               dsegtop = NULL;
+               }
+}
+
+
+/* mcode_increase doubles code area                                           */
+
+static s4 *mcode_increase(u1 *codeptr)
+{
+       long len;
+
+       len = codeptr - mcodebase;
+       mcodebase = MREALLOC(mcodebase, u1, mcodesize, mcodesize * 2);
+       mcodesize *= 2;
+       mcodeend = (s4*) (mcodebase + mcodesize);
+       return (s4*) (mcodebase + len);
+}
+
+
+/* desg_increase doubles data area                                            */
+
+static void dseg_increase() {
+       u1 *newstorage = MNEW (u1, dsegsize * 2);
+       memcpy ( newstorage + dsegsize, dsegtop - dsegsize, dsegsize);
+       MFREE (dsegtop - dsegsize, u1, dsegsize);
+       dsegtop = newstorage;
+       dsegsize *= 2;
+       dsegtop += dsegsize;
+}
+
+
+static s4 dseg_adds4_increase(s4 value)
+{
+       dseg_increase();
+       *((s4 *) (dsegtop - dseglen)) = value;
+       return -dseglen;
+}
+
+
+static s4 dseg_adds4(s4 value)
+{
+       s4 *dataptr;
+
+       dseglen += 4;
+       dataptr = (s4 *) (dsegtop - dseglen);
+       if (dseglen > dsegsize)
+               return dseg_adds4_increase(value);
+       *dataptr = value;
+       return -dseglen;
+}
+
+
+static s4 dseg_adds8_increase(s8 value)
+{
+       dseg_increase();
+       *((s8 *) (dsegtop - dseglen)) = value;
+       return -dseglen;
+}
+
+
+static s4 dseg_adds8(s8 value)
+{
+       s8 *dataptr;
+
+       dseglen = ALIGN (dseglen + 8, 8);
+       dataptr = (s8 *) (dsegtop - dseglen);
+       if (dseglen > dsegsize)
+               return dseg_adds8_increase(value);
+       *dataptr = value;
+       return -dseglen;
+}
+
+
+static s4 dseg_addfloat_increase(float value)
+{
+       dseg_increase();
+       *((float *) (dsegtop - dseglen)) = value;
+       return -dseglen;
+}
+
+
+static s4 dseg_addfloat(float value)
+{
+       float *dataptr;
+
+       dseglen += 4;
+       dataptr = (float *) (dsegtop - dseglen);
+       if (dseglen > dsegsize)
+               return dseg_addfloat_increase(value);
+       *dataptr = value;
+       return -dseglen;
+}
+
+
+static s4 dseg_adddouble_increase(double value)
+{
+       dseg_increase();
+       *((double *) (dsegtop - dseglen)) = value;
+       return -dseglen;
+}
+
+
+static s4 dseg_adddouble(double value)
+{
+       double *dataptr;
+
+       dseglen = ALIGN (dseglen + 8, 8);
+       dataptr = (double *) (dsegtop - dseglen);
+       if (dseglen > dsegsize)
+               return dseg_adddouble_increase(value);
+       *dataptr = value;
+       return -dseglen;
+}
+
+
+static void dseg_addtarget(basicblock *target)
+{
+       jumpref *jr = DNEW(jumpref);
+
+       jr->tablepos = dseg_addaddress(NULL);
+       jr->target = target;
+       jr->next = jumpreferences;
+       jumpreferences = jr;
+}
+
+
+static void mcode_addreference(basicblock *target, void *branchptr)
+{
+       s4 branchpos = (u1*) branchptr - mcodebase;
+
+       if (target->mpc >= 0) {
+               gen_resolvebranch((u1*) mcodebase + branchpos, branchpos, target->mpc);
+               }
+       else {
+               branchref *br = DNEW(branchref);
+
+               br->branchpos = branchpos;
+               br->next = target->branchrefs;
+               target->branchrefs= br;
+               }
+}
+
+
+static void mcode_addxboundrefs(void *branchptr)
+{
+       s4 branchpos = (u1*) branchptr - mcodebase;
+
+       branchref *br = DNEW(branchref);
+
+       br->branchpos = branchpos;
+       br->next = xboundrefs;
+       xboundrefs = br;
+}
+
+
+static void mcode_addxcheckarefs(void *branchptr)
+{
+       s4 branchpos = (u1*) branchptr - mcodebase;
+
+       branchref *br = DNEW(branchref);
+
+       br->branchpos = branchpos;
+       br->next = xcheckarefs;
+       xcheckarefs = br;
+}
+
+
+static void mcode_addxnullrefs(void *branchptr)
+{
+       s4 branchpos = (u1*) branchptr - mcodebase;
+
+       branchref *br = DNEW(branchref);
+
+       br->branchpos = branchpos;
+       br->next = xnullrefs;
+       xnullrefs = br;
+}
+
+
+static void mcode_addxcastrefs(void *branchptr)
+{
+       s4 branchpos = (u1*) branchptr - mcodebase;
+
+       branchref *br = DNEW(branchref);
+
+       br->branchpos = branchpos;
+       br->next = xcastrefs;
+       xcastrefs = br;
+}
+
+
+static void mcode_finish(int mcodelen)
+{
+       jumpref *jr;
+       u1 *epoint;
+
+       count_code_len += mcodelen;
+       count_data_len += dseglen;
+
+       dseglen = ALIGN(dseglen, MAX_ALIGN);
+
+       method -> mcodelength = mcodelen + dseglen;
+       method -> mcode = CNEW(u1, mcodelen + dseglen);
+
+       memcpy ( method->mcode, dsegtop - dseglen, dseglen);
+       memcpy ( method->mcode + dseglen, mcodebase, mcodelen);
+
+       method -> entrypoint = epoint = (u1*) (method->mcode + dseglen);
+
+       /* jump table resolving */
+
+       jr = jumpreferences;
+       while (jr != NULL) {
+               *((void**) (epoint + jr->tablepos)) = epoint + jr->target->mpc;
+               jr = jr->next;
+               }
+
+#ifdef CACHE_FLUSH_BLOCK
+       synchronize_caches(method->mcode, (mcodelen>>2));
+#endif
+       
+}
+
+
+static void dseg_display(s4 *s4ptr)
+{
+       int i;
+       
+       printf("  --- dump of datasegment\n");
+       for (i = dseglen; i > 0 ; i -= 4) {
+               printf("-%6x: %8x\n", i, (int)(*s4ptr++));
+               }
+       printf("  --- begin of data segment: %p\n", s4ptr);
+}
diff --git a/jit/parse.c b/jit/parse.c
new file mode 100644 (file)
index 0000000..269db06
--- /dev/null
@@ -0,0 +1,1120 @@
+/* jit/parse.c *****************************************************************
+
+       Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+       See file COPYRIGHT for information on usage and disclaimer of warranties
+
+       Parser for JavaVM to intermediate code translation
+       
+       Author: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
+
+       Last Change: 1998/05/07
+
+*******************************************************************************/
+
+#include "math.h"
+
+
+/* macros for byte code fetching ***********************************************
+
+       fetch a byte code of given size from position pos
+
+*******************************************************************************/
+
+#define code_get_u1(pos)    jcode[pos]
+#define code_get_s1(pos)    ((s1)jcode[pos])
+#define code_get_u2(pos)    ((((u2)jcode[pos])<<8)+jcode[pos+1])
+#define code_get_s2(pos)    ((s2)((((u2)jcode[pos])<<8)+jcode[pos+1]))
+#define code_get_u4(pos)    ((((u4)jcode[pos])<<24)+(((u4)jcode[pos+1])<<16)+\
+                             (((u4)jcode[pos+2])<<8)+jcode[pos+3])
+#define code_get_s4(pos)    ((s4)((((u4)jcode[pos])<<24)+(((u4)jcode[pos+1])<<16)+\
+                             (((u4)jcode[pos+2])<<8)+jcode[pos+3]))
+
+
+/* functionc compiler_addinitclass *********************************************
+
+       add class into the list of classes to initialize
+
+*******************************************************************************/
+                                
+static void compiler_addinitclass (classinfo *c)
+{
+       classinfo *cl;
+
+       if (c->initialized) return;
+       
+       cl = chain_first(uninitializedclasses);
+       if (cl == c)
+               return;
+       
+       if (cl == class)
+               cl = chain_next(uninitializedclasses);
+       for (;;) {
+               if (cl == c)
+                       return;
+               if (cl == NULL) {
+                       if (runverbose) {
+                               sprintf(logtext, "compiler_addinitclass: ");
+                               unicode_sprint(logtext+strlen(logtext), c->name);
+                               dolog();
+                               }
+                       chain_addlast(uninitializedclasses, c);
+                       return;
+                       }
+               if (c < cl) {
+                       if (runverbose) {
+                               sprintf(logtext, "compiler_addinitclass: ");
+                               unicode_sprint(logtext+strlen(logtext), c->name);
+                               dolog();
+                               }
+                       chain_addbefore(uninitializedclasses, c);
+                       return;
+                       }
+               cl = chain_next(uninitializedclasses);
+               }
+}                       
+
+
+/* function descriptor2types ***************************************************
+
+       decodes a already checked method descriptor. The parameter count, the
+       return type and the argument types are stored in the passed methodinfo.
+
+*******************************************************************************/               
+
+static void descriptor2types (methodinfo *m)
+{
+       u1 *types, *tptr;
+       int pcount, c;
+       u2 *cptr;
+
+       pcount = 0;
+       types = DMNEW (u1, m->descriptor->length);
+       
+       tptr = types;
+       if (!(m->flags & ACC_STATIC)) {
+               *tptr++ = TYPE_ADR;
+               pcount++;
+               }
+
+       cptr = m->descriptor->text;
+       cptr++;
+       while ((c = *cptr++) != ')') {
+               pcount++;
+               switch (c) {
+                       case 'B':
+                       case 'C':
+                       case 'I':
+                       case 'S':
+                       case 'Z':  *tptr++ = TYPE_INT;
+                                  break;
+                       case 'J':  *tptr++ = TYPE_LNG;
+                                  break;
+                       case 'F':  *tptr++ = TYPE_FLT;
+                                  break;
+                       case 'D':  *tptr++ = TYPE_DBL;
+                                  break;
+                       case 'L':  *tptr++ = TYPE_ADR;
+                                  while (*cptr++ != ';');
+                                  break;
+                       case '[':  *tptr++ = TYPE_ADR;
+                                  while (c == '[')
+                                      c = *cptr++;
+                                  if (c == 'L')
+                                      while (*cptr++ != ';') /* skip */;
+                                  break;
+                       default:   panic ("Ill formed methodtype-descriptor");
+                       }
+               }
+
+       /* compute return type */
+
+       switch (*cptr) {
+               case 'B':
+               case 'C':
+               case 'I':
+               case 'S':
+               case 'Z':  m->returntype = TYPE_INT;
+                          break;
+               case 'J':  m->returntype = TYPE_LNG;
+                          break;
+               case 'F':  m->returntype = TYPE_FLT;
+                          break;
+               case 'D':  m->returntype = TYPE_DBL;
+                          break;
+               case '[':
+               case 'L':  m->returntype = TYPE_ADR;
+                          break;
+               case 'V':  m->returntype = TYPE_VOID;
+                          break;
+
+               default:   panic ("Ill formed methodtype-descriptor");
+               }
+
+       m->paramcount = pcount;
+       m->paramtypes = types;
+}
+
+
+/* function allocate_literals **************************************************
+
+       Scans the JavaVM code of a method and allocates string literals. Needed
+       to generate the same addresses as the old JIT compiler.
+       
+*******************************************************************************/
+
+static void allocate_literals()
+{
+       int     p, nextp;
+       int     opcode, i;
+       s4      num;
+       unicode *s;
+
+       for (p = 0; p < jcodelength; p = nextp) {
+
+               opcode = jcode[p];
+               nextp = p + jcommandsize[opcode];
+
+               switch (opcode) {
+                       case JAVA_WIDE:
+                               if (code_get_u1(p + 1) == JAVA_IINC)
+                                       nextp = p + 6;
+                               else
+                                       nextp = p + 4;
+                               break;
+                                                       
+                       case JAVA_LOOKUPSWITCH:
+                               nextp = ALIGN((p + 1), 4);
+                               num = code_get_u4(nextp + 4);
+                               nextp = nextp + 8 + 8 * num;
+                               break;
+
+                       case JAVA_TABLESWITCH:
+                               nextp = ALIGN ((p + 1),4);
+                               num = code_get_s4(nextp + 4);
+                               num = code_get_s4(nextp + 8) - num;
+                               nextp = nextp + 16 + 4 * num;
+                               break;
+
+                       case JAVA_LDC1:
+                               i = code_get_u1(p+1);
+                               goto pushconstantitem;
+                       case JAVA_LDC2:
+                       case JAVA_LDC2W:
+                               i = code_get_u2(p + 1);
+                       pushconstantitem:
+                               if (class_constanttype(class, i) == CONSTANT_String) {
+                                       s = class_getconstant(class, i, CONSTANT_String);
+                                       (void) literalstring_new(s);
+                                       }
+                               break;
+                       } /* end switch */
+               } /* end while */
+}
+
+
+
+/*******************************************************************************
+
+       function 'parse' scans the JavaVM code and generates intermediate code
+
+       During parsing the block index table is used to store at bit pos 0
+       a flag which marks basic block starts and at position 1 to 31 the
+       intermediate instruction index. After parsing the block index table
+       is scanned, for marked positions a block is generated and the block
+       number is stored in the block index table.
+
+*******************************************************************************/
+
+/* intermediate code generating macros */
+
+#define PINC           iptr++;ipc++
+#define LOADCONST_I(v) iptr->opc=ICMD_ICONST;iptr->op1=0;iptr->val.i=(v);PINC
+#define LOADCONST_L(v) iptr->opc=ICMD_LCONST;iptr->op1=0;iptr->val.l=(v);PINC
+#define LOADCONST_F(v) iptr->opc=ICMD_FCONST;iptr->op1=0;iptr->val.f=(v);PINC
+#define LOADCONST_D(v) iptr->opc=ICMD_DCONST;iptr->op1=0;iptr->val.d=(v);PINC
+#define LOADCONST_A(v) iptr->opc=ICMD_ACONST;iptr->op1=0;iptr->val.a=(v);PINC
+#define OP(o)          iptr->opc=(o);iptr->op1=0;iptr->val.l=0;PINC
+#define OP1(o,o1)      iptr->opc=(o);iptr->op1=(o1);iptr->val.l=(0);PINC
+#define OP2I(o,o1,v)   iptr->opc=(o);iptr->op1=(o1);iptr->val.i=(v);PINC
+#define OP2A(o,o1,v)   iptr->opc=(o);iptr->op1=(o1);iptr->val.a=(v);PINC
+#define BUILTIN1(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN1;iptr->op1=t;\
+                       iptr->val.a=(v);PINC
+#define BUILTIN2(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN2;iptr->op1=t;\
+                       iptr->val.a=(v);PINC
+#define BUILTIN3(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN3;iptr->op1=t;\
+                       iptr->val.a=(v);PINC
+
+
+/* block generating and checking macros */
+
+#define block_insert(i)    {if(!(block_index[i]&1))\
+                               {b_count++;block_index[i] |= 1;}}
+#define bound_check(i)     {if((i< 0) || (i>=jcodelength)) \
+                               panic("branch target out of code-boundary");}
+#define bound_check1(i)    {if((i< 0) || (i>jcodelength)) \
+                               panic("branch target out of code-boundary");}
+
+
+static void parse()
+{
+       int  p;                     /* java instruction counter                   */
+       int  nextp;                 /* start of next java instruction             */
+       int  opcode;                /* java opcode                                */
+       int  i;                     /* temporary for different uses (counters)    */
+       int  ipc = 0;               /* intermediate instruction counter           */
+       int  b_count = 0;           /* basic block counter                        */
+       int  s_count = 0;           /* stack element counter                      */
+       bool blockend = false;      /* true if basic block end has reached        */
+       bool iswide = false;        /* true if last instruction was a wide        */
+       instruction *iptr;          /* current pointer into instruction array     */
+
+
+       /* allocate instruction array and block index table */
+       
+       /* 1 additional for end ipc and 3 for loop unrolling */
+       
+       block_index = DMNEW(int, jcodelength + 3);
+
+       /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
+       /* additional MONITOREXITS are reached by branches which are 3 bytes */
+       
+       iptr = instr = DMNEW(instruction, jcodelength + 5);
+       
+       /* initialize block_index table (unrolled four times) */
+
+       {
+       int *ip;
+       
+       for (i = 0, ip = block_index; i <= jcodelength; i += 4, ip += 4) {
+               ip[0] = 0;
+               ip[1] = 0;
+               ip[2] = 0;
+               ip[3] = 0;
+               }
+       }
+
+       /* compute branch targets of exception table */
+
+       for (i = 0; i < exceptiontablelength; i++) {
+               p = extable[i].startpc;
+               bound_check(p);
+               block_insert(p);
+               p = extable[i].endpc;
+               bound_check1(p);
+               if (p < jcodelength)
+                       block_insert(p);
+               p = extable[i].handlerpc;
+               bound_check(p);
+               block_insert(p);
+               }
+
+       s_count = 1 + exceptiontablelength; /* initialize stack element counter   */
+
+       if (runverbose) {
+/*             isleafmethod=false; */
+               }
+
+#ifdef USE_THREADS
+       if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
+               isleafmethod=false;
+               }                       
+#endif
+
+       /* scan all java instructions */
+
+       for (p = 0; p < jcodelength; p = nextp) {
+
+               opcode = code_get_u1 (p);           /* fetch op code                  */
+
+               block_index[p] |= (ipc << 1);       /* store intermediate count       */
+
+               if (blockend) {
+                       block_insert(p);                /* start new block                */
+                       blockend = false;
+                       }
+
+               nextp = p + jcommandsize[opcode];   /* compute next instruction start */
+               s_count += stackreq[opcode];            /* compute stack element count    */
+
+               switch (opcode) {
+
+                       case JAVA_NOP:
+                               break;
+
+                       /* pushing constants onto the stack p */
+
+                       case JAVA_BIPUSH:
+                               LOADCONST_I(code_get_s1(p+1));
+                               break;
+
+                       case JAVA_SIPUSH:
+                               LOADCONST_I(code_get_s2(p+1));
+                               break;
+
+                       case JAVA_LDC1:
+                               i = code_get_u1(p+1);
+                               goto pushconstantitem;
+                       case JAVA_LDC2:
+                       case JAVA_LDC2W:
+                               i = code_get_u2(p + 1);
+
+                       pushconstantitem:
+
+                               if (i >= class->cpcount) 
+                                       panic ("Attempt to access constant outside range");
+
+                               switch (class->cptags[i]) {
+                                       case CONSTANT_Integer:
+                                               LOADCONST_I(((constant_integer*)
+                                                            (class->cpinfos[i]))->value);
+                                               break;
+                                       case CONSTANT_Long:
+                                               LOADCONST_L(((constant_long*)
+                                                            (class->cpinfos[i]))->value);
+                                               break;
+                                       case CONSTANT_Float:
+                                               LOADCONST_F(((constant_float*)
+                                                            (class->cpinfos[i]))->value);
+                                               break;
+                                       case CONSTANT_Double:
+                                               LOADCONST_D(((constant_double*)
+                                                            (class->cpinfos[i]))->value);
+                                               break;
+                                       case CONSTANT_String:
+                                               LOADCONST_A(literalstring_new((unicode*)
+                                                                             (class->cpinfos[i])));
+                                               break;
+                                       default: panic("Invalid constant type to push");
+                                       }
+                               break;
+
+                       case JAVA_ACONST_NULL:
+                               LOADCONST_A(NULL);
+                               break;
+
+                       case JAVA_ICONST_M1:
+                       case JAVA_ICONST_0:
+                       case JAVA_ICONST_1:
+                       case JAVA_ICONST_2:
+                       case JAVA_ICONST_3:
+                       case JAVA_ICONST_4:
+                       case JAVA_ICONST_5:
+                               LOADCONST_I(opcode - JAVA_ICONST_0);
+                               break;
+
+                       case JAVA_LCONST_0:
+                       case JAVA_LCONST_1:
+                               LOADCONST_L(opcode - JAVA_LCONST_0);
+                               break;
+
+                       case JAVA_FCONST_0:
+                       case JAVA_FCONST_1:
+                       case JAVA_FCONST_2:
+                               LOADCONST_F(opcode - JAVA_FCONST_0);
+                               break;
+
+                       case JAVA_DCONST_0:
+                       case JAVA_DCONST_1:
+                               LOADCONST_D(opcode - JAVA_DCONST_0);
+                               break;
+
+                       /* loading variables onto the stack */
+
+                       case JAVA_ILOAD:
+                       case JAVA_LLOAD:
+                       case JAVA_FLOAD:
+                       case JAVA_DLOAD:
+                       case JAVA_ALOAD:
+                               if (!iswide)
+                                       i = code_get_u1(p+1);
+                               else {
+                                       i = code_get_u2(p+1);
+                                       nextp = p+3;
+                                       iswide = false;
+                                       }
+                               OP1(opcode, i);
+                               break;
+
+                       case JAVA_ILOAD_0:
+                       case JAVA_ILOAD_1:
+                       case JAVA_ILOAD_2:
+                       case JAVA_ILOAD_3:
+                               OP1(ICMD_ILOAD, opcode - JAVA_ILOAD_0);
+                               break;
+
+                       case JAVA_LLOAD_0:
+                       case JAVA_LLOAD_1:
+                       case JAVA_LLOAD_2:
+                       case JAVA_LLOAD_3:
+                               OP1(ICMD_LLOAD, opcode - JAVA_LLOAD_0);
+                               break;
+
+                       case JAVA_FLOAD_0:
+                       case JAVA_FLOAD_1:
+                       case JAVA_FLOAD_2:
+                       case JAVA_FLOAD_3:
+                               OP1(ICMD_FLOAD, opcode - JAVA_FLOAD_0);
+                               break;
+
+                       case JAVA_DLOAD_0:
+                       case JAVA_DLOAD_1:
+                       case JAVA_DLOAD_2:
+                       case JAVA_DLOAD_3:
+                               OP1(ICMD_DLOAD, opcode - JAVA_DLOAD_0);
+                               break;
+
+                       case JAVA_ALOAD_0:
+                       case JAVA_ALOAD_1:
+                       case JAVA_ALOAD_2:
+                       case JAVA_ALOAD_3:
+                               OP1(ICMD_ALOAD, opcode - JAVA_ALOAD_0);
+                               break;
+
+                       /* storing stack values into local variables */
+
+                       case JAVA_ISTORE:
+                       case JAVA_LSTORE:
+                       case JAVA_FSTORE:
+                       case JAVA_DSTORE:
+                       case JAVA_ASTORE:
+                               if (!iswide)
+                                       i = code_get_u1(p+1);
+                               else {
+                                       i = code_get_u2(p+1);
+                                       iswide=false;
+                                       nextp = p+3;
+                                       }
+                               OP1(opcode, i);
+                               break;
+
+                       case JAVA_ISTORE_0:
+                       case JAVA_ISTORE_1:
+                       case JAVA_ISTORE_2:
+                       case JAVA_ISTORE_3:
+                               OP1(ICMD_ISTORE, opcode - JAVA_ISTORE_0);
+                               break;
+
+                       case JAVA_LSTORE_0:
+                       case JAVA_LSTORE_1:
+                       case JAVA_LSTORE_2:
+                       case JAVA_LSTORE_3:
+                               OP1(ICMD_LSTORE, opcode - JAVA_LSTORE_0);
+                               break;
+
+                       case JAVA_FSTORE_0:
+                       case JAVA_FSTORE_1:
+                       case JAVA_FSTORE_2:
+                       case JAVA_FSTORE_3:
+                               OP1(ICMD_FSTORE, opcode - JAVA_FSTORE_0);
+                               break;
+
+                       case JAVA_DSTORE_0:
+                       case JAVA_DSTORE_1:
+                       case JAVA_DSTORE_2:
+                       case JAVA_DSTORE_3:
+                               OP1(ICMD_DSTORE, opcode - JAVA_DSTORE_0);
+                               break;
+
+                       case JAVA_ASTORE_0:
+                       case JAVA_ASTORE_1:
+                       case JAVA_ASTORE_2:
+                       case JAVA_ASTORE_3:
+                               OP1(ICMD_ASTORE, opcode - JAVA_ASTORE_0);
+                               break;
+
+                       case JAVA_IINC:
+                               {
+                               int v;
+                               
+                               if (!iswide) {
+                                       i = code_get_u1(p + 1);
+                                       v = code_get_s1(p + 2);
+                                       }
+                               else {
+                                       i = code_get_u2(p + 1);
+                                       v = code_get_s2(p + 3);
+                                       iswide = false;
+                                       nextp = p+5;
+                                       }
+                               OP2I(opcode, i, v);
+                               }
+                               break;
+
+                       /* wider index for loading, storing and incrementing */
+
+                       case JAVA_WIDE:
+                               iswide = true;
+                               nextp = p + 1;
+                               break;
+
+                       /* managing arrays ************************************************/
+
+                       case JAVA_NEWARRAY:
+                               OP2I(ICMD_CHECKASIZE, 0, 0);
+                               switch (code_get_s1(p+1)) {
+                                       case 4:
+                                               BUILTIN1((functionptr)builtin_newarray_boolean, TYPE_ADR);
+                                               break;
+                                       case 5:
+                                               BUILTIN1((functionptr)builtin_newarray_char, TYPE_ADR);
+                                               break;
+                                       case 6:
+                                               BUILTIN1((functionptr)builtin_newarray_float, TYPE_ADR);
+                                               break;
+                                       case 7:
+                                               BUILTIN1((functionptr)builtin_newarray_double, TYPE_ADR);
+                                               break;
+                                       case 8:
+                                               BUILTIN1((functionptr)builtin_newarray_byte, TYPE_ADR);
+                                               break;
+                                       case 9:
+                                               BUILTIN1((functionptr)builtin_newarray_short, TYPE_ADR);
+                                               break;
+                                       case 10:
+                                               BUILTIN1((functionptr)builtin_newarray_int, TYPE_ADR);
+                                               break;
+                                       case 11:
+                                               BUILTIN1((functionptr)builtin_newarray_long, TYPE_ADR);
+                                               break;
+                                       default: panic("Invalid array-type to create");
+                                       }
+                               break;
+
+                       case JAVA_ANEWARRAY:
+                               OP2I(ICMD_CHECKASIZE, 0, 0);
+                               i = code_get_u2(p+1);
+                               /* array or class type ? */
+                               if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
+                                       LOADCONST_A(class_getconstant(class, i,
+                                                                     CONSTANT_Arraydescriptor));
+                                       BUILTIN2((functionptr)builtin_newarray_array, TYPE_ADR);
+                                       }
+                               else {
+                                       LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+                                       BUILTIN2((functionptr)builtin_anewarray, TYPE_ADR);
+                                       }
+                               break;
+
+                       case JAVA_MULTIANEWARRAY:
+                               isleafmethod=false;
+                               i = code_get_u2(p+1);
+                               {
+                               int v = code_get_u1(p+3);
+                               constant_arraydescriptor *desc =
+                                   class_getconstant (class, i, CONSTANT_Arraydescriptor);
+                               OP2A(opcode, v, desc);
+                               }
+                               break;
+
+                       case JAVA_IFEQ:
+                       case JAVA_IFLT:
+                       case JAVA_IFLE:
+                       case JAVA_IFNE:
+                       case JAVA_IFGT:
+                       case JAVA_IFGE:
+                       case JAVA_IFNULL:
+                       case JAVA_IFNONNULL:
+                       case JAVA_IF_ICMPEQ:
+                       case JAVA_IF_ICMPNE:
+                       case JAVA_IF_ICMPLT:
+                       case JAVA_IF_ICMPGT:
+                       case JAVA_IF_ICMPLE:
+                       case JAVA_IF_ICMPGE:
+                       case JAVA_IF_ACMPEQ:
+                       case JAVA_IF_ACMPNE:
+                       case JAVA_GOTO:
+                       case JAVA_JSR:
+                               i = p + code_get_s2(p+1);
+                               bound_check(i);
+                               block_insert(i);
+                               blockend = true;
+                               OP1(opcode, i);
+                               break;
+                       case JAVA_GOTO_W:
+                       case JAVA_JSR_W:
+                               i = p + code_get_s4(p+1);
+                               bound_check(i);
+                               block_insert(i);
+                               blockend = true;
+                               OP1(opcode, i);
+                               break;
+
+                       case JAVA_RET:
+                               if (!iswide)
+                                       i = code_get_u1(p+1);
+                               else {
+                                       i = code_get_u2(p+1);
+                                       nextp = p+3;
+                                       iswide = false;
+                                       }
+                               blockend = true;
+                               OP1(opcode, i);
+                               break;
+
+                       case JAVA_IRETURN:
+                       case JAVA_LRETURN:
+                       case JAVA_FRETURN:
+                       case JAVA_DRETURN:
+                       case JAVA_ARETURN:
+                       case JAVA_RETURN:
+                               blockend = true;
+                               OP(opcode);
+                               break;
+
+                       case JAVA_ATHROW:
+                               blockend = true;
+                               OP(opcode);
+                               break;
+                               
+
+                       /* table jumps ********************************/
+
+                       case JAVA_LOOKUPSWITCH:
+                               {
+                               s4 num, j;
+
+                               blockend = true;
+                               nextp = ALIGN((p + 1), 4);
+                               OP2A(opcode, 0, jcode + nextp);
+
+                               /* default target */
+
+                               j =  p + code_get_s4(nextp);
+                               *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
+                               nextp += 4;
+                               bound_check(j);
+                               block_insert(j);
+
+                               /* number of pairs */
+
+                               num = code_get_u4(nextp);
+                               *((s4*)(jcode + nextp)) = num;
+                               nextp += 4;
+
+                               for (i = 0; i < num; i++) {
+
+                                       /* value */
+
+                                       j = code_get_s4(nextp);
+                                       *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+                                       nextp += 4;
+
+                                       /* target */
+
+                                       j = p + code_get_s4(nextp);
+                                       *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+                                       nextp += 4;
+                                       bound_check(j);
+                                       block_insert(j);
+                                       }
+
+                               break;
+                               }
+
+
+                       case JAVA_TABLESWITCH:
+                               {
+                               s4 num, j;
+
+                               blockend = true;
+                               nextp = ALIGN((p + 1), 4);
+                               OP2A(opcode, 0, jcode + nextp);
+
+                               /* default target */
+
+                               j = p + code_get_s4(nextp);
+                               *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
+                               nextp += 4;
+                               bound_check(j);
+                               block_insert(j);
+
+                               /* lower bound */
+
+                               j = code_get_s4(nextp);
+                               *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
+                               nextp += 4;
+
+                               /* upper bound */
+
+                               num = code_get_s4(nextp);
+                               *((s4*)(jcode + nextp)) = num;   /* restore for little endian */
+                               nextp += 4;
+
+                               num -= j;
+
+                               for (i = 0; i <= num; i++) {
+                                       j = p + code_get_s4(nextp);
+                                       *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+                                       nextp += 4;
+                                       bound_check(j);
+                                       block_insert(j);
+                                       }
+
+                               break;
+                               }
+
+
+                       /* load and store of object fields *******************/
+
+                       case JAVA_AASTORE:
+                               BUILTIN3((functionptr) asm_builtin_aastore, TYPE_VOID);
+                               break;
+
+                       case JAVA_PUTSTATIC:
+                       case JAVA_GETSTATIC:
+                               i = code_get_u2(p + 1);
+                               {
+                               constant_FMIref *fr;
+                               fieldinfo *fi;
+                               fr = class_getconstant (class, i, CONSTANT_Fieldref);
+                               fi = class_findfield (fr->class, fr->name, fr->descriptor);
+                               compiler_addinitclass (fr->class);
+                               OP2A(opcode, fi->type, fi);
+                               }
+                               break;
+                       case JAVA_PUTFIELD:
+                       case JAVA_GETFIELD:
+                               i = code_get_u2(p + 1);
+                               {
+                               constant_FMIref *fr;
+                               fieldinfo *fi;
+                               fr = class_getconstant (class, i, CONSTANT_Fieldref);
+                               fi = class_findfield (fr->class, fr->name, fr->descriptor);
+                               OP2A(opcode, fi->type, fi);
+                               }
+                               break;
+
+
+                       /* method invocation *****/
+
+                       case JAVA_INVOKESTATIC:
+                               i = code_get_u2(p + 1);
+                               {
+                               constant_FMIref *mr;
+                               methodinfo *mi;
+                               
+                               mr = class_getconstant (class, i, CONSTANT_Methodref);
+                               mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+                               if (! (mi->flags & ACC_STATIC))
+                                       panic ("Static/Nonstatic mismatch calling static method");
+                               descriptor2types(mi);
+                               isleafmethod=false;
+                               OP2A(opcode, mi->paramcount, mi);
+                               }
+                               break;
+                       case JAVA_INVOKESPECIAL:
+                       case JAVA_INVOKEVIRTUAL:
+                               i = code_get_u2(p + 1);
+                               {
+                               constant_FMIref *mr;
+                               methodinfo *mi;
+                               
+                               mr = class_getconstant (class, i, CONSTANT_Methodref);
+                               mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+                               if (mi->flags & ACC_STATIC)
+                                       panic ("Static/Nonstatic mismatch calling static method");
+                               descriptor2types(mi);
+                               isleafmethod=false;
+                               OP2A(opcode, mi->paramcount, mi);
+                               }
+                               break;
+                       case JAVA_INVOKEINTERFACE:
+                               i = code_get_u2(p + 1);
+                               {
+                               constant_FMIref *mr;
+                               methodinfo *mi;
+                               
+                               mr = class_getconstant (class, i, CONSTANT_InterfaceMethodref);
+                               mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+                               if (mi->flags & ACC_STATIC)
+                                       panic ("Static/Nonstatic mismatch calling static method");
+                               descriptor2types(mi);
+                               isleafmethod=false;
+                               OP2A(opcode, mi->paramcount, mi);
+                               }
+                               break;
+
+                       /* miscellaneous object operations *******/
+
+                       case JAVA_NEW:
+                               i = code_get_u2 (p+1);
+                               LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+                               BUILTIN1((functionptr) builtin_new, TYPE_ADR);
+                               break;
+
+                       case JAVA_CHECKCAST:
+                               i = code_get_u2(p+1);
+
+                               /* array type cast-check */
+                               if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
+                                       LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
+                                       BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
+                                       }
+                               else { /* object type cast-check */
+                                       OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
+                                       }
+                               break;
+
+                       case JAVA_INSTANCEOF:
+                               i = code_get_u2(p+1);
+
+                               /* array type cast-check */
+                               if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
+                                       LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
+                                       BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
+                                       }
+                               else { /* object type cast-check */
+                                       OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
+                                       }
+                               break;
+
+                       case JAVA_MONITORENTER:
+#ifdef USE_THREADS
+                               if (checksync) {
+#ifdef SOFTNULLPTRCHECK
+                                       if (checknull) {
+                                               BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+                                               }
+                                       else {
+/*                                             BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID); */
+                                               BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+                                               }
+#else
+                                       BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
+#endif
+                                       }
+                               else
+#endif
+                                       {
+                                       OP(ICMD_NULLCHECKPOP);
+                                       }
+                               break;
+
+                       case JAVA_MONITOREXIT:
+#ifdef USE_THREADS
+                               if (checksync) {
+                                       BUILTIN1((functionptr) builtin_monitorexit, TYPE_VOID);
+                                       }
+                               else
+#endif
+                                       {
+                                       OP(ICMD_POP);
+                                       }
+                               break;
+
+                       /* any other basic operation **************************************/
+
+                       case JAVA_IDIV:
+                               OP(opcode);
+                               break;
+
+                       case JAVA_IREM:
+                               OP(opcode);
+                               break;
+
+                       case JAVA_LDIV:
+                               OP(opcode);
+                               break;
+
+                       case JAVA_LREM:
+                               OP(opcode);
+                               break;
+
+                       case JAVA_FREM:
+                               BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
+                               break;
+
+                       case JAVA_DREM:
+                               BUILTIN2((functionptr) builtin_drem, TYPE_DOUBLE);
+                               break;
+
+                       case JAVA_F2I:
+                               if (checkfloats) {
+                                       BUILTIN1((functionptr) builtin_f2i, TYPE_INT);
+                                       }
+                               else {
+                                       OP(opcode);
+                                       }
+                               break;
+
+                       case JAVA_F2L:
+                               if (checkfloats) {
+                                       BUILTIN1((functionptr) builtin_f2l, TYPE_LONG);
+                                       }
+                               else {
+                                       OP(opcode);
+                                       }
+                               break;
+
+                       case JAVA_D2I:
+                               if (checkfloats) {
+                                       BUILTIN1((functionptr) builtin_d2i, TYPE_INT);
+                                       }
+                               else {
+                                       OP(opcode);
+                                       }
+                               break;
+
+                       case JAVA_D2L:
+                               if (checkfloats) {
+                                       BUILTIN1((functionptr) builtin_d2l, TYPE_LONG);
+                                       }
+                               else {
+                                       OP(opcode);
+                                       }
+                               break;
+
+                       case JAVA_BREAKPOINT:
+                               panic("Illegal opcode Breakpoint encountered");
+                               break;
+
+                       case 203:
+                       case 204:
+                       case 205:
+                       case 206:
+                       case 207:
+                       case 208:
+                       case 209:
+                       case 210:
+                       case 211:
+                       case 212:
+                       case 213:
+                       case 214:
+                       case 215:
+                       case 216:
+                       case 217:
+                       case 218:
+                       case 219:
+                       case 220:
+                       case 221:
+                       case 222:
+                       case 223:
+                       case 224:
+                       case 225:
+                       case 226:
+                       case 227:
+                       case 228:
+                       case 229:
+                       case 230:
+                       case 231:
+                       case 232:
+                       case 233:
+                       case 234:
+                       case 235:
+                       case 236:
+                       case 237:
+                       case 238:
+                       case 239:
+                       case 240:
+                       case 241:
+                       case 242:
+                       case 243:
+                       case 244:
+                       case 245:
+                       case 246:
+                       case 247:
+                       case 248:
+                       case 249:
+                       case 250:
+                       case 251:
+                       case 252:
+                       case 253:
+                       case 254:
+                       case 255:
+                               printf("Illegal opcode %d at instr %d", opcode, ipc);
+                               panic("encountered");
+                               break;
+
+                       default:
+                               OP(opcode);
+                               break;
+
+                       } /* end switch */
+
+               } /* end for */
+
+       if (p != jcodelength)
+               panic("Command-sequence crosses code-boundary");
+
+       if (!blockend)
+               panic("Code does not end with branch/return/athrow - stmt");    
+
+       /* adjust block count if target 0 is not first intermediate instruction   */
+
+       if (!block_index[0] || (block_index[0] > 1))
+               b_count++;
+
+       /* copy local to global variables   */
+
+       instr_count = ipc;
+       block_count = b_count;
+       stack_count = s_count + block_count * maxstack;
+
+       /* allocate stack table */
+
+       stack = DMNEW(stackelement, stack_count);
+
+       {
+       basicblock  *bptr;
+
+       bptr = block = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
+
+       b_count = 0;
+       
+       /* additional block if target 0 is not first intermediate instruction     */
+
+       if (!block_index[0] || (block_index[0] > 1)) {
+               bptr->iinstr = instr;
+               bptr->mpc = -1;
+               bptr->flags = -1;
+               bptr->type = BBTYPE_STD;
+               bptr->branchrefs = NULL;
+               bptr->pre_count = 0;
+               bptr++;
+               b_count++;
+               }
+
+       /* allocate blocks */
+
+       for (p = 0; p < jcodelength; p++)
+               if (block_index[p] & 1) {
+                       bptr->iinstr = instr + (block_index[p] >> 1);
+                       if (b_count != 0)
+                               (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
+                       bptr->mpc = -1;
+                       bptr->flags = -1;
+                       bptr->type = BBTYPE_STD;
+                       bptr->branchrefs = NULL;
+                       block_index[p] = b_count;
+                       bptr->pre_count = 0;
+                       bptr++;
+                       b_count++;
+                       }
+
+       /* allocate additional block at end */
+
+       bptr->iinstr = NULL;
+       (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
+       bptr->icount = 0;
+       bptr->mpc = -1;
+       bptr->flags = -1;
+       bptr->type = BBTYPE_STD;
+       bptr->branchrefs = NULL;
+       bptr->pre_count = 0;
+       }
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff --git a/jit/reg.c b/jit/reg.c
new file mode 100644 (file)
index 0000000..5838bce
--- /dev/null
+++ b/jit/reg.c
@@ -0,0 +1,1002 @@
+/* jit/reg.c *******************************************************************
+
+       Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+       See file COPYRIGHT for information on usage and disclaimer of warranties
+
+       The register-manager.
+
+       Authors:  Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
+
+       Last Change: 1998/11/09
+
+*******************************************************************************/
+
+static varinfo5 *locals;
+static varinfo5 *interfaces;
+
+static int intregsnum;              /* absolute number of integer registers   */
+static int floatregsnum;            /* absolute number of float registers     */ 
+
+static int intreg_ret;              /* register to return integer values      */
+static int intreg_argnum;           /* number of integer argument registers   */
+
+static int floatreg_ret;            /* register for return float values       */
+static int fltreg_argnum;           /* number of float argument registers     */
+
+
+static int *argintregs;             /* scratch integer registers              */
+static int *tmpintregs = NULL;      /* scratch integer registers              */
+static int *savintregs;             /* saved integer registers                */
+static int *argfltregs;             /* scratch float registers                */
+static int *tmpfltregs;             /* scratch float registers                */
+static int *savfltregs;             /* saved float registers                  */
+static int *freetmpintregs;         /* free scratch integer registers         */
+static int *freesavintregs;         /* free saved integer registers           */
+static int *freetmpfltregs;         /* free scratch float registers           */
+static int *freesavfltregs;         /* free saved float registers             */
+
+static int *freemem;                /* free scratch memory                    */
+static int memuse;                  /* used memory count                      */
+static int ifmemuse;                /* interface used memory count            */
+static int maxmemuse;               /* maximal used memory count (spills)     */
+static int freememtop;              /* free memory count                      */
+
+static int tmpintregcnt;            /* scratch integer register count         */
+static int savintregcnt;            /* saved integer register count           */
+static int tmpfltregcnt;            /* scratch float register count           */
+static int savfltregcnt;            /* saved float register count             */
+
+static int iftmpintregcnt;          /* iface scratch integer register count   */
+static int ifsavintregcnt;          /* iface saved integer register count     */
+static int iftmpfltregcnt;          /* iface scratch float register count     */
+static int ifsavfltregcnt;          /* iface saved float register count       */
+
+static int tmpintreguse;            /* used scratch integer register count    */
+static int savintreguse;            /* used saved integer register count      */
+static int tmpfltreguse;            /* used scratch float register count      */
+static int savfltreguse;            /* used saved float register count        */
+
+static int maxtmpintreguse;         /* max used scratch int register count    */
+static int maxsavintreguse;         /* max used saved int register count      */
+static int maxtmpfltreguse;         /* max used scratch float register count  */
+static int maxsavfltreguse;         /* max used saved float register count    */
+
+static int freetmpinttop;           /* free scratch integer register count    */
+static int freesavinttop;           /* free saved integer register count      */
+static int freetmpflttop;           /* free scratch float register count      */
+static int freesavflttop;           /* free saved float register count        */
+
+static int savedregs_num;              /* total number of registers to be saved      */
+static int arguments_num;       /* size of parameter field in the stackframe  */
+
+
+
+/* function reg_init ***********************************************************
+
+       initialises the register-allocator
+       
+*******************************************************************************/
+
+static void reg_init()
+{
+       int n;
+       
+       if (!tmpintregs) {
+
+               if (TYPE_INT != 0 || TYPE_ADR != 4) 
+                       panic ("JAVA-Basictypes have been changed");
+
+               intreg_argnum = 0;
+               tmpintregcnt = 0;
+               savintregcnt = 0;
+
+               for (intregsnum = 0; nregdescint[intregsnum] != REG_END; intregsnum++) {
+                       switch (nregdescint[intregsnum]) {
+                               case REG_SAV: savintregcnt++;
+                                             break;
+                               case REG_TMP: tmpintregcnt++;
+                                             break;
+                               case REG_ARG: intreg_argnum++;
+                               }
+                       }
+
+               argintregs = MNEW (int, intreg_argnum);
+               tmpintregs = MNEW (int, tmpintregcnt);
+               savintregs = MNEW (int, savintregcnt);
+               freetmpintregs = MNEW (int, tmpintregcnt);
+               freesavintregs = MNEW (int, savintregcnt);
+
+               intreg_argnum = 0;
+               tmpintreguse = 0;
+               savintreguse = 0;
+
+               for (n = 0; n < intregsnum; n++) {
+                       switch (nregdescint[n]) {
+                               case REG_RET: intreg_ret = n; 
+                                             break;
+                               case REG_SAV: savintregs[savintreguse++] = n;
+                                             break;
+                               case REG_TMP: tmpintregs[tmpintreguse++] = n;
+                                             break;
+                               case REG_ARG: argintregs[intreg_argnum++] = n;
+                                             break;
+                               }
+                       }
+                                       
+               
+               fltreg_argnum = 0;
+               tmpfltregcnt = 0;
+               savfltregcnt = 0;
+
+               for (floatregsnum = 0; nregdescfloat[floatregsnum] != REG_END; floatregsnum++) {
+                       switch (nregdescfloat[floatregsnum]) {
+                               case REG_SAV: savfltregcnt++;
+                                             break;
+                               case REG_TMP: tmpfltregcnt++;
+                                             break;
+                               case REG_ARG: fltreg_argnum++;
+                                             break;
+                               }
+                       }
+
+               argfltregs = MNEW (int, fltreg_argnum);
+               tmpfltregs = MNEW (int, tmpfltregcnt);
+               savfltregs = MNEW (int, savfltregcnt);
+               freetmpfltregs = MNEW (int, tmpfltregcnt);
+               freesavfltregs = MNEW (int, savfltregcnt);
+
+               fltreg_argnum = 0;
+               tmpfltreguse = 0;
+               savfltreguse = 0;
+
+               for (n = 0; n < floatregsnum; n++) {
+                       switch (nregdescfloat[n]) {
+                               case REG_RET: floatreg_ret = n; 
+                                             break;
+                               case REG_SAV: savfltregs[savfltreguse++] = n;
+                                             break;
+                               case REG_TMP: tmpfltregs[tmpfltreguse++] = n;
+                                             break;
+                               case REG_ARG: argfltregs[fltreg_argnum++] = n;
+                                             break;
+                               }
+                       }
+                                       
+               }
+
+}
+
+
+/* function reg_close **********************************************************
+
+       releases all allocated space for registers
+
+*******************************************************************************/
+
+static void reg_close ()
+{
+       if (argintregs) MFREE (argintregs, int, intreg_argnum);
+       if (argfltregs) MFREE (argfltregs, int, fltreg_argnum);
+       if (tmpintregs) MFREE (tmpintregs, int, tmpintregcnt);
+       if (savintregs) MFREE (savintregs, int, savintregcnt);
+       if (tmpfltregs) MFREE (tmpfltregs, int, tmpfltregcnt);
+       if (savfltregs) MFREE (savfltregs, int, savfltregcnt);
+
+       if (freetmpintregs) MFREE (freetmpintregs, int, tmpintregcnt);
+       if (freesavintregs) MFREE (freesavintregs, int, savintregcnt);
+       if (freetmpfltregs) MFREE (freetmpfltregs, int, tmpfltregcnt);
+       if (freesavfltregs) MFREE (freesavfltregs, int, savfltregcnt);
+}
+
+
+/* function local_init *********************************************************
+
+       initialises the local variable and interfaces table
+       
+*******************************************************************************/
+
+static void local_init()
+{
+       int i;
+       varinfo5 *v;
+
+       freemem    = DMNEW(int, maxstack);
+       locals     = DMNEW(varinfo5, maxlocals);
+       interfaces = DMNEW(varinfo5, maxstack);
+
+       for (v = locals, i = maxlocals; i > 0; v++, i--) {
+               v[0][TYPE_INT].type = -1;
+               v[0][TYPE_LNG].type = -1;
+               v[0][TYPE_FLT].type = -1;
+               v[0][TYPE_DBL].type = -1;
+               v[0][TYPE_ADR].type = -1;
+               }
+
+       for (v = interfaces, i = maxstack; i > 0; v++, i--) {
+               v[0][TYPE_INT].type = -1;
+               v[0][TYPE_INT].flags = 0;
+               v[0][TYPE_LNG].type = -1;
+               v[0][TYPE_LNG].flags = 0;
+               v[0][TYPE_FLT].type = -1;
+               v[0][TYPE_FLT].flags = 0;
+               v[0][TYPE_DBL].type = -1;
+               v[0][TYPE_DBL].flags = 0;
+               v[0][TYPE_ADR].type = -1;
+               v[0][TYPE_ADR].flags = 0;
+               }
+}
+
+
+/* function interface_regalloc *************************************************
+
+       allocates registers for all interface variables
+       
+*******************************************************************************/
+       
+static void interface_regalloc ()
+{
+       int     s, t, saved;
+       int     intalloc, fltalloc;
+       varinfo *v;
+       
+       /* allocate stack space for passing arguments to called methods */
+
+       if (arguments_num > intreg_argnum)
+               ifmemuse = arguments_num - intreg_argnum;
+       else
+               ifmemuse = 0;
+
+       iftmpintregcnt = tmpintregcnt;
+       ifsavintregcnt = savintregcnt;
+       iftmpfltregcnt = tmpfltregcnt;
+       ifsavfltregcnt = savfltregcnt;
+
+       for (s = 0; s < maxstack; s++) {
+               intalloc = -1; fltalloc = -1;
+               saved = (interfaces[s][TYPE_INT].flags | interfaces[s][TYPE_LNG].flags |
+                        interfaces[s][TYPE_FLT].flags | interfaces[s][TYPE_DBL].flags |
+                        interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
+               for (t = TYPE_INT; t <= TYPE_ADR; t++) {
+                       v = &interfaces[s][t];
+                       if (v->type >= 0) {
+                               if (!saved) {
+                                       if (IS_FLT_DBL_TYPE(t)) {
+                                               if (fltalloc >= 0) {
+                                                       v->flags |= interfaces[s][fltalloc].flags & INMEMORY;
+                                                       v->regoff = interfaces[s][fltalloc].regoff;
+                                                       }
+                                               else if (iftmpfltregcnt > 0) {
+                                                       iftmpfltregcnt--;
+                                                       v->regoff = tmpfltregs[iftmpfltregcnt];
+                                                       }
+                                               else if (ifsavfltregcnt > 0) {
+                                                       ifsavfltregcnt--;
+                                                       v->regoff = savfltregs[ifsavfltregcnt];
+                                                       }
+                                               else {
+                                                       v->flags |= INMEMORY;
+                                                       v->regoff = ifmemuse++;
+                                                       }
+                                               fltalloc = t;
+                                               }
+                                       else {
+                                               if (intalloc >= 0) {
+                                                       v->flags |= interfaces[s][intalloc].flags & INMEMORY;
+                                                       v->regoff = interfaces[s][intalloc].regoff;
+                                                       }
+                                               else if (iftmpintregcnt > 0) {
+                                                       iftmpintregcnt--;
+                                                       v->regoff = tmpintregs[iftmpintregcnt];
+                                                       }
+                                               else if (ifsavintregcnt > 0) {
+                                                       ifsavintregcnt--;
+                                                       v->regoff = savintregs[ifsavintregcnt];
+                                                       }
+                                               else {
+                                                       v->flags |= INMEMORY;
+                                                       v->regoff = ifmemuse++;
+                                                       }
+                                               intalloc = t;
+                                               }
+                                       }
+                               else {
+                                       if (IS_FLT_DBL_TYPE(t)) {
+                                               if (fltalloc >= 0) {
+                                                       v->flags |= interfaces[s][fltalloc].flags & INMEMORY;
+                                                       v->regoff = interfaces[s][fltalloc].regoff;
+                                                       }
+                                               else if (ifsavfltregcnt > 0) {
+                                                       ifsavfltregcnt--;
+                                                       v->regoff = savfltregs[ifsavfltregcnt];
+                                                       }
+                                               else {
+                                                       v->flags |= INMEMORY;
+                                                       v->regoff = ifmemuse++;
+                                                       }
+                                               fltalloc = t;
+                                               }
+                                       else {
+                                               if (intalloc >= 0) {
+                                                       v->flags |= interfaces[s][intalloc].flags & INMEMORY;
+                                                       v->regoff = interfaces[s][intalloc].regoff;
+                                                       }
+                                               else if (ifsavintregcnt > 0) {
+                                                       ifsavintregcnt--;
+                                                       v->regoff = savintregs[ifsavintregcnt];
+                                                       }
+                                               else {
+                                                       v->flags |= INMEMORY;
+                                                       v->regoff = ifmemuse++;
+                                                       }
+                                               intalloc = t;
+                                               }
+                                       }
+                               } /* if (type >= 0) */
+                       }     /* for t */
+               }         /* for s */
+       maxmemuse = ifmemuse;
+       maxtmpintreguse = iftmpintregcnt;
+       maxsavintreguse = ifsavintregcnt;
+       maxtmpfltreguse = iftmpfltregcnt;
+       maxsavfltreguse = ifsavfltregcnt;
+}
+
+
+/* function local_regalloc *****************************************************
+
+       allocates registers for all local variables
+       
+*******************************************************************************/
+       
+static void local_regalloc ()
+{
+       int     s, t;
+       int     intalloc, fltalloc;
+       varinfo *v;
+       
+       if (isleafmethod) {
+               for (s = 0; s < maxlocals; s++) {
+                       intalloc = -1; fltalloc = -1;
+                       for (t = TYPE_INT; t <= TYPE_ADR; t++) {
+                               v = &locals[s][t];
+                               if (v->type >= 0) {
+                                       if (IS_FLT_DBL_TYPE(t)) {
+                                               if (fltalloc >= 0) {
+                                                       v->flags = locals[s][fltalloc].flags;
+                                                       v->regoff = locals[s][fltalloc].regoff;
+                                                       }
+                                               else if (s < fltreg_argnum) {
+                                                       v->flags = 0;
+                                                       v->regoff = argfltregs[s];
+                                                       }
+                                               else if (maxtmpfltreguse > 0) {
+                                                       maxtmpfltreguse--;
+                                                       v->flags = 0;
+                                                       v->regoff = tmpfltregs[maxtmpfltreguse];
+                                                       }
+                                               else if (maxsavfltreguse > 0) {
+                                                       maxsavfltreguse--;
+                                                       v->flags = 0;
+                                                       v->regoff = savfltregs[maxsavfltreguse];
+                                                       }
+                                               else {
+                                                       v->flags = INMEMORY;
+                                                       v->regoff = maxmemuse++;
+                                                       }
+                                               fltalloc = t;
+                                               }
+                                       else {
+                                               if (intalloc >= 0) {
+                                                       v->flags = locals[s][intalloc].flags;
+                                                       v->regoff = locals[s][intalloc].regoff;
+                                                       }
+                                               else if (s < intreg_argnum) {
+                                                       v->flags = 0;
+                                                       v->regoff = argintregs[s];
+                                                       }
+                                               else if (maxtmpintreguse > 0) {
+                                                       maxtmpintreguse--;
+                                                       v->flags = 0;
+                                                       v->regoff = tmpintregs[maxtmpintreguse];
+                                                       }
+                                               else if (maxsavintreguse > 0) {
+                                                       maxsavintreguse--;
+                                                       v->flags = 0;
+                                                       v->regoff = savintregs[maxsavintreguse];
+                                                       }
+                                               else {
+                                                       v->flags = INMEMORY;
+                                                       v->regoff = maxmemuse++;
+                                                       }
+                                               intalloc = t;
+                                               }
+                                       }
+                               }
+                       }
+               return;
+               }
+       for (s = 0; s < maxlocals; s++) {
+               intalloc = -1; fltalloc = -1;
+               for (t=TYPE_INT; t<=TYPE_ADR; t++) {
+                       v = &locals[s][t];
+                       if (v->type >= 0) {
+                               if (IS_FLT_DBL_TYPE(t)) {
+                                       if (fltalloc >= 0) {
+                                               v->flags = locals[s][fltalloc].flags;
+                                               v->regoff = locals[s][fltalloc].regoff;
+                                               }
+                                       else if (maxsavfltreguse > 0) {
+                                               maxsavfltreguse--;
+                                               v->flags = 0;
+                                               v->regoff = savfltregs[maxsavfltreguse];
+                                               }
+                                       else {
+                                               v->flags = INMEMORY;
+                                               v->regoff = maxmemuse++;
+                                               }
+                                       fltalloc = t;
+                                       }
+                               else {
+                                       if (intalloc >= 0) {
+                                               v->flags = locals[s][intalloc].flags;
+                                               v->regoff = locals[s][intalloc].regoff;
+                                               }
+                                       else if (maxsavintreguse > 0) {
+                                               maxsavintreguse--;
+                                               v->flags = 0;
+                                               v->regoff = savintregs[maxsavintreguse];
+                                               }
+                                       else {
+                                               v->flags = INMEMORY;
+                                               v->regoff = maxmemuse++;
+                                               }
+                                       intalloc = t;
+                                       }
+                               }
+                       }
+               }
+}
+
+
+static void reg_init_temp()
+{
+       freememtop = 0;
+       memuse = ifmemuse;
+
+       freetmpinttop = 0;
+       freesavinttop = 0;
+       freetmpflttop = 0;
+       freesavflttop = 0;
+       tmpintreguse = iftmpintregcnt;
+       savintreguse = ifsavintregcnt;
+       tmpfltreguse = iftmpfltregcnt;
+       savfltreguse = ifsavfltregcnt;
+}
+
+
+#define reg_new_temp(s) if(s->varkind==TEMPVAR)reg_new_temp_func(s)
+
+static void reg_new_temp_func(stackptr s)
+{
+if (s->flags & SAVEDVAR) {
+       if (IS_FLT_DBL_TYPE(s->type)) {
+               if (freesavflttop > 0) {
+                       freesavflttop--;
+                       s->regoff = freesavfltregs[freesavflttop];
+                       return;
+                       }
+               else if (savfltreguse > 0) {
+                       savfltreguse--;
+                       if (savfltreguse < maxsavfltreguse)
+                               maxsavfltreguse = savfltreguse;
+                       s->regoff = savfltregs[savfltreguse];
+                       return;
+                       }
+               }
+       else {
+               if (freesavinttop > 0) {
+                       freesavinttop--;
+                       s->regoff = freesavintregs[freesavinttop];
+                       return;
+                       }
+               else if (savintreguse > 0) {
+                       savintreguse--;
+                       if (savintreguse < maxsavintreguse)
+                               maxsavintreguse = savintreguse;
+                       s->regoff = savintregs[savintreguse];
+                       return;
+                       }
+               }
+       }
+else {
+       if (IS_FLT_DBL_TYPE(s->type)) {
+               if (freetmpflttop > 0) {
+                       freetmpflttop--;
+                       s->regoff = freetmpfltregs[freetmpflttop];
+                       return;
+                       }
+               else if (tmpfltreguse > 0) {
+                       tmpfltreguse--;
+                       if (tmpfltreguse < maxtmpfltreguse)
+                               maxtmpfltreguse = tmpfltreguse;
+                       s->regoff = tmpfltregs[tmpfltreguse];
+                       return;
+                       }
+               }
+       else {
+               if (freetmpinttop > 0) {
+                       freetmpinttop--;
+                       s->regoff = freetmpintregs[freetmpinttop];
+                       return;
+                       }
+               else if (tmpintreguse > 0) {
+                       tmpintreguse--;
+                       if (tmpintreguse < maxtmpintreguse)
+                               maxtmpintreguse = tmpintreguse;
+                       s->regoff = tmpintregs[tmpintreguse];
+                       return;
+                       }
+               }
+       }
+if (freememtop > 0) {
+       freememtop--;
+       s->regoff = freemem[freememtop];
+       }
+else {
+       s->regoff = memuse++;
+       if (memuse > maxmemuse)
+               maxmemuse = memuse;
+       }
+s->flags |= INMEMORY;
+}
+
+
+#define reg_free_temp(s) if(s->varkind==TEMPVAR)reg_free_temp_func(s)
+
+static void reg_free_temp_func(stackptr s)
+{
+if (s->flags & INMEMORY)
+       freemem[freememtop++] = s->regoff;
+else if (IS_FLT_DBL_TYPE(s->type)) {
+       if (s->flags & SAVEDVAR)
+               freesavfltregs[freesavflttop++] = s->regoff;
+       else
+               freetmpfltregs[freetmpflttop++] = s->regoff;
+       }
+else
+       if (s->flags & SAVEDVAR)
+               freesavintregs[freesavinttop++] = s->regoff;
+       else
+               freetmpintregs[freetmpinttop++] = s->regoff;
+}
+
+
+static void allocate_scratch_registers()
+{
+       int b_count;
+       int opcode, i, len;
+       stackptr    src, dst;
+       instruction *iptr = instr;
+       basicblock  *bptr;
+       
+       b_count = block_count;
+       bptr = block;
+       while (--b_count >= 0) {
+               if (bptr->flags >= BBREACHED) {
+                       dst = bptr->instack;
+                       reg_init_temp();
+                       iptr = bptr->iinstr;
+                       len = bptr->icount;
+                       while (--len >= 0)  {
+                               src = dst;
+                               dst = iptr->dst;
+                               opcode = iptr->opc;
+                               switch (opcode) {
+
+                                       /* pop 0 push 0 */
+
+                                       case ICMD_NOP:
+                                       case ICMD_ELSE_ICONST:
+                                       case ICMD_CHECKASIZE:
+                                       case ICMD_IINC:
+                                       case ICMD_JSR:
+                                       case ICMD_RET:
+                                       case ICMD_RETURN:
+                                       case ICMD_GOTO:
+                                               break;
+
+                                       /* pop 0 push 1 const */
+                                       
+                                       case ICMD_ICONST:
+                                       case ICMD_LCONST:
+                                       case ICMD_FCONST:
+                                       case ICMD_DCONST:
+                                       case ICMD_ACONST:
+
+                                       /* pop 0 push 1 load */
+                                       
+                                       case ICMD_ILOAD:
+                                       case ICMD_LLOAD:
+                                       case ICMD_FLOAD:
+                                       case ICMD_DLOAD:
+                                       case ICMD_ALOAD:
+                                               reg_new_temp(dst);
+                                               break;
+
+                                       /* pop 2 push 1 */
+
+                                       case ICMD_IALOAD:
+                                       case ICMD_LALOAD:
+                                       case ICMD_FALOAD:
+                                       case ICMD_DALOAD:
+                                       case ICMD_AALOAD:
+
+                                       case ICMD_BALOAD:
+                                       case ICMD_CALOAD:
+                                       case ICMD_SALOAD:
+                                               reg_free_temp(src);
+                                               reg_free_temp(src->prev);
+                                               reg_new_temp(dst);
+                                               break;
+
+                                       /* pop 3 push 0 */
+
+                                       case ICMD_IASTORE:
+                                       case ICMD_LASTORE:
+                                       case ICMD_FASTORE:
+                                       case ICMD_DASTORE:
+                                       case ICMD_AASTORE:
+
+                                       case ICMD_BASTORE:
+                                       case ICMD_CASTORE:
+                                       case ICMD_SASTORE:
+                                               reg_free_temp(src);
+                                               reg_free_temp(src->prev);
+                                               reg_free_temp(src->prev->prev);
+                                               break;
+
+                                       /* pop 1 push 0 store */
+
+                                       case ICMD_ISTORE:
+                                       case ICMD_LSTORE:
+                                       case ICMD_FSTORE:
+                                       case ICMD_DSTORE:
+                                       case ICMD_ASTORE:
+
+                                       /* pop 1 push 0 */
+
+                                       case ICMD_POP:
+
+                                       case ICMD_IRETURN:
+                                       case ICMD_LRETURN:
+                                       case ICMD_FRETURN:
+                                       case ICMD_DRETURN:
+                                       case ICMD_ARETURN:
+
+                                       case ICMD_ATHROW:
+
+                                       case ICMD_PUTSTATIC:
+
+                                       /* pop 1 push 0 branch */
+
+                                       case ICMD_IFNULL:
+                                       case ICMD_IFNONNULL:
+
+                                       case ICMD_IFEQ:
+                                       case ICMD_IFNE:
+                                       case ICMD_IFLT:
+                                       case ICMD_IFGE:
+                                       case ICMD_IFGT:
+                                       case ICMD_IFLE:
+
+                                       case ICMD_IF_LEQ:
+                                       case ICMD_IF_LNE:
+                                       case ICMD_IF_LLT:
+                                       case ICMD_IF_LGE:
+                                       case ICMD_IF_LGT:
+                                       case ICMD_IF_LLE:
+
+                                       /* pop 1 push 0 table branch */
+
+                                       case ICMD_TABLESWITCH:
+                                       case ICMD_LOOKUPSWITCH:
+
+                                       case ICMD_NULLCHECKPOP:
+                                       case ICMD_MONITORENTER:
+                                       case ICMD_MONITOREXIT:
+                                               reg_free_temp(src);
+                                               break;
+
+                                       /* pop 2 push 0 branch */
+
+                                       case ICMD_IF_ICMPEQ:
+                                       case ICMD_IF_ICMPNE:
+                                       case ICMD_IF_ICMPLT:
+                                       case ICMD_IF_ICMPGE:
+                                       case ICMD_IF_ICMPGT:
+                                       case ICMD_IF_ICMPLE:
+
+                                       case ICMD_IF_LCMPEQ:
+                                       case ICMD_IF_LCMPNE:
+                                       case ICMD_IF_LCMPLT:
+                                       case ICMD_IF_LCMPGE:
+                                       case ICMD_IF_LCMPGT:
+                                       case ICMD_IF_LCMPLE:
+
+                                       case ICMD_IF_ACMPEQ:
+                                       case ICMD_IF_ACMPNE:
+
+                                       /* pop 2 push 0 */
+
+                                       case ICMD_POP2:
+
+                                       case ICMD_PUTFIELD:
+                                               reg_free_temp(src);
+                                               reg_free_temp(src->prev);
+                                               break;
+
+                                       /* pop 0 push 1 dup */
+                                       
+                                       case ICMD_DUP:
+                                               reg_new_temp(dst);
+                                               break;
+
+                                       /* pop 0 push 2 dup */
+                                       
+                                       case ICMD_DUP2:
+                                               reg_new_temp(dst->prev);
+                                               reg_new_temp(dst);
+                                               break;
+
+                                       /* pop 2 push 3 dup */
+                                       
+                                       case ICMD_DUP_X1:
+                                               reg_new_temp(dst->prev->prev);
+                                               reg_new_temp(dst->prev);
+                                               reg_new_temp(dst);
+                                               reg_free_temp(src);
+                                               reg_free_temp(src->prev);
+                                               break;
+
+                                       /* pop 3 push 4 dup */
+                                       
+                                       case ICMD_DUP_X2:
+                                               reg_new_temp(dst->prev->prev->prev);
+                                               reg_new_temp(dst->prev->prev);
+                                               reg_new_temp(dst->prev);
+                                               reg_new_temp(dst);
+                                               reg_free_temp(src);
+                                               reg_free_temp(src->prev);
+                                               reg_free_temp(src->prev->prev);
+                                               break;
+
+                                       /* pop 3 push 5 dup */
+                                       
+                                       case ICMD_DUP2_X1:
+                                               reg_new_temp(dst->prev->prev->prev->prev);
+                                               reg_new_temp(dst->prev->prev->prev);
+                                               reg_new_temp(dst->prev->prev);
+                                               reg_new_temp(dst->prev);
+                                               reg_new_temp(dst);
+                                               reg_free_temp(src);
+                                               reg_free_temp(src->prev);
+                                               reg_free_temp(src->prev->prev);
+                                               break;
+
+                                       /* pop 4 push 6 dup */
+                                       
+                                       case ICMD_DUP2_X2:
+                                               reg_new_temp(dst->prev->prev->prev->prev->prev);
+                                               reg_new_temp(dst->prev->prev->prev->prev);
+                                               reg_new_temp(dst->prev->prev->prev);
+                                               reg_new_temp(dst->prev->prev);
+                                               reg_new_temp(dst->prev);
+                                               reg_new_temp(dst);
+                                               reg_free_temp(src);
+                                               reg_free_temp(src->prev);
+                                               reg_free_temp(src->prev->prev);
+                                               reg_free_temp(src->prev->prev->prev);
+                                               break;
+
+                                       /* pop 2 push 2 swap */
+                                       
+                                       case ICMD_SWAP:
+                                               reg_new_temp(dst->prev);
+                                               reg_new_temp(dst);
+                                               reg_free_temp(src);
+                                               reg_free_temp(src->prev);
+                                               break;
+
+                                       /* pop 2 push 1 */
+                                       
+                                       case ICMD_IADD:
+                                       case ICMD_ISUB:
+                                       case ICMD_IMUL:
+                                       case ICMD_IDIV:
+                                       case ICMD_IREM:
+
+                                       case ICMD_ISHL:
+                                       case ICMD_ISHR:
+                                       case ICMD_IUSHR:
+                                       case ICMD_IAND:
+                                       case ICMD_IOR:
+                                       case ICMD_IXOR:
+
+                                       case ICMD_LADD:
+                                       case ICMD_LSUB:
+                                       case ICMD_LMUL:
+                                       case ICMD_LDIV:
+                                       case ICMD_LREM:
+
+                                       case ICMD_LOR:
+                                       case ICMD_LAND:
+                                       case ICMD_LXOR:
+
+                                       case ICMD_LSHL:
+                                       case ICMD_LSHR:
+                                       case ICMD_LUSHR:
+
+                                       case ICMD_FADD:
+                                       case ICMD_FSUB:
+                                       case ICMD_FMUL:
+                                       case ICMD_FDIV:
+                                       case ICMD_FREM:
+
+                                       case ICMD_DADD:
+                                       case ICMD_DSUB:
+                                       case ICMD_DMUL:
+                                       case ICMD_DDIV:
+                                       case ICMD_DREM:
+
+                                       case ICMD_LCMP:
+                                       case ICMD_FCMPL:
+                                       case ICMD_FCMPG:
+                                       case ICMD_DCMPL:
+                                       case ICMD_DCMPG:
+                                               reg_free_temp(src);
+                                               reg_free_temp(src->prev);
+                                               reg_new_temp(dst);
+                                               break;
+
+                                       /* pop 1 push 1 */
+                                       
+                                       case ICMD_IADDCONST:
+                                       case ICMD_ISUBCONST:
+                                       case ICMD_IMULCONST:
+                                       case ICMD_IDIVPOW2:
+                                       case ICMD_IREMPOW2:
+                                       case ICMD_IREM0X10001:
+                                       case ICMD_IANDCONST:
+                                       case ICMD_IORCONST:
+                                       case ICMD_IXORCONST:
+                                       case ICMD_ISHLCONST:
+                                       case ICMD_ISHRCONST:
+                                       case ICMD_IUSHRCONST:
+
+                                       case ICMD_LADDCONST:
+                                       case ICMD_LSUBCONST:
+                                       case ICMD_LMULCONST:
+                                       case ICMD_LDIVPOW2:
+                                       case ICMD_LREMPOW2:
+                                       case ICMD_LREM0X10001:
+                                       case ICMD_LANDCONST:
+                                       case ICMD_LORCONST:
+                                       case ICMD_LXORCONST:
+                                       case ICMD_LSHLCONST:
+                                       case ICMD_LSHRCONST:
+                                       case ICMD_LUSHRCONST:
+
+                                       case ICMD_IFEQ_ICONST:
+                                       case ICMD_IFNE_ICONST:
+                                       case ICMD_IFLT_ICONST:
+                                       case ICMD_IFGE_ICONST:
+                                       case ICMD_IFGT_ICONST:
+                                       case ICMD_IFLE_ICONST:
+
+                                       case ICMD_INEG:
+                                       case ICMD_INT2BYTE:
+                                       case ICMD_INT2CHAR:
+                                       case ICMD_INT2SHORT:
+                                       case ICMD_LNEG:
+                                       case ICMD_FNEG:
+                                       case ICMD_DNEG:
+
+                                       case ICMD_I2L:
+                                       case ICMD_I2F:
+                                       case ICMD_I2D:
+                                       case ICMD_L2I:
+                                       case ICMD_L2F:
+                                       case ICMD_L2D:
+                                       case ICMD_F2I:
+                                       case ICMD_F2L:
+                                       case ICMD_F2D:
+                                       case ICMD_D2I:
+                                       case ICMD_D2L:
+                                       case ICMD_D2F:
+
+                                       case ICMD_CHECKCAST:
+
+                                       case ICMD_ARRAYLENGTH:
+                                       case ICMD_INSTANCEOF:
+
+                                       case ICMD_NEWARRAY:
+                                       case ICMD_ANEWARRAY:
+
+                                       case ICMD_GETFIELD:
+                                               reg_free_temp(src);
+                                               reg_new_temp(dst);
+                                               break;
+
+                                       /* pop 0 push 1 */
+                                       
+                                       case ICMD_GETSTATIC:
+
+                                       case ICMD_NEW:
+
+                                               reg_new_temp(dst);
+                                               break;
+
+                                       /* pop many push any */
+                                       
+                                       case ICMD_INVOKEVIRTUAL:
+                                       case ICMD_INVOKESPECIAL:
+                                       case ICMD_INVOKESTATIC:
+                                       case ICMD_INVOKEINTERFACE:
+                                               {
+                                               i = iptr->op1;
+                                               while (--i >= 0) {
+                                                       reg_free_temp(src);
+                                                       src = src->prev;
+                                                       }
+                                               if (((methodinfo*)iptr->val.a)->returntype != TYPE_VOID)
+                                                       reg_new_temp(dst);
+                                               break;
+                                               }
+
+                                       case ICMD_BUILTIN3:
+                                               reg_free_temp(src);
+                                               src = src->prev;
+                                       case ICMD_BUILTIN2:
+                                               reg_free_temp(src);
+                                               src = src->prev;
+                                       case ICMD_BUILTIN1:
+                                               reg_free_temp(src);
+                                               src = src->prev;
+                                               if (iptr->op1 != TYPE_VOID)
+                                                       reg_new_temp(dst);
+                                               break;
+
+                                       case ICMD_MULTIANEWARRAY:
+                                               i = iptr->op1;
+                                               while (--i >= 0) {
+                                                       reg_free_temp(src);
+                                                       src = src->prev;
+                                                       }
+                                               reg_new_temp(dst);
+                                               break;
+
+                                       default:
+                                               printf("ICMD %d at %d\n", iptr->opc, (int)(iptr-instr));
+                                               panic("Missing ICMD code during register allocation");
+                                       } /* switch */
+                               iptr++;
+                               } /* while instructions */
+                       } /* if */
+               bptr++;
+       } /* while blocks */
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff --git a/jit/stack.c b/jit/stack.c
new file mode 100644 (file)
index 0000000..ef56f35
--- /dev/null
@@ -0,0 +1,1966 @@
+/* jit/stack.c *****************************************************************
+
+       Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+       See file COPYRIGHT for information on usage and disclaimer of warranties
+
+       Parser for JavaVM to intermediate code translation
+       
+       Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
+
+       Last Change: 1997/11/18
+
+*******************************************************************************/
+
+#define CONDITIONAL_LOADCONST
+
+#ifdef STATISTICS
+#define COUNT(cnt) cnt++
+#else
+#define COUNT(cnt)
+#endif
+
+#define STACKRESET {curstack=0;stackdepth=0;}
+
+#define TYPEPANIC  {show_icmd_method();panic("Stack type mismatch");}
+#define CURKIND    curstack->varkind
+#define CURTYPE    curstack->type
+
+#define NEWSTACK(s,v,n) {new->prev=curstack;new->type=s;new->flags=0;\
+                        new->varkind=v;new->varnum=n;curstack=new;new++;}
+#define NEWSTACKn(s,n)  NEWSTACK(s,UNDEFVAR,n)
+#define NEWSTACK0(s)    NEWSTACK(s,UNDEFVAR,0)
+#define NEWXSTACK   {NEWSTACK(TYPE_ADR,STACKVAR,0);curstack=0;}
+
+#define SETDST      {iptr->dst=curstack;}
+#define POP(s)      {if(s!=curstack->type){TYPEPANIC;}\
+                     if(curstack->varkind==UNDEFVAR)curstack->varkind=TEMPVAR;\
+                     curstack=curstack->prev;}
+#define POPANY      {if(curstack->varkind==UNDEFVAR)curstack->varkind=TEMPVAR;\
+                     curstack=curstack->prev;}
+#define COPY(s,d)   {(d)->flags=0;(d)->type=(s)->type;\
+                     (d)->varkind=(s)->varkind;(d)->varnum=(s)->varnum;}
+
+#define PUSHCONST(s){NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
+#define LOAD(s,v,n) {NEWSTACK(s,v,n);SETDST;stackdepth++;}
+#define STORE(s)    {POP(s);SETDST;stackdepth--;}
+#define OP1_0(s)    {POP(s);SETDST;stackdepth--;}
+#define OP1_0ANY    {POPANY;SETDST;stackdepth--;}
+#define OP0_1(s)    {NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
+#define OP1_1(s,d)  {POP(s);NEWSTACKn(d,stackdepth-1);SETDST;}
+#define OP2_0(s)    {POP(s);POP(s);SETDST;stackdepth-=2;}
+#define OPTT2_0(t,b){POP(t);POP(b);SETDST;stackdepth-=2;}
+#define OP2_1(s)    {POP(s);POP(s);NEWSTACKn(s,stackdepth-2);SETDST;stackdepth--;}
+#define OP2IAT_1(s) {POP(TYPE_INT);POP(TYPE_ADR);NEWSTACKn(s,stackdepth-2);\
+                     SETDST;stackdepth--;}
+#define OP2IT_1(s)  {POP(TYPE_INT);POP(s);NEWSTACKn(s,stackdepth-2);\
+                     SETDST;stackdepth--;}
+#define OPTT2_1(s,d){POP(s);POP(s);NEWSTACKn(d,stackdepth-2);SETDST;stackdepth--;}
+#define OP2_2(s)    {POP(s);POP(s);NEWSTACKn(s,stackdepth-2);\
+                     NEWSTACKn(s,stackdepth-1);SETDST;}
+#define OP3TIA_0(s) {POP(s);POP(TYPE_INT);POP(TYPE_ADR);SETDST;stackdepth-=3;}
+#define OP3_0(s)    {POP(s);POP(s);POP(s);SETDST;stackdepth-=3;}
+#define POPMANY(i)  {stackdepth-=i;while(--i>=0){POPANY;}SETDST;}
+#define DUP         {NEWSTACK(CURTYPE,CURKIND,curstack->varnum);SETDST;\
+                    stackdepth++;}
+#define SWAP        {COPY(curstack,new);POPANY;COPY(curstack,new+1);POPANY;\
+                    new[0].prev=curstack;new[1].prev=new;\
+                    curstack=new+1;new+=2;SETDST;}
+#define DUP_X1      {COPY(curstack,new);COPY(curstack,new+2);POPANY;\
+                    COPY(curstack,new+1);POPANY;new[0].prev=curstack;\
+                    new[1].prev=new;new[2].prev=new+1;\
+                    curstack=new+2;new+=3;SETDST;stackdepth++;}
+#define DUP2_X1     {COPY(curstack,new+1);COPY(curstack,new+4);POPANY;\
+                    COPY(curstack,new);COPY(curstack,new+3);POPANY;\
+                    COPY(curstack,new+2);POPANY;new[0].prev=curstack;\
+                    new[1].prev=new;new[2].prev=new+1;\
+                    new[3].prev=new+2;new[4].prev=new+3;\
+                    curstack=new+4;new+=5;SETDST;stackdepth+=2;}
+#define DUP_X2      {COPY(curstack,new);COPY(curstack,new+3);POPANY;\
+                    COPY(curstack,new+2);POPANY;COPY(curstack,new+1);POPANY;\
+                    new[0].prev=curstack;new[1].prev=new;\
+                    new[2].prev=new+1;new[3].prev=new+2;\
+                    curstack=new+3;new+=4;SETDST;stackdepth++;}
+#define DUP2_X2     {COPY(curstack,new+1);COPY(curstack,new+5);POPANY;\
+                    COPY(curstack,new);COPY(curstack,new+4);POPANY;\
+                    COPY(curstack,new+3);POPANY;COPY(curstack,new+2);POPANY;\
+                    new[0].prev=curstack;new[1].prev=new;\
+                    new[2].prev=new+1;new[3].prev=new+2;\
+                    new[4].prev=new+3;new[5].prev=new+4;\
+                    curstack=new+5;new+=6;SETDST;stackdepth+=2;}
+
+#define COPYCURSTACK(copy) {\
+       int d;\
+       stackptr s;\
+       if(curstack){\
+               s=curstack;\
+               new+=stackdepth;\
+               d=stackdepth;\
+               copy=new;\
+               while(s){\
+                       copy--;d--;\
+                       copy->prev=copy-1;\
+                       copy->type=s->type;\
+                       copy->flags=0;\
+                       copy->varkind=STACKVAR;\
+                       copy->varnum=d;\
+                       s=s->prev;\
+                       }\
+               copy->prev=NULL;\
+               copy=new-1;\
+               }\
+       else\
+               copy=NULL;\
+}
+
+
+#define BBEND(s,i){\
+       i=stackdepth-1;\
+       copy=s;\
+       while(copy){\
+               if((copy->varkind==STACKVAR)&&(copy->varnum>i))\
+                       copy->varkind=TEMPVAR;\
+               else {\
+                       copy->varkind=STACKVAR;\
+                       copy->varnum=i;\
+                       }\
+               interfaces[i][copy->type].type = copy->type;\
+               interfaces[i][copy->type].flags |= copy->flags;\
+               i--;copy=copy->prev;\
+               }\
+       i=bptr->indepth-1;\
+       copy=bptr->instack;\
+       while(copy){\
+               interfaces[i][copy->type].type = copy->type;\
+               if(copy->varkind==STACKVAR){\
+                       if (copy->flags & SAVEDVAR)\
+                               interfaces[i][copy->type].flags |= SAVEDVAR;\
+                       }\
+               i--;copy=copy->prev;\
+               }\
+}
+
+       
+#define MARKREACHED(b,c) {\
+       if(b->flags<0)\
+               {COPYCURSTACK(c);b->flags=0;b->instack=c;b->indepth=stackdepth;}\
+       else {stackptr s=curstack;stackptr t=b->instack;\
+               if(b->indepth!=stackdepth)\
+                       {show_icmd_method();panic("Stack depth mismatch");}\
+               while(s){if (s->type!=t->type)\
+                               TYPEPANIC\
+                       s=s->prev;t=t->prev;\
+                       }\
+               }\
+}
+
+
+static void show_icmd_method();
+
+static void analyse_stack()
+{
+       int b_count, b_index;
+       int stackdepth;
+       stackptr curstack, new, copy;
+       int opcode, i, len, loops;
+       int superblockend, repeat, deadcode;
+       instruction *iptr = instr;
+       basicblock *bptr, *tbptr;
+       s4  *s4ptr;
+       
+       arguments_num = 0;
+       new = stack;
+       loops = 0;
+       block[0].flags = BBREACHED;
+       block[0].instack = 0;
+       block[0].indepth = 0;
+
+       for (i = 0; i < exceptiontablelength; i++) {
+               bptr = &block[block_index[extable[i].handlerpc]];
+               bptr->flags = BBREACHED;
+               bptr->type = BBTYPE_EXH;
+               bptr->instack = new;
+               bptr->indepth = 1;
+               bptr->pre_count = 10000;
+               STACKRESET;
+               NEWXSTACK;
+               }
+
+#ifdef CONDITIONAL_LOADCONST
+       b_count = block_count;
+       bptr = block;
+       while (--b_count >= 0) {
+               if (bptr->icount != 0) {
+                       iptr = bptr->iinstr + bptr->icount - 1;
+                       switch (iptr->opc) {
+                               case ICMD_RET:
+                               case ICMD_RETURN:
+                               case ICMD_IRETURN:
+                               case ICMD_LRETURN:
+                               case ICMD_FRETURN:
+                               case ICMD_DRETURN:
+                               case ICMD_ARETURN:
+                               case ICMD_ATHROW:
+                                       break;
+
+                               case ICMD_IFEQ:
+                               case ICMD_IFNE:
+                               case ICMD_IFLT:
+                               case ICMD_IFGE:
+                               case ICMD_IFGT:
+                               case ICMD_IFLE:
+
+                               case ICMD_IFNULL:
+                               case ICMD_IFNONNULL:
+
+                               case ICMD_IF_ICMPEQ:
+                               case ICMD_IF_ICMPNE:
+                               case ICMD_IF_ICMPLT:
+                               case ICMD_IF_ICMPGE:
+                               case ICMD_IF_ICMPGT:
+                               case ICMD_IF_ICMPLE:
+
+                               case ICMD_IF_ACMPEQ:
+                               case ICMD_IF_ACMPNE:
+                                       bptr[1].pre_count++;
+                               case ICMD_GOTO:
+                                       block[block_index[iptr->op1]].pre_count++;
+                                       break;
+
+                               case ICMD_TABLESWITCH:
+                                       s4ptr = iptr->val.a;
+                                       block[block_index[*s4ptr++]].pre_count++;   /* default */
+                                       i = *s4ptr++;                               /* low     */
+                                       i = *s4ptr++ - i + 1;                       /* high    */
+                                       while (--i >= 0) {
+                                               block[block_index[*s4ptr++]].pre_count++;
+                                               }
+                                       break;
+                                       
+                               case ICMD_LOOKUPSWITCH:
+                                       s4ptr = iptr->val.a;
+                                       block[block_index[*s4ptr++]].pre_count++;   /* default */
+                                       i = *s4ptr++;                               /* count   */
+                                       while (--i >= 0) {
+                                               block[block_index[s4ptr[1]]].pre_count++;
+                                               s4ptr += 2;
+                                               }
+                                       break;
+                               default:
+                                       bptr[1].pre_count++;
+                                       break;
+                               }
+                       }
+               bptr++;
+               }
+#endif
+
+
+       do {
+               loops++;
+               b_count = block_count;
+               bptr = block;
+               superblockend = true;
+               repeat = false;
+               STACKRESET;
+               deadcode = true;
+               while (--b_count >= 0) {
+                       if (bptr->flags == BBDELETED) {
+                               /* do nothing */
+                               }
+                       else if (superblockend && (bptr->flags < BBREACHED))
+                               repeat = true;
+                       else if (bptr->flags <= BBREACHED) {
+                               if (superblockend)
+                                       stackdepth = bptr->indepth;
+                               else if (bptr->flags < BBREACHED) {
+                                       COPYCURSTACK(copy);
+                                       bptr->instack = copy;
+                                       bptr->indepth = stackdepth;
+                                       }
+                               else if (bptr->indepth != stackdepth) {
+                                       show_icmd_method();
+                                       panic("Stack depth mismatch");
+                                       
+                                       }
+                               curstack = bptr->instack;
+                               deadcode = false;
+                               superblockend = false;
+                               bptr->flags = BBFINISHED;
+                               len = bptr->icount;
+                               iptr = bptr->iinstr;
+                               b_index = bptr - block;
+                               while (--len >= 0)  {
+                                       opcode = iptr->opc;
+                                       switch (opcode) {
+
+                                               /* pop 0 push 0 */
+
+                                               case ICMD_NOP:
+                                               case ICMD_CHECKASIZE:
+
+                                               case ICMD_IFEQ_ICONST:
+                                               case ICMD_IFNE_ICONST:
+                                               case ICMD_IFLT_ICONST:
+                                               case ICMD_IFGE_ICONST:
+                                               case ICMD_IFGT_ICONST:
+                                               case ICMD_IFLE_ICONST:
+                                               case ICMD_ELSE_ICONST:
+                                                       SETDST;
+                                                       break;
+
+                                               case ICMD_RET:
+                                                       locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
+                                               case ICMD_RETURN:
+                                                       COUNT(count_pcmd_return);
+                                                       SETDST;
+                                                       superblockend = true;
+                                                       break;
+
+                                               /* pop 0 push 1 const */
+                                               
+                                               case ICMD_ICONST:
+                                                       COUNT(count_pcmd_load);
+                                                       if (len > 0) {
+                                                               switch (iptr[1].opc) {
+                                                                       case ICMD_IADD:
+                                                                               iptr[0].opc = ICMD_IADDCONST;
+icmd_iconst_tail:
+                                                                               iptr[1].opc = ICMD_NOP;
+                                                                               OP1_1(TYPE_INT,TYPE_INT);
+                                                                               COUNT(count_pcmd_op);
+                                                                               break;
+                                                                       case ICMD_ISUB:
+                                                                               iptr[0].opc = ICMD_ISUBCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IMUL:
+                                                                               iptr[0].opc = ICMD_IMULCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IDIV:
+                                                                               if (iptr[0].val.i == 0x00000002)
+                                                                                       iptr[0].val.i = 1;
+                                                                               else if (iptr[0].val.i == 0x00000004)
+                                                                                       iptr[0].val.i = 2;
+                                                                               else if (iptr[0].val.i == 0x00000008)
+                                                                                       iptr[0].val.i = 3;
+                                                                               else if (iptr[0].val.i == 0x00000010)
+                                                                                       iptr[0].val.i = 4;
+                                                                               else if (iptr[0].val.i == 0x00000020)
+                                                                                       iptr[0].val.i = 5;
+                                                                               else if (iptr[0].val.i == 0x00000040)
+                                                                                       iptr[0].val.i = 6;
+                                                                               else if (iptr[0].val.i == 0x00000080)
+                                                                                       iptr[0].val.i = 7;
+                                                                               else if (iptr[0].val.i == 0x00000100)
+                                                                                       iptr[0].val.i = 8;
+                                                                               else if (iptr[0].val.i == 0x00000200)
+                                                                                       iptr[0].val.i = 9;
+                                                                               else if (iptr[0].val.i == 0x00000400)
+                                                                                       iptr[0].val.i = 10;
+                                                                               else if (iptr[0].val.i == 0x00000800)
+                                                                                       iptr[0].val.i = 11;
+                                                                               else if (iptr[0].val.i == 0x00001000)
+                                                                                       iptr[0].val.i = 12;
+                                                                               else if (iptr[0].val.i == 0x00002000)
+                                                                                       iptr[0].val.i = 13;
+                                                                               else if (iptr[0].val.i == 0x00004000)
+                                                                                       iptr[0].val.i = 14;
+                                                                               else if (iptr[0].val.i == 0x00008000)
+                                                                                       iptr[0].val.i = 15;
+                                                                               else if (iptr[0].val.i == 0x00010000)
+                                                                                       iptr[0].val.i = 16;
+                                                                               else if (iptr[0].val.i == 0x00020000)
+                                                                                       iptr[0].val.i = 17;
+                                                                               else if (iptr[0].val.i == 0x00040000)
+                                                                                       iptr[0].val.i = 18;
+                                                                               else if (iptr[0].val.i == 0x00080000)
+                                                                                       iptr[0].val.i = 19;
+                                                                               else if (iptr[0].val.i == 0x00100000)
+                                                                                       iptr[0].val.i = 20;
+                                                                               else if (iptr[0].val.i == 0x00200000)
+                                                                                       iptr[0].val.i = 21;
+                                                                               else if (iptr[0].val.i == 0x00400000)
+                                                                                       iptr[0].val.i = 22;
+                                                                               else if (iptr[0].val.i == 0x00800000)
+                                                                                       iptr[0].val.i = 23;
+                                                                               else if (iptr[0].val.i == 0x01000000)
+                                                                                       iptr[0].val.i = 24;
+                                                                               else if (iptr[0].val.i == 0x02000000)
+                                                                                       iptr[0].val.i = 25;
+                                                                               else if (iptr[0].val.i == 0x04000000)
+                                                                                       iptr[0].val.i = 26;
+                                                                               else if (iptr[0].val.i == 0x08000000)
+                                                                                       iptr[0].val.i = 27;
+                                                                               else if (iptr[0].val.i == 0x10000000)
+                                                                                       iptr[0].val.i = 28;
+                                                                               else if (iptr[0].val.i == 0x20000000)
+                                                                                       iptr[0].val.i = 29;
+                                                                               else if (iptr[0].val.i == 0x40000000)
+                                                                                       iptr[0].val.i = 30;
+                                                                               else if (iptr[0].val.i == 0x80000000)
+                                                                                       iptr[0].val.i = 31;
+                                                                               else {
+                                                                                       PUSHCONST(TYPE_INT);
+                                                                                       break;
+                                                                                       }
+                                                                               iptr[0].opc = ICMD_IDIVPOW2;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IREM:
+                                                                               if (iptr[0].val.i == 0x10001) {
+                                                                                       iptr[0].opc = ICMD_IREM0X10001;
+                                                                                       goto icmd_iconst_tail;
+                                                                                       }
+                                                                               if ((iptr[0].val.i == 0x00000002) ||
+                                                                                   (iptr[0].val.i == 0x00000004) ||
+                                                                                   (iptr[0].val.i == 0x00000008) ||
+                                                                                   (iptr[0].val.i == 0x00000010) ||
+                                                                                   (iptr[0].val.i == 0x00000020) ||
+                                                                                   (iptr[0].val.i == 0x00000040) ||
+                                                                                   (iptr[0].val.i == 0x00000080) ||
+                                                                                   (iptr[0].val.i == 0x00000100) ||
+                                                                                   (iptr[0].val.i == 0x00000200) ||
+                                                                                   (iptr[0].val.i == 0x00000400) ||
+                                                                                   (iptr[0].val.i == 0x00000800) ||
+                                                                                   (iptr[0].val.i == 0x00001000) ||
+                                                                                   (iptr[0].val.i == 0x00002000) ||
+                                                                                   (iptr[0].val.i == 0x00004000) ||
+                                                                                   (iptr[0].val.i == 0x00008000) ||
+                                                                                   (iptr[0].val.i == 0x00010000) ||
+                                                                                   (iptr[0].val.i == 0x00020000) ||
+                                                                                   (iptr[0].val.i == 0x00040000) ||
+                                                                                   (iptr[0].val.i == 0x00080000) ||
+                                                                                   (iptr[0].val.i == 0x00100000) ||
+                                                                                   (iptr[0].val.i == 0x00200000) ||
+                                                                                   (iptr[0].val.i == 0x00400000) ||
+                                                                                   (iptr[0].val.i == 0x00800000) ||
+                                                                                   (iptr[0].val.i == 0x01000000) ||
+                                                                                   (iptr[0].val.i == 0x02000000) ||
+                                                                                   (iptr[0].val.i == 0x04000000) ||
+                                                                                   (iptr[0].val.i == 0x08000000) ||
+                                                                                   (iptr[0].val.i == 0x10000000) ||
+                                                                                   (iptr[0].val.i == 0x20000000) ||
+                                                                                   (iptr[0].val.i == 0x40000000) ||
+                                                                                   (iptr[0].val.i == 0x80000000)) {
+                                                                                       iptr[0].opc = ICMD_IREMPOW2;
+                                                                                       iptr[0].val.i -= 1;
+                                                                                       goto icmd_iconst_tail;
+                                                                                       }
+                                                                               PUSHCONST(TYPE_INT);
+                                                                               break;
+                                                                       case ICMD_IAND:
+                                                                               iptr[0].opc = ICMD_IANDCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IOR:
+                                                                               iptr[0].opc = ICMD_IORCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IXOR:
+                                                                               iptr[0].opc = ICMD_IXORCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_ISHL:
+                                                                               iptr[0].opc = ICMD_ISHLCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_ISHR:
+                                                                               iptr[0].opc = ICMD_ISHRCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IUSHR:
+                                                                               iptr[0].opc = ICMD_IUSHRCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IF_ICMPEQ:
+                                                                               iptr[0].opc = ICMD_IFEQ;
+icmd_if_icmp_tail:
+                                                                               iptr[0].op1 = iptr[1].op1;
+                                                                               bptr->icount--;
+                                                                               len--;
+                                                                               /* iptr[1].opc = ICMD_NOP; */
+                                                                               OP1_0(TYPE_INT);
+                                                                               tbptr = block + block_index[iptr->op1];
+                                                                               MARKREACHED(tbptr, copy);
+                                                                               COUNT(count_pcmd_bra);
+                                                                               break;
+                                                                       case ICMD_IF_ICMPLT:
+                                                                               iptr[0].opc = ICMD_IFLT;
+                                                                               goto icmd_if_icmp_tail;
+                                                                       case ICMD_IF_ICMPLE:
+                                                                               iptr[0].opc = ICMD_IFLE;
+                                                                               goto icmd_if_icmp_tail;
+                                                                       case ICMD_IF_ICMPNE:
+                                                                               iptr[0].opc = ICMD_IFNE;
+                                                                               goto icmd_if_icmp_tail;
+                                                                       case ICMD_IF_ICMPGT:
+                                                                               iptr[0].opc = ICMD_IFGT;
+                                                                               goto icmd_if_icmp_tail;
+                                                                       case ICMD_IF_ICMPGE:
+                                                                               iptr[0].opc = ICMD_IFGE;
+                                                                               goto icmd_if_icmp_tail;
+                                                                       default:
+                                                                               PUSHCONST(TYPE_INT);
+                                                                       }
+                                                               }
+                                                       else
+                                                               PUSHCONST(TYPE_INT);
+                                                       break;
+                                               case ICMD_LCONST:
+                                                       COUNT(count_pcmd_load);
+                                                       if (len > 0) {
+                                                               switch (iptr[1].opc) {
+                                                                       case ICMD_LADD:
+                                                                               iptr[0].opc = ICMD_LADDCONST;
+icmd_lconst_tail:
+                                                                               iptr[1].opc = ICMD_NOP;
+                                                                               OP1_1(TYPE_LNG,TYPE_LNG);
+                                                                               COUNT(count_pcmd_op);
+                                                                               break;
+                                                                       case ICMD_LSUB:
+                                                                               iptr[0].opc = ICMD_LSUBCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LMUL:
+                                                                               iptr[0].opc = ICMD_LMULCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LDIV:
+                                                                               if (iptr[0].val.l == 0x00000002)
+                                                                                       iptr[0].val.l = 1;
+                                                                               else if (iptr[0].val.l == 0x00000004)
+                                                                                       iptr[0].val.l = 2;
+                                                                               else if (iptr[0].val.l == 0x00000008)
+                                                                                       iptr[0].val.l = 3;
+                                                                               else if (iptr[0].val.l == 0x00000010)
+                                                                                       iptr[0].val.l = 4;
+                                                                               else if (iptr[0].val.l == 0x00000020)
+                                                                                       iptr[0].val.l = 5;
+                                                                               else if (iptr[0].val.l == 0x00000040)
+                                                                                       iptr[0].val.l = 6;
+                                                                               else if (iptr[0].val.l == 0x00000080)
+                                                                                       iptr[0].val.l = 7;
+                                                                               else if (iptr[0].val.l == 0x00000100)
+                                                                                       iptr[0].val.l = 8;
+                                                                               else if (iptr[0].val.l == 0x00000200)
+                                                                                       iptr[0].val.l = 9;
+                                                                               else if (iptr[0].val.l == 0x00000400)
+                                                                                       iptr[0].val.l = 10;
+                                                                               else if (iptr[0].val.l == 0x00000800)
+                                                                                       iptr[0].val.l = 11;
+                                                                               else if (iptr[0].val.l == 0x00001000)
+                                                                                       iptr[0].val.l = 12;
+                                                                               else if (iptr[0].val.l == 0x00002000)
+                                                                                       iptr[0].val.l = 13;
+                                                                               else if (iptr[0].val.l == 0x00004000)
+                                                                                       iptr[0].val.l = 14;
+                                                                               else if (iptr[0].val.l == 0x00008000)
+                                                                                       iptr[0].val.l = 15;
+                                                                               else if (iptr[0].val.l == 0x00010000)
+                                                                                       iptr[0].val.l = 16;
+                                                                               else if (iptr[0].val.l == 0x00020000)
+                                                                                       iptr[0].val.l = 17;
+                                                                               else if (iptr[0].val.l == 0x00040000)
+                                                                                       iptr[0].val.l = 18;
+                                                                               else if (iptr[0].val.l == 0x00080000)
+                                                                                       iptr[0].val.l = 19;
+                                                                               else if (iptr[0].val.l == 0x00100000)
+                                                                                       iptr[0].val.l = 20;
+                                                                               else if (iptr[0].val.l == 0x00200000)
+                                                                                       iptr[0].val.l = 21;
+                                                                               else if (iptr[0].val.l == 0x00400000)
+                                                                                       iptr[0].val.l = 22;
+                                                                               else if (iptr[0].val.l == 0x00800000)
+                                                                                       iptr[0].val.l = 23;
+                                                                               else if (iptr[0].val.l == 0x01000000)
+                                                                                       iptr[0].val.l = 24;
+                                                                               else if (iptr[0].val.l == 0x02000000)
+                                                                                       iptr[0].val.l = 25;
+                                                                               else if (iptr[0].val.l == 0x04000000)
+                                                                                       iptr[0].val.l = 26;
+                                                                               else if (iptr[0].val.l == 0x08000000)
+                                                                                       iptr[0].val.l = 27;
+                                                                               else if (iptr[0].val.l == 0x10000000)
+                                                                                       iptr[0].val.l = 28;
+                                                                               else if (iptr[0].val.l == 0x20000000)
+                                                                                       iptr[0].val.l = 29;
+                                                                               else if (iptr[0].val.l == 0x40000000)
+                                                                                       iptr[0].val.l = 30;
+                                                                               else if (iptr[0].val.l == 0x80000000)
+                                                                                       iptr[0].val.l = 31;
+                                                                               else {
+                                                                                       PUSHCONST(TYPE_LNG);
+                                                                                       break;
+                                                                                       }
+                                                                               iptr[0].opc = ICMD_LDIVPOW2;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LREM:
+                                                                               if (iptr[0].val.l == 0x10001) {
+                                                                                       iptr[0].opc = ICMD_LREM0X10001;
+                                                                                       goto icmd_lconst_tail;
+                                                                                       }
+                                                                               if ((iptr[0].val.l == 0x00000002) ||
+                                                                                   (iptr[0].val.l == 0x00000004) ||
+                                                                                   (iptr[0].val.l == 0x00000008) ||
+                                                                                   (iptr[0].val.l == 0x00000010) ||
+                                                                                   (iptr[0].val.l == 0x00000020) ||
+                                                                                   (iptr[0].val.l == 0x00000040) ||
+                                                                                   (iptr[0].val.l == 0x00000080) ||
+                                                                                   (iptr[0].val.l == 0x00000100) ||
+                                                                                   (iptr[0].val.l == 0x00000200) ||
+                                                                                   (iptr[0].val.l == 0x00000400) ||
+                                                                                   (iptr[0].val.l == 0x00000800) ||
+                                                                                   (iptr[0].val.l == 0x00001000) ||
+                                                                                   (iptr[0].val.l == 0x00002000) ||
+                                                                                   (iptr[0].val.l == 0x00004000) ||
+                                                                                   (iptr[0].val.l == 0x00008000) ||
+                                                                                   (iptr[0].val.l == 0x00010000) ||
+                                                                                   (iptr[0].val.l == 0x00020000) ||
+                                                                                   (iptr[0].val.l == 0x00040000) ||
+                                                                                   (iptr[0].val.l == 0x00080000) ||
+                                                                                   (iptr[0].val.l == 0x00100000) ||
+                                                                                   (iptr[0].val.l == 0x00200000) ||
+                                                                                   (iptr[0].val.l == 0x00400000) ||
+                                                                                   (iptr[0].val.l == 0x00800000) ||
+                                                                                   (iptr[0].val.l == 0x01000000) ||
+                                                                                   (iptr[0].val.l == 0x02000000) ||
+                                                                                   (iptr[0].val.l == 0x04000000) ||
+                                                                                   (iptr[0].val.l == 0x08000000) ||
+                                                                                   (iptr[0].val.l == 0x10000000) ||
+                                                                                   (iptr[0].val.l == 0x20000000) ||
+                                                                                   (iptr[0].val.l == 0x40000000) ||
+                                                                                   (iptr[0].val.l == 0x80000000)) {
+                                                                                       iptr[0].opc = ICMD_LREMPOW2;
+                                                                                       iptr[0].val.l -= 1;
+                                                                                       goto icmd_lconst_tail;
+                                                                                       }
+                                                                               PUSHCONST(TYPE_LNG);
+                                                                               break;
+                                                                       case ICMD_LAND:
+                                                                               iptr[0].opc = ICMD_LANDCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LOR:
+                                                                               iptr[0].opc = ICMD_LORCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LXOR:
+                                                                               iptr[0].opc = ICMD_LXORCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LSHL:
+                                                                               iptr[0].opc = ICMD_LSHLCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LSHR:
+                                                                               iptr[0].opc = ICMD_LSHRCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LUSHR:
+                                                                               iptr[0].opc = ICMD_LUSHRCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LCMP:
+                                                                               if ((len > 1) && (iptr[2].val.i == 0)) {
+                                                                                       switch (iptr[2].opc) {
+                                                                                       case ICMD_IFEQ:
+                                                                                               iptr[0].opc = ICMD_IF_LEQ;
+icmd_lconst_lcmp_tail:
+                                                                                               iptr[0].op1 = iptr[2].op1;
+                                                                                               bptr->icount -= 2;
+                                                                                               len -= 2;
+                                                                                               /* iptr[1].opc = ICMD_NOP;
+                                                                                               iptr[2].opc = ICMD_NOP; */
+                                                                                               OP1_0(TYPE_LNG);
+                                                                                               tbptr = block + block_index[iptr->op1];
+                                                                                               MARKREACHED(tbptr, copy);
+                                                                                               COUNT(count_pcmd_bra);
+                                                                                               COUNT(count_pcmd_op);
+                                                                                               break;
+                                                                                       case ICMD_IFNE:
+                                                                                               iptr[0].opc = ICMD_IF_LNE;
+                                                                                               goto icmd_lconst_lcmp_tail;
+                                                                                       case ICMD_IFLT:
+                                                                                               iptr[0].opc = ICMD_IF_LLT;
+                                                                                               goto icmd_lconst_lcmp_tail;
+                                                                                       case ICMD_IFGT:
+                                                                                               iptr[0].opc = ICMD_IF_LGT;
+                                                                                               goto icmd_lconst_lcmp_tail;
+                                                                                       case ICMD_IFLE:
+                                                                                               iptr[0].opc = ICMD_IF_LLE;
+                                                                                               goto icmd_lconst_lcmp_tail;
+                                                                                       case ICMD_IFGE:
+                                                                                               iptr[0].opc = ICMD_IF_LGE;
+                                                                                               goto icmd_lconst_lcmp_tail;
+                                                                                       default:
+                                                                                               PUSHCONST(TYPE_LNG);
+                                                                                       } /* switch (iptr[2].opc) */
+                                                                                       } /* if (iptr[2].val.i == 0) */
+                                                                               else
+                                                                                       PUSHCONST(TYPE_LNG);
+                                                                               break;
+                                                                       default:
+                                                                               PUSHCONST(TYPE_LNG);
+                                                                       }
+                                                               }
+                                                       else
+                                                               PUSHCONST(TYPE_LNG);
+                                                       break;
+                                               case ICMD_FCONST:
+                                                       COUNT(count_pcmd_load);
+                                                       PUSHCONST(TYPE_FLT);
+                                                       break;
+                                               case ICMD_DCONST:
+                                                       COUNT(count_pcmd_load);
+                                                       PUSHCONST(TYPE_DBL);
+                                                       break;
+                                               case ICMD_ACONST:
+                                                       COUNT(count_pcmd_load);
+                                                       PUSHCONST(TYPE_ADR);
+                                                       break;
+
+                                               /* pop 0 push 1 load */
+                                               
+                                               case ICMD_ILOAD:
+                                               case ICMD_LLOAD:
+                                               case ICMD_FLOAD:
+                                               case ICMD_DLOAD:
+                                               case ICMD_ALOAD:
+                                                       COUNT(count_load_instruction);
+                                                       i = opcode-ICMD_ILOAD;
+                                                       locals[iptr->op1][i].type = i;
+                                                       LOAD(i, LOCALVAR, iptr->op1);
+                                                       break;
+
+                                               /* pop 2 push 1 */
+
+                                               case ICMD_IALOAD:
+                                               case ICMD_LALOAD:
+                                               case ICMD_FALOAD:
+                                               case ICMD_DALOAD:
+                                               case ICMD_AALOAD:
+                                                       COUNT(count_check_null);
+                                                       COUNT(count_check_bound);
+                                                       COUNT(count_pcmd_mem);
+                                                       OP2IAT_1(opcode-ICMD_IALOAD);
+                                                       break;
+
+                                               case ICMD_BALOAD:
+                                               case ICMD_CALOAD:
+                                               case ICMD_SALOAD:
+                                                       COUNT(count_check_null);
+                                                       COUNT(count_check_bound);
+                                                       COUNT(count_pcmd_mem);
+                                                       OP2IAT_1(TYPE_INT);
+                                                       break;
+
+                                               /* pop 0 push 0 iinc */
+
+                                               case ICMD_IINC:
+#ifdef STATISTICS
+                                                       i = stackdepth;
+                                                       if (i >= 10)
+                                                               count_store_depth[10]++;
+                                                       else
+                                                               count_store_depth[i]++;
+#endif
+                                                       copy = curstack;
+                                                       i = stackdepth - 1;
+                                                       while (copy) {
+                                                               if ((copy->varkind == LOCALVAR) &&
+                                                                   (copy->varnum == curstack->varnum)) {
+                                                                       copy->varkind = TEMPVAR;
+                                                                       copy->varnum = i;
+                                                                       }
+                                                               i--;
+                                                               copy = copy->prev;
+                                                               }
+                                                       SETDST;
+                                                       break;
+
+                                               /* pop 1 push 0 store */
+
+                                               case ICMD_ISTORE:
+                                               case ICMD_LSTORE:
+                                               case ICMD_FSTORE:
+                                               case ICMD_DSTORE:
+                                               case ICMD_ASTORE:
+                                                       i = opcode-ICMD_ISTORE;
+                                                       locals[iptr->op1][i].type = i;
+#ifdef STATISTICS
+                                                       count_pcmd_store++;
+                                                       i = new - curstack;
+                                                       if (i >= 20)
+                                                               count_store_length[20]++;
+                                                       else
+                                                               count_store_length[i]++;
+                                                       i = stackdepth - 1;
+                                                       if (i >= 10)
+                                                               count_store_depth[10]++;
+                                                       else
+                                                               count_store_depth[i]++;
+#endif
+                                                       copy = curstack->prev;
+                                                       i = stackdepth - 2;
+                                                       while (copy) {
+                                                               if ((copy->varkind == LOCALVAR) &&
+                                                                   (copy->varnum == curstack->varnum)) {
+                                                                       copy->varkind = TEMPVAR;
+                                                                       copy->varnum = i;
+                                                                       }
+                                                               i--;
+                                                               copy = copy->prev;
+                                                               }
+                                                       if ((new - curstack) == 1) {
+                                                               curstack->varkind = LOCALVAR;
+                                                               curstack->varnum = iptr->op1;
+                                                               };
+                                                       STORE(opcode-ICMD_ISTORE);
+                                                       break;
+
+                                               /* pop 3 push 0 */
+
+                                               case ICMD_IASTORE:
+                                               case ICMD_LASTORE:
+                                               case ICMD_FASTORE:
+                                               case ICMD_DASTORE:
+                                               case ICMD_AASTORE:
+                                                       COUNT(count_check_null);
+                                                       COUNT(count_check_bound);
+                                                       COUNT(count_pcmd_mem);
+                                                       OP3TIA_0(opcode-ICMD_IASTORE);
+                                                       break;
+                                               case ICMD_BASTORE:
+                                               case ICMD_CASTORE:
+                                               case ICMD_SASTORE:
+                                                       COUNT(count_check_null);
+                                                       COUNT(count_check_bound);
+                                                       COUNT(count_pcmd_mem);
+                                                       OP3TIA_0(TYPE_INT);
+                                                       break;
+
+                                               /* pop 1 push 0 */
+
+                                               case ICMD_POP:
+                                                       OP1_0ANY;
+                                                       break;
+
+                                               case ICMD_IRETURN:
+                                               case ICMD_LRETURN:
+                                               case ICMD_FRETURN:
+                                               case ICMD_DRETURN:
+                                               case ICMD_ARETURN:
+                                                       COUNT(count_pcmd_return);
+                                                       OP1_0(opcode-ICMD_IRETURN);
+                                                       superblockend = true;
+                                                       break;
+
+                                               case ICMD_ATHROW:
+                                                       COUNT(count_check_null);
+                                                       OP1_0(TYPE_ADR);
+                                                       STACKRESET;
+                                                       SETDST;
+                                                       superblockend = true;
+                                                       break;
+
+                                               case ICMD_PUTSTATIC:
+                                                       COUNT(count_pcmd_mem);
+                                                       OP1_0(iptr->op1);
+                                                       break;
+
+                                               /* pop 1 push 0 branch */
+
+                                               case ICMD_IFNULL:
+                                               case ICMD_IFNONNULL:
+                                                       COUNT(count_pcmd_bra);
+                                                       OP1_0(TYPE_ADR);
+                                                       tbptr = block + block_index[iptr->op1];
+                                                       MARKREACHED(tbptr, copy);
+                                                       break;
+
+                                               case ICMD_IFEQ:
+                                               case ICMD_IFNE:
+                                               case ICMD_IFLT:
+                                               case ICMD_IFGE:
+                                               case ICMD_IFGT:
+                                               case ICMD_IFLE:
+                                                       COUNT(count_pcmd_bra);
+#ifdef CONDITIONAL_LOADCONST
+                                                       {
+                                                       tbptr = block + b_index;
+                                                       if ((b_count >= 3) &&
+                                                           ((b_index + 2) == block_index[iptr[0].op1]) &&
+                                                           (tbptr[1].pre_count == 1) &&
+                                                           (iptr[1].opc == ICMD_ICONST) &&
+                                                           (iptr[2].opc == ICMD_GOTO)   &&
+                                                           ((b_index + 3) == block_index[iptr[2].op1]) &&
+                                                           (tbptr[2].pre_count == 1) &&
+                                                           (iptr[3].opc == ICMD_ICONST)) {
+                                                               OP1_1(TYPE_INT, TYPE_INT);
+                                                               switch (iptr[0].opc) {
+                                                                       case ICMD_IFEQ:
+                                                                               iptr[0].opc = ICMD_IFNE_ICONST;
+                                                                               break;
+                                                                       case ICMD_IFNE:
+                                                                               iptr[0].opc = ICMD_IFEQ_ICONST;
+                                                                               break;
+                                                                       case ICMD_IFLT:
+                                                                               iptr[0].opc = ICMD_IFGE_ICONST;
+                                                                               break;
+                                                                       case ICMD_IFGE:
+                                                                               iptr[0].opc = ICMD_IFLT_ICONST;
+                                                                               break;
+                                                                       case ICMD_IFGT:
+                                                                               iptr[0].opc = ICMD_IFLE_ICONST;
+                                                                               break;
+                                                                       case ICMD_IFLE:
+                                                                               iptr[0].opc = ICMD_IFGT_ICONST;
+                                                                               break;
+                                                                       }
+                                                               iptr[0].val.i = iptr[1].val.i;
+                                                               iptr[1].opc = ICMD_ELSE_ICONST;
+                                                               iptr[1].val.i = iptr[3].val.i;
+                                                               iptr[2].opc = ICMD_NOP;
+                                                               iptr[3].opc = ICMD_NOP;
+                                                               tbptr[1].flags = BBDELETED;
+                                                               tbptr[2].flags = BBDELETED;
+                                                               tbptr[1].icount = 0;
+                                                               tbptr[2].icount = 0;
+                                                               if (tbptr[3].pre_count == 2) {
+                                                                       len += tbptr[3].icount + 3;
+                                                                       bptr->icount += tbptr[3].icount + 3;
+                                                                       tbptr[3].flags = BBDELETED;
+                                                                       tbptr[3].icount = 0;
+                                                                       b_index++;
+                                                                       }
+                                                               else {
+                                                                       bptr->icount++;
+                                                                       len ++;
+                                                                       }
+                                                               b_index += 2;
+                                                               break;
+                                                               }
+                                                       }
+#endif
+                                                       OP1_0(TYPE_INT);
+                                                       tbptr = block + block_index[iptr->op1];
+                                                       MARKREACHED(tbptr, copy);
+                                                       break;
+
+                                               /* pop 0 push 0 branch */
+
+                                               case ICMD_GOTO:
+                                                       COUNT(count_pcmd_bra);
+                                                       tbptr = block + block_index[iptr->op1];
+                                                       MARKREACHED(tbptr, copy);
+                                                       SETDST;
+                                                       superblockend = true;
+                                                       break;
+
+                                               /* pop 1 push 0 table branch */
+
+                                               case ICMD_TABLESWITCH:
+                                                       COUNT(count_pcmd_table);
+                                                       OP1_0(TYPE_INT);
+                                                       s4ptr = iptr->val.a;
+                                                       tbptr = block + block_index[*s4ptr++]; /* default */
+                                                       MARKREACHED(tbptr, copy);
+                                                       i = *s4ptr++;                          /* low     */
+                                                       i = *s4ptr++ - i + 1;                  /* high    */
+                                                       while (--i >= 0) {
+                                                               tbptr = block + block_index[*s4ptr++];
+                                                               MARKREACHED(tbptr, copy);
+                                                               }
+                                                       SETDST;
+                                                       superblockend = true;
+                                                       break;
+                                                       
+                                               /* pop 1 push 0 table branch */
+
+                                               case ICMD_LOOKUPSWITCH:
+                                                       COUNT(count_pcmd_table);
+                                                       OP1_0(TYPE_INT);
+                                                       s4ptr = iptr->val.a;
+                                                       tbptr = block + block_index[*s4ptr++]; /* default */
+                                                       MARKREACHED(tbptr, copy);
+                                                       i = *s4ptr++;                          /* count   */
+                                                       while (--i >= 0) {
+                                                               tbptr = block + block_index[s4ptr[1]];
+                                                               MARKREACHED(tbptr, copy);
+                                                               s4ptr += 2;
+                                                               }
+                                                       SETDST;
+                                                       superblockend = true;
+                                                       break;
+
+                                               case ICMD_NULLCHECKPOP:
+                                               case ICMD_MONITORENTER:
+                                                       COUNT(count_check_null);
+                                               case ICMD_MONITOREXIT:
+                                                       OP1_0(TYPE_ADR);
+                                                       break;
+
+                                               /* pop 2 push 0 branch */
+
+                                               case ICMD_IF_ICMPEQ:
+                                               case ICMD_IF_ICMPNE:
+                                               case ICMD_IF_ICMPLT:
+                                               case ICMD_IF_ICMPGE:
+                                               case ICMD_IF_ICMPGT:
+                                               case ICMD_IF_ICMPLE:
+                                                       COUNT(count_pcmd_bra);
+                                                       OP2_0(TYPE_INT);
+                                                       tbptr = block + block_index[iptr->op1];
+                                                       MARKREACHED(tbptr, copy);
+                                                       break;
+
+                                               case ICMD_IF_ACMPEQ:
+                                               case ICMD_IF_ACMPNE:
+                                                       COUNT(count_pcmd_bra);
+                                                       OP2_0(TYPE_ADR);
+                                                       tbptr = block + block_index[iptr->op1];
+                                                       MARKREACHED(tbptr, copy);
+                                                       break;
+
+                                               /* pop 2 push 0 */
+
+                                               case ICMD_PUTFIELD:
+                                                       COUNT(count_check_null);
+                                                       COUNT(count_pcmd_mem);
+                                                       OPTT2_0(iptr->op1,TYPE_ADR);
+                                                       break;
+
+                                               case ICMD_POP2:
+                                                       if (! IS_2_WORD_TYPE(curstack->type)) {
+                                                               OP1_0ANY;                /* second pop */
+                                                               }
+                                                       else
+                                                               iptr->opc = ICMD_POP;
+                                                       OP1_0ANY;
+                                                       break;
+
+                                               /* pop 0 push 1 dup */
+                                               
+                                               case ICMD_DUP:
+                                                       COUNT(count_dup_instruction);
+                                                       DUP;
+                                                       break;
+
+                                               case ICMD_DUP2:
+                                                       if (IS_2_WORD_TYPE(curstack->type)) {
+                                                               iptr->opc = ICMD_DUP;
+                                                               DUP;
+                                                               }
+                                                       else {
+                                                               copy = curstack;
+                                                               NEWSTACK(copy[-1].type, copy[-1].varkind,
+                                                                        copy[-1].varnum);
+                                                               NEWSTACK(copy[ 0].type, copy[ 0].varkind,
+                                                                        copy[ 0].varnum);
+                                                               SETDST;
+                                                               stackdepth+=2;
+                                                               }
+                                                       break;
+
+                                               /* pop 2 push 3 dup */
+                                               
+                                               case ICMD_DUP_X1:
+                                                       DUP_X1;
+                                                       break;
+
+                                               case ICMD_DUP2_X1:
+                                                       if (IS_2_WORD_TYPE(curstack->type)) {
+                                                               iptr->opc = ICMD_DUP_X1;
+                                                               DUP_X1;
+                                                               }
+                                                       else {
+                                                               DUP2_X1;
+                                                               }
+                                                       break;
+
+                                               /* pop 3 push 4 dup */
+                                               
+                                               case ICMD_DUP_X2:
+                                                       if (IS_2_WORD_TYPE(curstack[-1].type)) {
+                                                               iptr->opc = ICMD_DUP_X1;
+                                                               DUP_X1;
+                                                               }
+                                                       else {
+                                                               DUP_X2;
+                                                               }
+                                                       break;
+
+                                               case ICMD_DUP2_X2:
+                                                       if (IS_2_WORD_TYPE(curstack->type)) {
+                                                               if (IS_2_WORD_TYPE(curstack[-1].type)) {
+                                                                       iptr->opc = ICMD_DUP_X1;
+                                                                       DUP_X1;
+                                                                       }
+                                                               else {
+                                                                       iptr->opc = ICMD_DUP_X2;
+                                                                       DUP_X2;
+                                                                       }
+                                                               }
+                                                       else
+                                                               if (IS_2_WORD_TYPE(curstack[-2].type)) {
+                                                                       iptr->opc = ICMD_DUP2_X1;
+                                                                       DUP2_X1;
+                                                                       }
+                                                               else {
+                                                                       DUP2_X2;
+                                                                       }
+                                                       break;
+
+                                               /* pop 2 push 2 swap */
+                                               
+                                               case ICMD_SWAP:
+                                                       SWAP;
+                                                       break;
+
+                                               /* pop 2 push 1 */
+                                               
+                                               case ICMD_IDIV:
+                                                       if (!(SUPPORT_DIVISION)) {
+                                                               iptr[0].opc = ICMD_BUILTIN2;
+                                                               iptr[0].op1 = TYPE_INT;
+                                                               iptr[0].val.a = (functionptr) asm_builtin_idiv;
+                                                               isleafmethod = false;
+                                                               goto builtin2;
+                                                               }
+
+                                               case ICMD_LDIV:
+                                                       if (!(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_MULDIV)) {
+                                                               iptr[0].opc = ICMD_BUILTIN2;
+                                                               iptr[0].op1 = TYPE_LNG;
+                                                               iptr[0].val.a = (functionptr) asm_builtin_ldiv;
+                                                               isleafmethod = false;
+                                                               goto builtin2;
+                                                               }
+
+                                               case ICMD_IREM:
+                                                       if (!(SUPPORT_DIVISION)) {
+                                                               iptr[0].opc = ICMD_BUILTIN2;
+                                                               iptr[0].op1 = TYPE_INT;
+                                                               iptr[0].val.a = (functionptr) asm_builtin_irem;
+                                                               isleafmethod = false;
+                                                               goto builtin2;
+                                                               }
+
+                                               case ICMD_LREM:
+                                                       if (!(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_MULDIV)) {
+                                                               iptr[0].opc = ICMD_BUILTIN2;
+                                                               iptr[0].op1 = TYPE_LNG;
+                                                               iptr[0].val.a = (functionptr) asm_builtin_lrem;
+                                                               isleafmethod = false;
+                                                               goto builtin2;
+                                                               }
+
+                                               case ICMD_IADD:
+                                               case ICMD_ISUB:
+                                               case ICMD_IMUL:
+
+                                               case ICMD_ISHL:
+                                               case ICMD_ISHR:
+                                               case ICMD_IUSHR:
+                                               case ICMD_IAND:
+                                               case ICMD_IOR:
+                                               case ICMD_IXOR:
+                                                       COUNT(count_pcmd_op);
+                                                       OP2_1(TYPE_INT);
+                                                       break;
+
+                                               case ICMD_LADD:
+                                               case ICMD_LSUB:
+                                               case ICMD_LMUL:
+
+                                               case ICMD_LOR:
+                                               case ICMD_LAND:
+                                               case ICMD_LXOR:
+                                                       COUNT(count_pcmd_op);
+                                                       OP2_1(TYPE_LNG);
+                                                       break;
+
+                                               case ICMD_LSHL:
+                                               case ICMD_LSHR:
+                                               case ICMD_LUSHR:
+                                                       COUNT(count_pcmd_op);
+                                                       OP2IT_1(TYPE_LNG);
+                                                       break;
+
+                                               case ICMD_FADD:
+                                               case ICMD_FSUB:
+                                               case ICMD_FMUL:
+                                               case ICMD_FDIV:
+                                               case ICMD_FREM:
+                                                       COUNT(count_pcmd_op);
+                                                       OP2_1(TYPE_FLT);
+                                                       break;
+
+                                               case ICMD_DADD:
+                                               case ICMD_DSUB:
+                                               case ICMD_DMUL:
+                                               case ICMD_DDIV:
+                                               case ICMD_DREM:
+                                                       COUNT(count_pcmd_op);
+                                                       OP2_1(TYPE_DBL);
+                                                       break;
+
+                                               case ICMD_LCMP:
+                                                       COUNT(count_pcmd_op);
+                                                       if ((len > 0) && (iptr[1].val.i == 0)) {
+                                                               switch (iptr[1].opc) {
+                                                                       case ICMD_IFEQ:
+                                                                               iptr[0].opc = ICMD_IF_LCMPEQ;
+icmd_lcmp_if_tail:
+                                                                               iptr[0].op1 = iptr[1].op1;
+                                                                               len--;
+                                                                               bptr->icount--;
+                                                                               /* iptr[1].opc = ICMD_NOP; */
+                                                                               OP2_0(TYPE_LNG);
+                                                                               tbptr = block + block_index[iptr->op1];
+                                                                               MARKREACHED(tbptr, copy);
+                                                                               COUNT(count_pcmd_bra);
+                                                                               break;
+                                                                       case ICMD_IFNE:
+                                                                               iptr[0].opc = ICMD_IF_LCMPNE;
+                                                                               goto icmd_lcmp_if_tail;
+                                                                       case ICMD_IFLT:
+                                                                               iptr[0].opc = ICMD_IF_LCMPLT;
+                                                                               goto icmd_lcmp_if_tail;
+                                                                       case ICMD_IFGT:
+                                                                               iptr[0].opc = ICMD_IF_LCMPGT;
+                                                                               goto icmd_lcmp_if_tail;
+                                                                       case ICMD_IFLE:
+                                                                               iptr[0].opc = ICMD_IF_LCMPLE;
+                                                                               goto icmd_lcmp_if_tail;
+                                                                       case ICMD_IFGE:
+                                                                               iptr[0].opc = ICMD_IF_LCMPGE;
+                                                                               goto icmd_lcmp_if_tail;
+                                                                       default:
+                                                                               OPTT2_1(TYPE_LNG, TYPE_INT);
+                                                                       }
+                                                               }
+                                                       else
+                                                               OPTT2_1(TYPE_LNG, TYPE_INT);
+                                                       break;
+                                               case ICMD_FCMPL:
+                                               case ICMD_FCMPG:
+                                                       COUNT(count_pcmd_op);
+                                                       OPTT2_1(TYPE_FLT, TYPE_INT);
+                                                       break;
+                                               case ICMD_DCMPL:
+                                               case ICMD_DCMPG:
+                                                       COUNT(count_pcmd_op);
+                                                       OPTT2_1(TYPE_DBL, TYPE_INT);
+                                                       break;
+
+                                               /* pop 1 push 1 */
+                                               
+                                               case ICMD_INEG:
+                                               case ICMD_INT2BYTE:
+                                               case ICMD_INT2CHAR:
+                                               case ICMD_INT2SHORT:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_INT, TYPE_INT);
+                                                       break;
+                                               case ICMD_LNEG:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_LNG, TYPE_LNG);
+                                                       break;
+                                               case ICMD_FNEG:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_FLT, TYPE_FLT);
+                                                       break;
+                                               case ICMD_DNEG:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_DBL, TYPE_DBL);
+                                                       break;
+
+                                               case ICMD_I2L:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_INT, TYPE_LNG);
+                                                       break;
+                                               case ICMD_I2F:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_INT, TYPE_FLT);
+                                                       break;
+                                               case ICMD_I2D:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_INT, TYPE_DBL);
+                                                       break;
+                                               case ICMD_L2I:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_LNG, TYPE_INT);
+                                                       break;
+                                               case ICMD_L2F:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_LNG, TYPE_FLT);
+                                                       break;
+                                               case ICMD_L2D:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_LNG, TYPE_DBL);
+                                                       break;
+                                               case ICMD_F2I:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_FLT, TYPE_INT);
+                                                       break;
+                                               case ICMD_F2L:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_FLT, TYPE_LNG);
+                                                       break;
+                                               case ICMD_F2D:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_FLT, TYPE_DBL);
+                                                       break;
+                                               case ICMD_D2I:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_DBL, TYPE_INT);
+                                                       break;
+                                               case ICMD_D2L:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_DBL, TYPE_LNG);
+                                                       break;
+                                               case ICMD_D2F:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_DBL, TYPE_FLT);
+                                                       break;
+
+                                               case ICMD_CHECKCAST:
+                                                       OP1_1(TYPE_ADR, TYPE_ADR);
+                                                       break;
+
+                                               case ICMD_ARRAYLENGTH:
+                                               case ICMD_INSTANCEOF:
+                                                       OP1_1(TYPE_ADR, TYPE_INT);
+                                                       break;
+
+                                               case ICMD_NEWARRAY:
+                                               case ICMD_ANEWARRAY:
+                                                       OP1_1(TYPE_INT, TYPE_ADR);
+                                                       break;
+
+                                               case ICMD_GETFIELD:
+                                                       COUNT(count_check_null);
+                                                       COUNT(count_pcmd_mem);
+                                                       OP1_1(TYPE_ADR, iptr->op1);
+                                                       break;
+
+                                               /* pop 0 push 1 */
+                                               
+                                               case ICMD_GETSTATIC:
+                                                       COUNT(count_pcmd_mem);
+                                                       OP0_1(iptr->op1);
+                                                       break;
+
+                                               case ICMD_NEW:
+                                                       OP0_1(TYPE_ADR);
+                                                       break;
+
+                                               case ICMD_JSR:
+                                                       OP0_1(TYPE_ADR);
+                                                       tbptr = block + block_index[iptr->op1];
+                                                       tbptr->type=BBTYPE_SBR;
+                                                       MARKREACHED(tbptr, copy);
+                                                       OP1_0ANY;
+                                                       break;
+
+                                               /* pop many push any */
+                                               
+                                               case ICMD_INVOKEVIRTUAL:
+                                               case ICMD_INVOKESPECIAL:
+                                               case ICMD_INVOKEINTERFACE:
+                                               case ICMD_INVOKESTATIC:
+                                                       COUNT(count_pcmd_met);
+                                                       {
+                                                       methodinfo *m = iptr->val.a;
+                                                       if (m->flags & ACC_STATIC)
+                                                               {COUNT(count_check_null);}
+                                                       i = iptr->op1;
+                                                       if (i > arguments_num)
+                                                               arguments_num = i;
+                                                       copy = curstack;
+                                                       while (--i >= 0) {
+                                                               if (! (copy->flags & SAVEDVAR)) {
+                                                                       copy->varkind = ARGVAR;
+                                                                       copy->varnum = i;
+                                                                       }
+                                                               copy = copy->prev;
+                                                               }
+                                                       while (copy) {
+                                                               copy->flags |= SAVEDVAR;
+                                                               copy = copy->prev;
+                                                               }
+                                                       i = iptr->op1;
+                                                       POPMANY(i);
+                                                       if (m->returntype != TYPE_VOID) {
+                                                               OP0_1(m->returntype);
+                                                               }
+                                                       break;
+                                                       }
+
+                                               case ICMD_BUILTIN3:
+                                                       if (! (curstack->flags & SAVEDVAR)) {
+                                                               curstack->varkind = ARGVAR;
+                                                               curstack->varnum = 2;
+                                                               }
+                                                       OP1_0ANY;
+                                               case ICMD_BUILTIN2:
+builtin2:
+                                                       if (! (curstack->flags & SAVEDVAR)) {
+                                                               curstack->varkind = ARGVAR;
+                                                               curstack->varnum = 1;
+                                                               }
+                                                       OP1_0ANY;
+                                               case ICMD_BUILTIN1:
+                                                       if (! (curstack->flags & SAVEDVAR)) {
+                                                               curstack->varkind = ARGVAR;
+                                                               curstack->varnum = 0;
+                                                               }
+                                                       OP1_0ANY;
+                                                       copy = curstack;
+                                                       while (copy) {
+                                                               copy->flags |= SAVEDVAR;
+                                                               copy = copy->prev;
+                                                               }
+                                                       if (iptr->op1 != TYPE_VOID)
+                                                               OP0_1(iptr->op1);
+                                                       break;
+
+                                               case ICMD_MULTIANEWARRAY:
+                                                       i = iptr->op1;
+                                                       if ((i + intreg_argnum) > arguments_num)
+                                                               arguments_num = i + intreg_argnum;
+                                                       copy = curstack;
+                                                       while (--i >= 0) {
+                                                               if (! (copy->flags & SAVEDVAR)) {
+                                                                       copy->varkind = ARGVAR;
+                                                                       copy->varnum = i + intreg_argnum;
+                                                                       }
+                                                               copy = copy->prev;
+                                                               }
+                                                       while (copy) {
+                                                               copy->flags |= SAVEDVAR;
+                                                               copy = copy->prev;
+                                                               }
+                                                       i = iptr->op1;
+                                                       POPMANY(i);
+                                                       OP0_1(TYPE_ADR);
+                                                       break;
+
+                                               default:
+                                                       printf("ICMD %d at %d\n", iptr->opc, (int)(iptr-instr));
+                                                       panic("Missing ICMD code during stack analysis");
+                                               } /* switch */
+                                       iptr++;
+                                       } /* while instructions */
+                               bptr->outstack = curstack;
+                               bptr->outdepth = stackdepth;
+                               BBEND(curstack, i);
+                               } /* if */
+                       else
+                               superblockend = true;
+                       bptr++;
+               } /* while blocks */
+       } while (repeat && ! deadcode);
+
+#ifdef STATISTICS
+       if (block_count > count_max_basic_blocks)
+               count_max_basic_blocks = block_count;
+       count_basic_blocks += block_count;
+       if (instr_count > count_max_javainstr)
+               count_max_javainstr = instr_count;
+       count_javainstr += instr_count;
+       if (stack_count > count_upper_bound_new_stack)
+               count_upper_bound_new_stack = stack_count;
+       if ((new - stack) > count_max_new_stack)
+               count_max_new_stack = (new - stack);
+
+       b_count = block_count;
+       bptr = block;
+       while (--b_count >= 0) {
+               if (bptr->flags > BBREACHED) {
+                       if (bptr->indepth >= 10)
+                               count_block_stack[10]++;
+                       else
+                               count_block_stack[bptr->indepth]++;
+                       len = bptr->icount;
+                       if (len <= 10) 
+                               count_block_size_distribution[len - 1]++;
+                       else if (len <= 12)
+                               count_block_size_distribution[10]++;
+                       else if (len <= 14)
+                               count_block_size_distribution[11]++;
+                       else if (len <= 16)
+                               count_block_size_distribution[12]++;
+                       else if (len <= 18)
+                               count_block_size_distribution[13]++;
+                       else if (len <= 20)
+                               count_block_size_distribution[14]++;
+                       else if (len <= 25)
+                               count_block_size_distribution[15]++;
+                       else if (len <= 30)
+                               count_block_size_distribution[16]++;
+                       else
+                               count_block_size_distribution[17]++;
+                       }
+               bptr++;
+               }
+
+       if (loops == 1)
+               count_analyse_iterations[0]++;
+       else if (loops == 2)
+               count_analyse_iterations[1]++;
+       else if (loops == 3)
+               count_analyse_iterations[2]++;
+       else if (loops == 4)
+               count_analyse_iterations[3]++;
+       else
+               count_analyse_iterations[4]++;
+
+       if (block_count <= 5)
+               count_method_bb_distribution[0]++;
+       else if (block_count <= 10)
+               count_method_bb_distribution[1]++;
+       else if (block_count <= 15)
+               count_method_bb_distribution[2]++;
+       else if (block_count <= 20)
+               count_method_bb_distribution[3]++;
+       else if (block_count <= 30)
+               count_method_bb_distribution[4]++;
+       else if (block_count <= 40)
+               count_method_bb_distribution[5]++;
+       else if (block_count <= 50)
+               count_method_bb_distribution[6]++;
+       else if (block_count <= 75)
+               count_method_bb_distribution[7]++;
+       else
+               count_method_bb_distribution[8]++;
+#endif
+}
+
+
+static void print_stack(stackptr s) {
+       int i, j;
+       stackptr t;
+
+       i = maxstack;
+       t = s;
+       
+       while (t) {
+               i--;
+               t = t->prev;
+               }
+       j = maxstack - i;
+       while (--i >= 0)
+               printf("    ");
+       while (s) {
+               j--;
+               if (s->flags & SAVEDVAR)
+                       switch (s->varkind) {
+                               case TEMPVAR:
+                                       if (s->flags & INMEMORY)
+                                               printf(" m%02d", s->regoff);
+                                       else
+                                               printf(" r%02d", s->regoff);
+                                       break;
+                               case STACKVAR:
+                                       printf(" s%02d", s->varnum);
+                                       break;
+                               case LOCALVAR:
+                                       printf(" l%02d", s->varnum);
+                                       break;
+                               case ARGVAR:
+                                       printf(" a%02d", s->varnum);
+                                       break;
+                               default:
+                                       printf(" !%02d", j);
+                               }
+               else
+                       switch (s->varkind) {
+                               case TEMPVAR:
+                                       if (s->flags & INMEMORY)
+                                               printf(" M%02d", s->regoff);
+                                       else
+                                               printf(" R%02d", s->regoff);
+                                       break;
+                               case STACKVAR:
+                                       printf(" S%02d", s->varnum);
+                                       break;
+                               case LOCALVAR:
+                                       printf(" L%02d", s->varnum);
+                                       break;
+                               case ARGVAR:
+                                       printf(" A%02d", s->varnum);
+                                       break;
+                               default:
+                                       printf(" ?%02d", j);
+                               }
+               s = s->prev;
+               }
+}
+
+
+static void print_reg(stackptr s) {
+       if (s) {
+               if (s->flags & SAVEDVAR)
+                       switch (s->varkind) {
+                               case TEMPVAR:
+                                       if (s->flags & INMEMORY)
+                                               printf(" tm%02d", s->regoff);
+                                       else
+                                               printf(" tr%02d", s->regoff);
+                                       break;
+                               case STACKVAR:
+                                       printf(" s %02d", s->varnum);
+                                       break;
+                               case LOCALVAR:
+                                       printf(" l %02d", s->varnum);
+                                       break;
+                               case ARGVAR:
+                                       printf(" a %02d", s->varnum);
+                                       break;
+                               default:
+                                       printf(" ! %02d", s->varnum);
+                               }
+               else
+                       switch (s->varkind) {
+                               case TEMPVAR:
+                                       if (s->flags & INMEMORY)
+                                               printf(" Tm%02d", s->regoff);
+                                       else
+                                               printf(" Tr%02d", s->regoff);
+                                       break;
+                               case STACKVAR:
+                                       printf(" S %02d", s->varnum);
+                                       break;
+                               case LOCALVAR:
+                                       printf(" L %02d", s->varnum);
+                                       break;
+                               case ARGVAR:
+                                       printf(" A %02d", s->varnum);
+                                       break;
+                               default:
+                                       printf(" ? %02d", s->varnum);
+                               }
+               }
+       else
+               printf("     ");
+               
+}
+
+
+static char *builtin_name(functionptr bptr)
+{
+       builtin_descriptor *bdesc = builtin_desc;
+       while ((bdesc->bptr != NULL) && (bdesc->bptr != bptr))
+               bdesc++;
+       return bdesc->name;
+}
+
+
+static void show_icmd_method()
+{
+       int b, i, j, last;
+       int deadcode;
+       s4  *s4ptr;
+       instruction *iptr;
+       
+       printf("\n");
+       unicode_fprint(stdout, class->name);
+       printf(".");
+       unicode_fprint(stdout, method->name);
+       printf(" ");
+       unicode_fprint(stdout, method->descriptor);
+       printf ("\n\nMax locals: %d\n", (int) maxlocals);
+       printf ("Max stack:  %d\n", (int) maxstack);
+
+       printf ("Exceptions:\n");
+       for (i = 0; i < exceptiontablelength; i++) {
+               printf("    L%03d ... ", block_index[extable[i].startpc]);
+               printf("L%03d = ", block_index[extable[i].endpc]);
+               printf("L%03d\n", block_index[extable[i].handlerpc]);
+               }
+       
+       printf ("Local Table:\n");
+       for (i = 0; i < maxlocals; i++) {
+               printf("   %3d: ", i);
+               for (j = TYPE_INT; j <= TYPE_ADR; j++)
+                       if (locals[i][j].type >= 0) {
+                               printf("   (%d) ", j);
+                               if (locals[i][j].flags)
+                                       printf("m");
+                               else
+                                       printf("r");
+                               printf("%2d", locals[i][j].regoff);
+                               }
+               printf("\n");
+               }
+       printf("\n");
+
+       printf ("Interface Table:\n");
+       for (i = 0; i < maxstack; i++) {
+               if ((interfaces[i][0].type >= 0) || (interfaces[i][1].type >= 0) ||
+                   (interfaces[i][2].type >= 0) || (interfaces[i][3].type >= 0) ||
+                   (interfaces[i][4].type >= 0)) {
+                       printf("   %3d: ", i);
+                       for (j = TYPE_INT; j <= TYPE_ADR; j++)
+                               if (interfaces[i][j].type >= 0) {
+                                       printf("   (%d) ", j);
+                                       if (interfaces[i][j].flags & SAVEDVAR)
+                                               printf("s");
+                                       else
+                                               printf("t");
+                                       if (interfaces[i][j].flags & INMEMORY)
+                                               printf("m");
+                                       else
+                                               printf("r");
+                                       printf("%2d", interfaces[i][j].regoff);
+                                       }
+                       printf("\n");
+                       }
+               }
+       printf("\n");
+
+       if (showdisassemble) {
+               s4ptr = (s4 *) (method->mcode + dseglen);
+               for (i = 0; i < block[0].mpc; i += 4, s4ptr++) {
+                       disassinstr(*s4ptr, i); 
+                       }
+               printf("\n");
+               }
+
+       for (b = 0; b < block_count; b++)
+               if (block[b].flags != BBDELETED) {
+               deadcode = block[b].flags <= BBREACHED;
+               printf("[");
+               if (deadcode)
+                       for (j = maxstack; j > 0; j--)
+                               printf(" ?  ");
+               else
+                       print_stack(block[b].instack);
+               printf("] L%03d(%d):\n", b, block[b].pre_count);
+               iptr = block[b].iinstr;
+               i = iptr - instr;
+               for (last = i + block[b].icount; i < last; i++, iptr++) {
+                       printf("[");
+                       if (deadcode) {
+                               for (j = maxstack; j > 0; j--)
+                                       printf(" ?  ");
+                               }
+                       else
+                               print_stack(iptr->dst);
+                       printf("]     %4d  %s", i, icmd_names[iptr->opc]);
+                       switch ((int) iptr->opc) {
+                               case ICMD_IADDCONST:
+                               case ICMD_ISUBCONST:
+                               case ICMD_IMULCONST:
+                               case ICMD_IDIVPOW2:
+                               case ICMD_IREMPOW2:
+                               case ICMD_IREM0X10001:
+                               case ICMD_IANDCONST:
+                               case ICMD_IORCONST:
+                               case ICMD_IXORCONST:
+                               case ICMD_ISHLCONST:
+                               case ICMD_ISHRCONST:
+                               case ICMD_IUSHRCONST:
+                               case ICMD_ICONST:
+                               case ICMD_ELSE_ICONST:
+                               case ICMD_IFEQ_ICONST:
+                               case ICMD_IFNE_ICONST:
+                               case ICMD_IFLT_ICONST:
+                               case ICMD_IFGE_ICONST:
+                               case ICMD_IFGT_ICONST:
+                               case ICMD_IFLE_ICONST:
+                                       printf(" %d", iptr->val.i);
+                                       break;
+                               case ICMD_LADDCONST:
+                               case ICMD_LSUBCONST:
+                               case ICMD_LMULCONST:
+                               case ICMD_LDIVPOW2:
+                               case ICMD_LREMPOW2:
+                               case ICMD_LANDCONST:
+                               case ICMD_LORCONST:
+                               case ICMD_LXORCONST:
+                               case ICMD_LSHLCONST:
+                               case ICMD_LSHRCONST:
+                               case ICMD_LUSHRCONST:
+                               case ICMD_LCONST:
+                                       printf(" %ld", iptr->val.l);
+                                       break;
+                               case ICMD_FCONST:
+                                       printf(" %f", iptr->val.f);
+                                       break;
+                               case ICMD_DCONST:
+                                       printf(" %f", iptr->val.d);
+                                       break;
+                               case ICMD_ACONST:
+                                       printf(" %p", iptr->val.a);
+                                       break;
+                               case ICMD_GETFIELD:
+                               case ICMD_PUTFIELD:
+                                       printf(" %d,", ((fieldinfo *) iptr->val.a)->offset);
+                               case ICMD_PUTSTATIC:
+                               case ICMD_GETSTATIC:
+                                       printf(" ");
+                                       unicode_fprint(stdout,
+                                                       ((fieldinfo *) iptr->val.a)->name);
+                                       break;
+                               case ICMD_IINC:
+                                       printf(" %d + %d", iptr->op1, iptr->val.i);
+                                       break;
+                               case ICMD_RET:
+                               case ICMD_ILOAD:
+                               case ICMD_LLOAD:
+                               case ICMD_FLOAD:
+                               case ICMD_DLOAD:
+                               case ICMD_ALOAD:
+                               case ICMD_ISTORE:
+                               case ICMD_LSTORE:
+                               case ICMD_FSTORE:
+                               case ICMD_DSTORE:
+                               case ICMD_ASTORE:
+                                       printf(" %d", iptr->op1);
+                                       break;
+                               case ICMD_NEW:
+                                       printf(" ");
+                                       unicode_fprint(stdout,
+                                                      ((classinfo *) iptr->val.a)->name);
+                                       break;
+                               case ICMD_NEWARRAY:
+                                       switch (iptr->op1) {
+                                               case 4:
+                                                       printf(" boolean");
+                                                       break;
+                                               case 5:
+                                                       printf(" char");
+                                                       break;
+                                               case 6:
+                                                       printf(" float");
+                                                       break;
+                                               case 7:
+                                                       printf(" double");
+                                                       break;
+                                               case 8:
+                                                       printf(" byte");
+                                                       break;
+                                               case 9:
+                                                       printf(" short");
+                                                       break;
+                                               case 10:
+                                                       printf(" int");
+                                                       break;
+                                               case 11:
+                                                       printf(" long");
+                                                       break;
+                                               }
+                                       break;
+                               case ICMD_ANEWARRAY:
+                                       if (iptr->op1) {
+                                               printf(" ");
+                                               unicode_fprint(stdout,
+                                                              ((classinfo *) iptr->val.a)->name);
+                                               }
+                                       break;
+                               case ICMD_CHECKCAST:
+                               case ICMD_INSTANCEOF:
+                                       if (iptr->op1) {
+                                               classinfo *c = iptr->val.a;
+                                               if (c->flags & ACC_INTERFACE)
+                                                       printf(" (INTERFACE) ");
+                                               else
+                                                       printf(" (CLASS,%3d) ", c->vftbl->diffval);
+                                               unicode_fprint(stdout, c->name);
+                                               }
+                                       break;
+                               case ICMD_BUILTIN3:
+                               case ICMD_BUILTIN2:
+                               case ICMD_BUILTIN1:
+                                       printf(" %s", builtin_name((functionptr) iptr->val.a));
+                                       break;
+                               case ICMD_INVOKEVIRTUAL:
+                               case ICMD_INVOKESPECIAL:
+                               case ICMD_INVOKESTATIC:
+                               case ICMD_INVOKEINTERFACE:
+                                       printf(" ");
+                                       unicode_fprint(stdout,
+                                                      ((methodinfo *) iptr->val.a)->class->name);
+                                       printf(".");
+                                       unicode_fprint(stdout,
+                                                      ((methodinfo *) iptr->val.a)->name);
+                                       break;
+                               case ICMD_IFEQ:
+                               case ICMD_IFNE:
+                               case ICMD_IFLT:
+                               case ICMD_IFGE:
+                               case ICMD_IFGT:
+                               case ICMD_IFLE:
+                               case ICMD_IF_LEQ:
+                               case ICMD_IF_LNE:
+                               case ICMD_IF_LLT:
+                               case ICMD_IF_LGE:
+                               case ICMD_IF_LGT:
+                               case ICMD_IF_LLE:
+                                       printf("(%d) L%03d", iptr->val.i, block_index[iptr->op1]);
+                                       break;
+                               case ICMD_JSR:
+                               case ICMD_GOTO:
+                               case ICMD_IFNULL:
+                               case ICMD_IFNONNULL:
+                               case ICMD_IF_ICMPEQ:
+                               case ICMD_IF_ICMPNE:
+                               case ICMD_IF_ICMPLT:
+                               case ICMD_IF_ICMPGE:
+                               case ICMD_IF_ICMPGT:
+                               case ICMD_IF_ICMPLE:
+                               case ICMD_IF_LCMPEQ:
+                               case ICMD_IF_LCMPNE:
+                               case ICMD_IF_LCMPLT:
+                               case ICMD_IF_LCMPGE:
+                               case ICMD_IF_LCMPGT:
+                               case ICMD_IF_LCMPLE:
+                               case ICMD_IF_ACMPEQ:
+                               case ICMD_IF_ACMPNE:
+                                       printf(" L%03d", block_index[iptr->op1]);
+                                       break;
+                               case ICMD_TABLESWITCH:
+                                       s4ptr = iptr->val.a;
+                                       printf(" L%03d;", block_index[*s4ptr++]); /* default */
+                                       j = *s4ptr++;                               /* low     */
+                                       j = *s4ptr++ - j;                           /* high    */
+                                       while (j >= 0) {
+                                               printf(" L%03d", block_index[*s4ptr++]);
+                                               j--;
+                                               }
+                                       break;
+                               case ICMD_LOOKUPSWITCH:
+                                       s4ptr = iptr->val.a;
+                                       printf(" L%d", block_index[*s4ptr++]);   /* default */
+                                       j = *s4ptr++;                               /* count   */
+                                       while (--j >= 0) {
+                                               printf(" L%03d", block_index[s4ptr[1]]);
+                                               s4ptr += 2;
+                                               }
+                                       break;
+                               }
+                       printf("\n");
+                       }
+
+               if (showdisassemble && (!deadcode)) {
+                       printf("\n");
+                       i = block[b].mpc;
+                       s4ptr = (s4 *) (method->mcode + dseglen + i);
+                       for (; i < block[b + 1].mpc; i += 4, s4ptr++) {
+                               disassinstr(*s4ptr, i); 
+                               }
+                       printf("\n");
+                       }
+       }
+       i = block[b].mpc;
+       s4ptr = (s4 *) (method->mcode + dseglen + i);
+       if (showdisassemble && (s4ptr < (s4 *) (method->mcode + method->mcodelength))) {
+               printf("\n");
+               for (; s4ptr < (s4 *) (method->mcode + method->mcodelength); i += 4, s4ptr++) {
+                       disassinstr(*s4ptr, i); 
+                       }
+               printf("\n");
+               }
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
index 3927e3a7c719ea4974129d5840742e74c5e28cb1..9b58781060b1e91090a6343d6c6b9dceef55c842 100644 (file)
--- a/loader.c
+++ b/loader.c
 #include "tables.h"
 #include "native.h"
 #include "builtin.h"
+#include "jit.h"
+#ifdef OLD_COMPILER
 #include "compiler.h"
+#endif
 #include "asmpart.h"
 
 #include "threads/thread.h"                        /* schani */
@@ -548,10 +551,14 @@ static void method_load (methodinfo *m, classinfo *c)
                functionptr f = native_findfunction 
                       (c->name, m->name, m->descriptor, (m->flags & ACC_STATIC) != 0);
                if (f) {
+#ifdef OLD_COMPILER
                if (newcompiler)
-                       m -> stubroutine = ncreatenativestub (f, m);
-               else
+#endif
                        m -> stubroutine = createnativestub (f, m);
+#ifdef OLD_COMPILER
+               else
+                       m -> stubroutine = oldcreatenativestub (f, m);
+#endif
                        }
                }
        
diff --git a/main.c b/main.c
index 067fe7a9c299d742315dbccdb8b16341c6789874..1269359647c232a93915fc952fd9cbc38c62824a 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,5 +1,4 @@
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
-/******************************* main.c ****************************************
+/* main.c **********************************************************************
 
        Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
 
 #include "global.h"
 
 #include "tables.h"
-#include "compiler.h"
-#include "ncomp/ncomp.h"
 #include "loader.h"
+#include "jit.h"
+#ifdef OLD_COMPILER
+#include "compiler.h"
+#endif
 
 #include "asmpart.h"
 #include "builtin.h"
@@ -43,9 +44,9 @@ void **stackbottom = 0;
 #endif
 
 
-/********************* interne Funktion: get_opt *****************************
+/* internal function: get_opt *************************************************
        
-       liest die n"achste Option aus der Kommandozeile
+       decodes the next command line option
        
 ******************************************************************************/
 
@@ -54,52 +55,56 @@ void **stackbottom = 0;
 #define OPT_IGNORE 1
 
 #define OPT_CLASSPATH   2
-#define OPT_D           3  
-#define OPT_MS          4  
-#define OPT_MX          5  
-#define OPT_VERBOSE1    6  
-#define OPT_VERBOSE     7  
-#define OPT_VERBOSEGC   8         
-#define OPT_VERBOSECALL 9          
+#define OPT_D           3
+#define OPT_MS          4
+#define OPT_MX          5
+#define OPT_VERBOSE1    6
+#define OPT_VERBOSE     7
+#define OPT_VERBOSEGC   8
+#define OPT_VERBOSECALL 9
 #define OPT_IEEE        10
 #define OPT_SOFTNULL    11
 #define OPT_TIME        12
 #define OPT_STAT        13
-#define OPT_LOG         14  
+#define OPT_LOG         14
 #define OPT_CHECK       15
-#define OPT_LOAD        16  
-#define OPT_METHOD      17  
-#define OPT_SIGNATURE   18  
-#define OPT_SHOW        19 
-#define OPT_ALL         20 
-#define OPT_OLD         21 
-
-struct { char *name; bool arg; int value; } opts[] = {
-  { "classpath",   true,   OPT_CLASSPATH },
-  { "D",           true,   OPT_D },
-  { "ms",          true,   OPT_MS },
-  { "mx",          true,   OPT_MX },
-  { "noasyncgc",   false,  OPT_IGNORE },  
-  { "noverify",    false,  OPT_IGNORE },  
-  { "oss",         true,   OPT_IGNORE },  
-  { "ss",          true,   OPT_IGNORE },  
-  { "v",           false,  OPT_VERBOSE1 },
-  { "verbose",     false,  OPT_VERBOSE },
-  { "verbosegc",   false,  OPT_VERBOSEGC },
-  { "verbosecall", false,  OPT_VERBOSECALL },
-  { "ieee",        false,  OPT_IEEE },
-  { "softnull",    false,  OPT_SOFTNULL },
-  { "time",        false,  OPT_TIME },
-  { "stat",        false,  OPT_STAT },
-  { "log",         true,   OPT_LOG },
-  { "c",           true,   OPT_CHECK },
-  { "l",           false,  OPT_LOAD },
-  { "m",           true,   OPT_METHOD },
-  { "sig",         true,   OPT_SIGNATURE },
-  { "s",           true,   OPT_SHOW },          
-  { "all",         false,  OPT_ALL },          
-  { "old",         false,  OPT_OLD },          
-  { NULL,  false, 0 }
+#define OPT_LOAD        16
+#define OPT_METHOD      17
+#define OPT_SIGNATURE   18
+#define OPT_SHOW        19
+#define OPT_ALL         20
+#ifdef OLD_COMPILER
+#define OPT_OLD         21
+#endif
+
+struct {char *name; bool arg; int value;} opts[] = {
+  {"classpath",   true,   OPT_CLASSPATH},
+  {"D",           true,   OPT_D},
+  {"ms",          true,   OPT_MS},
+  {"mx",          true,   OPT_MX},
+  {"noasyncgc",   false,  OPT_IGNORE},
+  {"noverify",    false,  OPT_IGNORE},
+  {"oss",         true,   OPT_IGNORE},
+  {"ss",          true,   OPT_IGNORE},
+  {"v",           false,  OPT_VERBOSE1},
+  {"verbose",     false,  OPT_VERBOSE},
+  {"verbosegc",   false,  OPT_VERBOSEGC},
+  {"verbosecall", false,  OPT_VERBOSECALL},
+  {"ieee",        false,  OPT_IEEE},
+  {"softnull",    false,  OPT_SOFTNULL},
+  {"time",        false,  OPT_TIME},
+  {"stat",        false,  OPT_STAT},
+  {"log",         true,   OPT_LOG},
+  {"c",           true,   OPT_CHECK},
+  {"l",           false,  OPT_LOAD},
+  {"m",           true,   OPT_METHOD},
+  {"sig",         true,   OPT_SIGNATURE},
+  {"s",           true,   OPT_SHOW},
+  {"all",         false,  OPT_ALL},
+#ifdef OLD_COMPILER
+  {"old",         false,  OPT_OLD},
+#endif
+  {NULL,  false, 0}
 };
 
 static int opt_ind = 1;
@@ -178,15 +183,20 @@ static void print_usage()
        printf ("                   s(ync) ...... don't check for synchronization\n");
        printf ("          -l ................... don't start the class after loading\n");
        printf ("          -all ................. compile all methods, no execution\n");
+#ifdef OLD_COMPILER
        printf ("          -old ................. use old JIT compiler\n");
+#endif
        printf ("          -m ................... compile only a specific method\n");
        printf ("          -sig ................. specify signature for a specific method\n");
        printf ("          -s(how)m(ethods) ..... show all methods&fields of a class\n");
-       printf ("                 c(onstants) ... show the constant pool\n");
        printf ("                 a(ssembler) ... show disassembled listing\n");
+       printf ("                 c(onstants) ... show the constant pool\n");
        printf ("                 d(atasegment).. show data segment listing\n");
-       printf ("                 s(tack) ....... show stack for every javaVM-command\n");
        printf ("                 i(ntermediate). show intermediate representation\n");
+       printf ("                 m(ethods)...... show class fields and methods\n");
+#ifdef OLD_COMPILER
+       printf ("                 s(tack) ....... show stack for every javaVM-command\n");
+#endif
        printf ("                 u(nicode) ..... show the unicode - hash\n");
 }   
 
@@ -397,10 +407,14 @@ void class_compile_methods ()
                for (i = 0; i < c -> methodscount; i++) {
                        m = &(c->methods[i]);
                        if (m->jcode) {
+#ifdef OLD_COMPILER
                                if (newcompiler)
-                                       (void) new_compile(m);
+#endif
+                                       (void) jit_compile(m);
+#ifdef OLD_COMPILER
                                else
                                        (void) compiler_compile(m);
+#endif
                                }
                        }
                c = list_next (&linkedclasses, c);
@@ -572,19 +586,24 @@ int main(int argc, char **argv)
                                makeinitializations = false;
                        break;
                        
+#ifdef OLD_COMPILER
                        case OPT_OLD:
                                newcompiler = false;                    
                                checknull = true;
                        break;
+#endif
                        
                case OPT_SHOW:       /* Anzeigeoptionen */
                        for (j=0; j<strlen(opt_arg); j++) {             
                                switch (opt_arg[j]) {
-                               case 'm':  showmethods=true; break;
-                               case 'c':  showconstantpool=true; break;
                                case 'a':  showdisassemble=true; compileverbose=true; break;
-                               case 's':  showstack=true; compileverbose=true; break;
+                               case 'c':  showconstantpool=true; break;
+                               case 'd':  showddatasegment=true; break;
                                case 'i':  showintermediate=true; compileverbose=true; break;
+                               case 'm':  showmethods=true; break;
+#ifdef OLD_COMPILER
+                               case 's':  showstack=true; compileverbose=true; break;
+#endif
                                case 'u':  showunicode=true; break;
                                default:   print_usage();
                                       exit(10);
@@ -621,8 +640,10 @@ int main(int argc, char **argv)
        unicode_init();
        heap_init(heapsize, heapstartsize, &dummy);
        loader_init();
+#ifdef OLD_COMPILER
        compiler_init();
-       ncomp_init();
+#endif
+       jit_init();
 
        native_loadclasses ();
 
@@ -695,10 +716,14 @@ int main(int argc, char **argv)
                        m = class_findmethod(topclass, 
                                        unicode_new_char(specificmethodname), NULL);
                if (!m) panic ("Specific method not found");
+#ifdef OLD_COMPILER
                if (newcompiler)
-                       (void) new_compile(m);
+#endif
+                       (void) jit_compile(m);
+#ifdef OLD_COMPILER
                else
                        (void) compiler_compile(m);
+#endif
                }
 
        /********************* Debug-Tabellen ausgeben ************************/
@@ -714,7 +739,9 @@ int main(int argc, char **argv)
        heap_close ();                          /* must be called before compiler_close and
                                                                   loader_close because finalization occurs
                                                                   here */
+#ifdef OLD_COMPILER
        compiler_close ();
+#endif
        loader_close ();
        unicode_close ( literalstring_free );
 
@@ -759,3 +786,17 @@ void cacao_shutdown(s4 status)
                
        exit(status);
 }
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
index 98a8547054b67533660baa677086316bc9333c24..adf10935b9670d5528943e0cdd60ca79aec0ef6c 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "../threads/thread.h"                  /* schani */
 #include "../threads/locks.h"
+#include "../sysdep/threads.h"
 
 
 
diff --git a/newcomp.c b/newcomp.c
deleted file mode 100644 (file)
index eeeb1d6..0000000
--- a/newcomp.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
-/***************************** ncomp/ncomp.c ***********************************
-
-       Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
-
-       See file COPYRIGHT for information on usage and disclaimer of warranties.
-
-       Contains the functions which translates a JavaVM method into native code.
-       This is the new version of the compiler which is a lot faster and has new
-       exception handling schemes. The main function is new_comp.
-
-       Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
-                Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
-
-       Last Change: 1997/11/05
-
-*******************************************************************************/
-
-#include "signal.h"
-#include "global.h"
-#include "ncomp/ncomp.h"
-
-#include "loader.h"
-#include "tables.h"
-#include "builtin.h"
-#include "native.h"
-#include "asmpart.h"
-
-#include "threads/thread.h"
-
-
-/*************************** global switches **********************************/
-
-bool compileverbose = false;
-bool showstack = false;
-bool showdisassemble = false; 
-bool showddatasegment = false; 
-bool showintermediate = false;
-int  optimizelevel = 0;
-
-bool checkbounds = true;
-bool checknull = true;
-bool checkfloats = true;
-bool checksync = true;
-
-bool getcompilingtime = false;
-long compilingtime = 0;
-
-int  has_ext_instr_set = 0;
-
-bool statistics = false;         
-
-int count_jit_calls = 0;
-int count_methods = 0;
-int count_spills = 0;
-int count_pcmd_activ = 0;
-int count_pcmd_drop = 0;
-int count_pcmd_zero = 0;
-int count_pcmd_const_store = 0;
-int count_pcmd_const_alu = 0;
-int count_pcmd_const_bra = 0;
-int count_pcmd_load = 0;
-int count_pcmd_move = 0;
-int count_load_instruction = 0;
-int count_pcmd_store = 0;
-int count_pcmd_store_comb = 0;
-int count_dup_instruction = 0;
-int count_pcmd_op = 0;
-int count_pcmd_mem = 0;
-int count_pcmd_met = 0;
-int count_pcmd_bra = 0;
-int count_pcmd_table = 0;
-int count_pcmd_return = 0;
-int count_pcmd_returnx = 0;
-int count_check_null = 0;
-int count_check_bound = 0;
-int count_max_basic_blocks = 0;
-int count_basic_blocks = 0;
-int count_javainstr = 0;
-int count_max_javainstr = 0;
-int count_javacodesize = 0;
-int count_javaexcsize = 0;
-int count_calls = 0;
-int count_tryblocks = 0;
-int count_code_len = 0;
-int count_data_len = 0;
-int count_cstub_len = 0;
-int count_nstub_len = 0;
-int count_max_new_stack = 0;
-int count_upper_bound_new_stack = 0;
-static int count_block_stack_init[11] = {0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0};
-int *count_block_stack = count_block_stack_init;
-static int count_analyse_iterations_init[5] = {0, 0, 0, 0, 0};
-int *count_analyse_iterations = count_analyse_iterations_init;
-static int count_method_bb_distribution_init[9] = {0, 0, 0, 0, 0,  0, 0, 0, 0};
-int *count_method_bb_distribution = count_method_bb_distribution_init;
-static int count_block_size_distribution_init[18] = {0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,   0, 0, 0, 0, 0,   0, 0, 0};
-int *count_block_size_distribution = count_block_size_distribution_init;
-static int count_store_length_init[21] = {0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
-                                          0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0};
-int *count_store_length = count_store_length_init;
-static int count_store_depth_init[11] = {0, 0, 0, 0, 0,  0, 0, 0, 0, 0,   0};
-int *count_store_depth = count_store_depth_init;
-
-
-/*********************** include compiler data types **************************/ 
-
-#include "ncomp/ncompdef.h"
-
-
-/*********************** global compiler variables ****************************/
-
-                                /* data about the currently compiled method   */
-
-static classinfo  *class;       /* class the compiled method belongs to       */
-static methodinfo *method;      /* pointer to method info of compiled method  */
-static unicode    *descriptor;  /* type descriptor of compiled method         */
-static u2         mparamcount;  /* number of parameters (incl. this)          */
-static u1         *mparamtypes; /* types of all parameters (TYPE_INT, ...)    */
-static u2         mreturntype;  /* return type of method                      */
-       
-static int maxstack;            /* maximal JavaVM stack size                  */
-static int maxlocals;           /* maximal number of local JavaVM variables   */
-static int jcodelength;         /* length of JavaVM-codes                     */
-static u1 *jcode;               /* pointer to start of JavaVM-code            */
-static int exceptiontablelength;/* length of exception table                  */
-static exceptiontable *extable; /* pointer to start of exception table        */
-
-static int block_count;         /* number of basic blocks                     */
-static basicblock *block;       /* points to basic block array                */
-static int *block_index;        /* a table which contains for every byte of   */
-                                /* JavaVM code a basic block index if at this */
-                                /* byte there is the start of a basic block   */
-
-static int instr_count;         /* number of JavaVM instructions              */
-static instruction *instr;      /* points to intermediate code instructions   */
-
-static int stack_count;         /* number of stack elements                   */
-static stackelement *stack;     /* points to intermediate code instructions   */
-
-static bool isleafmethod;       /* true if a method doesn't call subroutines  */
-
-/* list of all classes used by the compiled method which have to be           */
-/* initialised (if not already done) before execution of this method          */
-
-static chain *uninitializedclasses;  
-                                
-
-/******************** include compiler subsystems *****************************/
-
-#include "sysdep/ngen.h"        /* code generator header file                 */ 
-#include "ncomp/ntools.c"       /* compiler tool functions                    */ 
-#include "ncomp/mcode.c"        /* code generation tool functions             */ 
-#include "sysdep/disass.c"      /* disassembler (for debug purposes only)     */ 
-#include "ncomp/nparse.c"       /* parsing of JavaVM code                     */ 
-#include "ncomp/nreg.c"         /* register allocation and support routines   */ 
-#include "ncomp/nstack.c"       /* analysing the stack operations             */ 
-#include "sysdep/ngen.c"        /* code generator                             */ 
-
-
-
-
-/* dummy function, used when there is no JavaVM code available                */
-
-static void* do_nothing_function() 
-{
-       return NULL;
-}
-
-
-/*******************************************************************************
-
-       new_compile, new version of compiler, translates one method to machine code
-
-*******************************************************************************/
-
-methodptr new_compile(methodinfo *m)
-{
-       int  dumpsize;
-       long starttime = 0;
-       long stoptime  = 0;
-
-       /* if method has been already compiled return immediately */
-
-       count_jit_calls++;
-
-       if (m->entrypoint)
-               return m->entrypoint;
-
-       count_methods++;
-
-       intsDisable();      /* disable interrupts */
-       
-
-       /* mark start of dump memory area */
-
-       dumpsize = dump_size ();
-
-       /* measure time */
-
-       if (getcompilingtime)
-               starttime = getcputime();
-
-       /* if there is no javacode print error message and return empty method    */
-
-       if (! m->jcode) {
-               sprintf(logtext, "No code given for: ");
-               unicode_sprint(logtext+strlen(logtext), m->class->name);
-               strcpy(logtext+strlen(logtext), ".");
-               unicode_sprint(logtext+strlen(logtext), m->name);
-               unicode_sprint(logtext+strlen(logtext), m->descriptor);
-               dolog();
-               intsRestore();                             /* enable interrupts again */
-               return (methodptr) do_nothing_function;    /* return empty method     */
-               }
-
-       /* print log message for compiled method */
-
-       if (compileverbose) {
-               sprintf(logtext, "Compiling: ");
-               unicode_sprint(logtext+strlen(logtext), m->class->name);
-               strcpy(logtext+strlen(logtext), ".");
-               unicode_sprint(logtext+strlen(logtext), m->name);
-               unicode_sprint(logtext+strlen(logtext), m->descriptor);
-               dolog ();
-               }
-
-
-       /* initialisation of variables and subsystems */
-
-       isleafmethod = true;
-
-       method = m;
-       class = m->class;
-       descriptor = m->descriptor;
-       maxstack = m->maxstack;
-       maxlocals = m->maxlocals;
-       jcodelength = m->jcodelength;
-       jcode = m->jcode;
-       exceptiontablelength = m->exceptiontablelength;
-       extable = m->exceptiontable;
-
-#ifdef STATISTICS
-       count_tryblocks += exceptiontablelength;
-       count_javacodesize += jcodelength + 18;
-       count_javaexcsize += exceptiontablelength * 8;
-#endif
-
-       /* initialise parameter type descriptor */
-
-       descriptor2types (m);
-       mreturntype = m->returntype;
-       mparamcount = m->paramcount;
-       mparamtypes = m->paramtypes;
-
-       /* initialize class list with class the compiled method belongs to */
-
-       uninitializedclasses = chain_new(); 
-       compiler_addinitclass (m->class);
-
-
-       /********************** call the compiler passes **************************/
-       
-       reg_init();
-       local_init();
-       mcode_init();
-
-       if (runverbose)
-               allocate_literals();
-
-       parse();
-
-       analyse_stack();
-
-       interface_regalloc();
-
-       allocate_scratch_registers();
-       
-       local_regalloc();
-       
-       gen_mcode();
-
-       
-       /*********** Zwischendarstellungen auf Wunsch ausgeben **********/
-               
-       if (showintermediate)
-               show_icmd_method();
-       else if (showdisassemble)
-               disassemble((void*) (m->mcode + dseglen), m->mcodelength - dseglen);
-
-       if (showddatasegment)
-               dseg_display((void*) (m->mcode));
-
-
-
-       /* release dump area */
-
-       dump_release (dumpsize);
-
-       /* measure time */
-
-       if (getcompilingtime) {
-               stoptime = getcputime();
-               compilingtime += (stoptime-starttime); 
-               }
-
-       /* initialize all used classes */
-       /* because of reentrant code global variables are not allowed here        */
-
-       {
-       chain *ul = uninitializedclasses;   /* list of uninitialized classes      */ 
-       classinfo *c;                       /* single class                       */
-
-       while ((c = chain_first(ul)) != NULL) {
-               chain_remove (ul);
-               class_init (c);                         /* may again call the compiler        */
-               }
-       chain_free (ul);
-       }
-
-       intsRestore();    /* enable interrupts again */
-
-       /* return pointer to the methods entry point */
-       
-       return m -> entrypoint;
-}
-
-
-/************ functions for compiler initialisation and finalisation **********/
-
-void ncomp_init ()
-{
-       int i;
-
-       has_ext_instr_set = ! has_no_x_instr_set();
-
-       for (i = 0; i < 256; i++)
-               stackreq[i] = 1;
-
-       stackreq[JAVA_NOP]          = 0;
-       stackreq[JAVA_ISTORE]       = 0;
-       stackreq[JAVA_LSTORE]       = 0;
-       stackreq[JAVA_FSTORE]       = 0;
-       stackreq[JAVA_DSTORE]       = 0;
-       stackreq[JAVA_ASTORE]       = 0;
-       stackreq[JAVA_ISTORE_0]     = 0;
-       stackreq[JAVA_ISTORE_1]     = 0;
-       stackreq[JAVA_ISTORE_2]     = 0;
-       stackreq[JAVA_ISTORE_3]     = 0;
-       stackreq[JAVA_LSTORE_0]     = 0;
-       stackreq[JAVA_LSTORE_1]     = 0;
-       stackreq[JAVA_LSTORE_2]     = 0;
-       stackreq[JAVA_LSTORE_3]     = 0;
-       stackreq[JAVA_FSTORE_0]     = 0;
-       stackreq[JAVA_FSTORE_1]     = 0;
-       stackreq[JAVA_FSTORE_2]     = 0;
-       stackreq[JAVA_FSTORE_3]     = 0;
-       stackreq[JAVA_DSTORE_0]     = 0;
-       stackreq[JAVA_DSTORE_1]     = 0;
-       stackreq[JAVA_DSTORE_2]     = 0;
-       stackreq[JAVA_DSTORE_3]     = 0;
-       stackreq[JAVA_ASTORE_0]     = 0;
-       stackreq[JAVA_ASTORE_1]     = 0;
-       stackreq[JAVA_ASTORE_2]     = 0;
-       stackreq[JAVA_ASTORE_3]     = 0;
-       stackreq[JAVA_IASTORE]      = 0;
-       stackreq[JAVA_LASTORE]      = 0;
-       stackreq[JAVA_FASTORE]      = 0;
-       stackreq[JAVA_DASTORE]      = 0;
-       stackreq[JAVA_AASTORE]      = 0;
-       stackreq[JAVA_BASTORE]      = 0;
-       stackreq[JAVA_CASTORE]      = 0;
-       stackreq[JAVA_SASTORE]      = 0;
-       stackreq[JAVA_POP]          = 0;
-       stackreq[JAVA_POP2]         = 0;
-       stackreq[JAVA_IINC]         = 0;
-       stackreq[JAVA_IFEQ]         = 0;
-       stackreq[JAVA_IFNE]         = 0;
-       stackreq[JAVA_IFLT]         = 0;
-       stackreq[JAVA_IFGE]         = 0;
-       stackreq[JAVA_IFGT]         = 0;
-       stackreq[JAVA_IFLE]         = 0;
-       stackreq[JAVA_IF_ICMPEQ]    = 0;
-       stackreq[JAVA_IF_ICMPNE]    = 0;
-       stackreq[JAVA_IF_ICMPLT]    = 0;
-       stackreq[JAVA_IF_ICMPGE]    = 0;
-       stackreq[JAVA_IF_ICMPGT]    = 0;
-       stackreq[JAVA_IF_ICMPLE]    = 0;
-       stackreq[JAVA_IF_ACMPEQ]    = 0;
-       stackreq[JAVA_IF_ACMPNE]    = 0;
-       stackreq[JAVA_GOTO]         = 0;
-       stackreq[JAVA_RET]          = 0;
-       stackreq[JAVA_TABLESWITCH]  = 0;
-       stackreq[ICMD_LOOKUPSWITCH] = 0;
-       stackreq[JAVA_IRETURN]      = 0;
-       stackreq[JAVA_LRETURN]      = 0;
-       stackreq[JAVA_FRETURN]      = 0;
-       stackreq[JAVA_DRETURN]      = 0;
-       stackreq[JAVA_ARETURN]      = 0;
-       stackreq[JAVA_RETURN]       = 0;
-       stackreq[JAVA_PUTSTATIC]    = 0;
-       stackreq[JAVA_PUTFIELD]     = 0;
-       stackreq[JAVA_MONITORENTER] = 0;
-       stackreq[ICMD_MONITOREXIT]  = 0;
-       stackreq[JAVA_WIDE]         = 0;
-       stackreq[JAVA_IFNULL]       = 0;
-       stackreq[JAVA_IFNONNULL]    = 0;
-       stackreq[JAVA_GOTO_W]       = 0;
-       stackreq[JAVA_BREAKPOINT]   = 0;
-
-       stackreq[JAVA_SWAP] = 2;
-       stackreq[JAVA_DUP2] = 2;
-       stackreq[JAVA_DUP_X1] = 3;
-       stackreq[JAVA_DUP_X2] = 4;
-       stackreq[JAVA_DUP2_X1] = 3;
-       stackreq[JAVA_DUP2_X2] = 4;
-       
-       for (i = 0; i < 256; i++) stdopdescriptors[i] = NULL;
-
-       for (i = 0; i < sizeof(stdopdescriptortable)/sizeof(stdopdescriptor); i++) {
-               
-               if (stdopdescriptortable[i].isfloat && checkfloats) {
-                       stdopdescriptortable[i].supported = false;
-                       }
-
-               stdopdescriptors[stdopdescriptortable[i].opcode] = 
-                  &(stdopdescriptortable[i]);
-               }
-
-       init_exceptions();
-}
-
-
-void ncomp_close()
-{
-/*     mcode_close(); */
-}
-
index 067fe7a9c299d742315dbccdb8b16341c6789874..1269359647c232a93915fc952fd9cbc38c62824a 100644 (file)
@@ -1,5 +1,4 @@
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
-/******************************* main.c ****************************************
+/* main.c **********************************************************************
 
        Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
 
 #include "global.h"
 
 #include "tables.h"
-#include "compiler.h"
-#include "ncomp/ncomp.h"
 #include "loader.h"
+#include "jit.h"
+#ifdef OLD_COMPILER
+#include "compiler.h"
+#endif
 
 #include "asmpart.h"
 #include "builtin.h"
@@ -43,9 +44,9 @@ void **stackbottom = 0;
 #endif
 
 
-/********************* interne Funktion: get_opt *****************************
+/* internal function: get_opt *************************************************
        
-       liest die n"achste Option aus der Kommandozeile
+       decodes the next command line option
        
 ******************************************************************************/
 
@@ -54,52 +55,56 @@ void **stackbottom = 0;
 #define OPT_IGNORE 1
 
 #define OPT_CLASSPATH   2
-#define OPT_D           3  
-#define OPT_MS          4  
-#define OPT_MX          5  
-#define OPT_VERBOSE1    6  
-#define OPT_VERBOSE     7  
-#define OPT_VERBOSEGC   8         
-#define OPT_VERBOSECALL 9          
+#define OPT_D           3
+#define OPT_MS          4
+#define OPT_MX          5
+#define OPT_VERBOSE1    6
+#define OPT_VERBOSE     7
+#define OPT_VERBOSEGC   8
+#define OPT_VERBOSECALL 9
 #define OPT_IEEE        10
 #define OPT_SOFTNULL    11
 #define OPT_TIME        12
 #define OPT_STAT        13
-#define OPT_LOG         14  
+#define OPT_LOG         14
 #define OPT_CHECK       15
-#define OPT_LOAD        16  
-#define OPT_METHOD      17  
-#define OPT_SIGNATURE   18  
-#define OPT_SHOW        19 
-#define OPT_ALL         20 
-#define OPT_OLD         21 
-
-struct { char *name; bool arg; int value; } opts[] = {
-  { "classpath",   true,   OPT_CLASSPATH },
-  { "D",           true,   OPT_D },
-  { "ms",          true,   OPT_MS },
-  { "mx",          true,   OPT_MX },
-  { "noasyncgc",   false,  OPT_IGNORE },  
-  { "noverify",    false,  OPT_IGNORE },  
-  { "oss",         true,   OPT_IGNORE },  
-  { "ss",          true,   OPT_IGNORE },  
-  { "v",           false,  OPT_VERBOSE1 },
-  { "verbose",     false,  OPT_VERBOSE },
-  { "verbosegc",   false,  OPT_VERBOSEGC },
-  { "verbosecall", false,  OPT_VERBOSECALL },
-  { "ieee",        false,  OPT_IEEE },
-  { "softnull",    false,  OPT_SOFTNULL },
-  { "time",        false,  OPT_TIME },
-  { "stat",        false,  OPT_STAT },
-  { "log",         true,   OPT_LOG },
-  { "c",           true,   OPT_CHECK },
-  { "l",           false,  OPT_LOAD },
-  { "m",           true,   OPT_METHOD },
-  { "sig",         true,   OPT_SIGNATURE },
-  { "s",           true,   OPT_SHOW },          
-  { "all",         false,  OPT_ALL },          
-  { "old",         false,  OPT_OLD },          
-  { NULL,  false, 0 }
+#define OPT_LOAD        16
+#define OPT_METHOD      17
+#define OPT_SIGNATURE   18
+#define OPT_SHOW        19
+#define OPT_ALL         20
+#ifdef OLD_COMPILER
+#define OPT_OLD         21
+#endif
+
+struct {char *name; bool arg; int value;} opts[] = {
+  {"classpath",   true,   OPT_CLASSPATH},
+  {"D",           true,   OPT_D},
+  {"ms",          true,   OPT_MS},
+  {"mx",          true,   OPT_MX},
+  {"noasyncgc",   false,  OPT_IGNORE},
+  {"noverify",    false,  OPT_IGNORE},
+  {"oss",         true,   OPT_IGNORE},
+  {"ss",          true,   OPT_IGNORE},
+  {"v",           false,  OPT_VERBOSE1},
+  {"verbose",     false,  OPT_VERBOSE},
+  {"verbosegc",   false,  OPT_VERBOSEGC},
+  {"verbosecall", false,  OPT_VERBOSECALL},
+  {"ieee",        false,  OPT_IEEE},
+  {"softnull",    false,  OPT_SOFTNULL},
+  {"time",        false,  OPT_TIME},
+  {"stat",        false,  OPT_STAT},
+  {"log",         true,   OPT_LOG},
+  {"c",           true,   OPT_CHECK},
+  {"l",           false,  OPT_LOAD},
+  {"m",           true,   OPT_METHOD},
+  {"sig",         true,   OPT_SIGNATURE},
+  {"s",           true,   OPT_SHOW},
+  {"all",         false,  OPT_ALL},
+#ifdef OLD_COMPILER
+  {"old",         false,  OPT_OLD},
+#endif
+  {NULL,  false, 0}
 };
 
 static int opt_ind = 1;
@@ -178,15 +183,20 @@ static void print_usage()
        printf ("                   s(ync) ...... don't check for synchronization\n");
        printf ("          -l ................... don't start the class after loading\n");
        printf ("          -all ................. compile all methods, no execution\n");
+#ifdef OLD_COMPILER
        printf ("          -old ................. use old JIT compiler\n");
+#endif
        printf ("          -m ................... compile only a specific method\n");
        printf ("          -sig ................. specify signature for a specific method\n");
        printf ("          -s(how)m(ethods) ..... show all methods&fields of a class\n");
-       printf ("                 c(onstants) ... show the constant pool\n");
        printf ("                 a(ssembler) ... show disassembled listing\n");
+       printf ("                 c(onstants) ... show the constant pool\n");
        printf ("                 d(atasegment).. show data segment listing\n");
-       printf ("                 s(tack) ....... show stack for every javaVM-command\n");
        printf ("                 i(ntermediate). show intermediate representation\n");
+       printf ("                 m(ethods)...... show class fields and methods\n");
+#ifdef OLD_COMPILER
+       printf ("                 s(tack) ....... show stack for every javaVM-command\n");
+#endif
        printf ("                 u(nicode) ..... show the unicode - hash\n");
 }   
 
@@ -397,10 +407,14 @@ void class_compile_methods ()
                for (i = 0; i < c -> methodscount; i++) {
                        m = &(c->methods[i]);
                        if (m->jcode) {
+#ifdef OLD_COMPILER
                                if (newcompiler)
-                                       (void) new_compile(m);
+#endif
+                                       (void) jit_compile(m);
+#ifdef OLD_COMPILER
                                else
                                        (void) compiler_compile(m);
+#endif
                                }
                        }
                c = list_next (&linkedclasses, c);
@@ -572,19 +586,24 @@ int main(int argc, char **argv)
                                makeinitializations = false;
                        break;
                        
+#ifdef OLD_COMPILER
                        case OPT_OLD:
                                newcompiler = false;                    
                                checknull = true;
                        break;
+#endif
                        
                case OPT_SHOW:       /* Anzeigeoptionen */
                        for (j=0; j<strlen(opt_arg); j++) {             
                                switch (opt_arg[j]) {
-                               case 'm':  showmethods=true; break;
-                               case 'c':  showconstantpool=true; break;
                                case 'a':  showdisassemble=true; compileverbose=true; break;
-                               case 's':  showstack=true; compileverbose=true; break;
+                               case 'c':  showconstantpool=true; break;
+                               case 'd':  showddatasegment=true; break;
                                case 'i':  showintermediate=true; compileverbose=true; break;
+                               case 'm':  showmethods=true; break;
+#ifdef OLD_COMPILER
+                               case 's':  showstack=true; compileverbose=true; break;
+#endif
                                case 'u':  showunicode=true; break;
                                default:   print_usage();
                                       exit(10);
@@ -621,8 +640,10 @@ int main(int argc, char **argv)
        unicode_init();
        heap_init(heapsize, heapstartsize, &dummy);
        loader_init();
+#ifdef OLD_COMPILER
        compiler_init();
-       ncomp_init();
+#endif
+       jit_init();
 
        native_loadclasses ();
 
@@ -695,10 +716,14 @@ int main(int argc, char **argv)
                        m = class_findmethod(topclass, 
                                        unicode_new_char(specificmethodname), NULL);
                if (!m) panic ("Specific method not found");
+#ifdef OLD_COMPILER
                if (newcompiler)
-                       (void) new_compile(m);
+#endif
+                       (void) jit_compile(m);
+#ifdef OLD_COMPILER
                else
                        (void) compiler_compile(m);
+#endif
                }
 
        /********************* Debug-Tabellen ausgeben ************************/
@@ -714,7 +739,9 @@ int main(int argc, char **argv)
        heap_close ();                          /* must be called before compiler_close and
                                                                   loader_close because finalization occurs
                                                                   here */
+#ifdef OLD_COMPILER
        compiler_close ();
+#endif
        loader_close ();
        unicode_close ( literalstring_free );
 
@@ -759,3 +786,17 @@ void cacao_shutdown(s4 status)
                
        exit(status);
 }
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
index d28baccef059f4b3304d5a341bf8a6197ffcf88c..6f95bdca5868fca891cc39aaf42f030eb53e3160 100644 (file)
@@ -1,5 +1,4 @@
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
-/****************************** headers.c **************************************
+/* headers.c *******************************************************************
 
        Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
 
@@ -62,7 +61,7 @@ void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {
 
 u1 *createcompilerstub (methodinfo *m) {return NULL;}
 u1 *createnativestub (functionptr f, methodinfo *m) {return NULL;}
-u1 *ncreatenativestub (functionptr f, methodinfo *m) {return NULL;}
+u1 *oldcreatenativestub (functionptr f, methodinfo *m) {return NULL;}
 
 void removecompilerstub (u1 *stub) {}
 void removenativestub (u1 *stub) {}
@@ -474,3 +473,15 @@ int main(int argc, char **argv)
 }
 
 
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
index df11a012c4a2ad86fb0d07dd80c6efe41fc6a3de..dc791983d4c9915d6e5923262094b6a2635d78f8 100644 (file)
 *******************************************************************************/
 
 #ifndef __global_h_
-#define __global_h_                        /* schani */
+#define __global_h_
 
-#define STATISTICS                         /* andi   */
+#define OLD_COMPILER        /* if enabled makes old compiler available        */
+
+#define STATISTICS          /* if enabled collects program statistics         */
 
 /* JIT_MARKER_SUPPORT is the define used to toggle Just-in-time generated
-   marker functions on and off. */
-#undef JIT_MARKER_SUPPORT                  /* phil   */
+       marker functions on and off.
+*/
+#undef  JIT_MARKER_SUPPORT  /* phil   */
 
 /* standard includes **********************************************************/
 
diff --git a/src/vm/jit/parse.c b/src/vm/jit/parse.c
new file mode 100644 (file)
index 0000000..269db06
--- /dev/null
@@ -0,0 +1,1120 @@
+/* jit/parse.c *****************************************************************
+
+       Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+       See file COPYRIGHT for information on usage and disclaimer of warranties
+
+       Parser for JavaVM to intermediate code translation
+       
+       Author: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
+
+       Last Change: 1998/05/07
+
+*******************************************************************************/
+
+#include "math.h"
+
+
+/* macros for byte code fetching ***********************************************
+
+       fetch a byte code of given size from position pos
+
+*******************************************************************************/
+
+#define code_get_u1(pos)    jcode[pos]
+#define code_get_s1(pos)    ((s1)jcode[pos])
+#define code_get_u2(pos)    ((((u2)jcode[pos])<<8)+jcode[pos+1])
+#define code_get_s2(pos)    ((s2)((((u2)jcode[pos])<<8)+jcode[pos+1]))
+#define code_get_u4(pos)    ((((u4)jcode[pos])<<24)+(((u4)jcode[pos+1])<<16)+\
+                             (((u4)jcode[pos+2])<<8)+jcode[pos+3])
+#define code_get_s4(pos)    ((s4)((((u4)jcode[pos])<<24)+(((u4)jcode[pos+1])<<16)+\
+                             (((u4)jcode[pos+2])<<8)+jcode[pos+3]))
+
+
+/* functionc compiler_addinitclass *********************************************
+
+       add class into the list of classes to initialize
+
+*******************************************************************************/
+                                
+static void compiler_addinitclass (classinfo *c)
+{
+       classinfo *cl;
+
+       if (c->initialized) return;
+       
+       cl = chain_first(uninitializedclasses);
+       if (cl == c)
+               return;
+       
+       if (cl == class)
+               cl = chain_next(uninitializedclasses);
+       for (;;) {
+               if (cl == c)
+                       return;
+               if (cl == NULL) {
+                       if (runverbose) {
+                               sprintf(logtext, "compiler_addinitclass: ");
+                               unicode_sprint(logtext+strlen(logtext), c->name);
+                               dolog();
+                               }
+                       chain_addlast(uninitializedclasses, c);
+                       return;
+                       }
+               if (c < cl) {
+                       if (runverbose) {
+                               sprintf(logtext, "compiler_addinitclass: ");
+                               unicode_sprint(logtext+strlen(logtext), c->name);
+                               dolog();
+                               }
+                       chain_addbefore(uninitializedclasses, c);
+                       return;
+                       }
+               cl = chain_next(uninitializedclasses);
+               }
+}                       
+
+
+/* function descriptor2types ***************************************************
+
+       decodes a already checked method descriptor. The parameter count, the
+       return type and the argument types are stored in the passed methodinfo.
+
+*******************************************************************************/               
+
+static void descriptor2types (methodinfo *m)
+{
+       u1 *types, *tptr;
+       int pcount, c;
+       u2 *cptr;
+
+       pcount = 0;
+       types = DMNEW (u1, m->descriptor->length);
+       
+       tptr = types;
+       if (!(m->flags & ACC_STATIC)) {
+               *tptr++ = TYPE_ADR;
+               pcount++;
+               }
+
+       cptr = m->descriptor->text;
+       cptr++;
+       while ((c = *cptr++) != ')') {
+               pcount++;
+               switch (c) {
+                       case 'B':
+                       case 'C':
+                       case 'I':
+                       case 'S':
+                       case 'Z':  *tptr++ = TYPE_INT;
+                                  break;
+                       case 'J':  *tptr++ = TYPE_LNG;
+                                  break;
+                       case 'F':  *tptr++ = TYPE_FLT;
+                                  break;
+                       case 'D':  *tptr++ = TYPE_DBL;
+                                  break;
+                       case 'L':  *tptr++ = TYPE_ADR;
+                                  while (*cptr++ != ';');
+                                  break;
+                       case '[':  *tptr++ = TYPE_ADR;
+                                  while (c == '[')
+                                      c = *cptr++;
+                                  if (c == 'L')
+                                      while (*cptr++ != ';') /* skip */;
+                                  break;
+                       default:   panic ("Ill formed methodtype-descriptor");
+                       }
+               }
+
+       /* compute return type */
+
+       switch (*cptr) {
+               case 'B':
+               case 'C':
+               case 'I':
+               case 'S':
+               case 'Z':  m->returntype = TYPE_INT;
+                          break;
+               case 'J':  m->returntype = TYPE_LNG;
+                          break;
+               case 'F':  m->returntype = TYPE_FLT;
+                          break;
+               case 'D':  m->returntype = TYPE_DBL;
+                          break;
+               case '[':
+               case 'L':  m->returntype = TYPE_ADR;
+                          break;
+               case 'V':  m->returntype = TYPE_VOID;
+                          break;
+
+               default:   panic ("Ill formed methodtype-descriptor");
+               }
+
+       m->paramcount = pcount;
+       m->paramtypes = types;
+}
+
+
+/* function allocate_literals **************************************************
+
+       Scans the JavaVM code of a method and allocates string literals. Needed
+       to generate the same addresses as the old JIT compiler.
+       
+*******************************************************************************/
+
+static void allocate_literals()
+{
+       int     p, nextp;
+       int     opcode, i;
+       s4      num;
+       unicode *s;
+
+       for (p = 0; p < jcodelength; p = nextp) {
+
+               opcode = jcode[p];
+               nextp = p + jcommandsize[opcode];
+
+               switch (opcode) {
+                       case JAVA_WIDE:
+                               if (code_get_u1(p + 1) == JAVA_IINC)
+                                       nextp = p + 6;
+                               else
+                                       nextp = p + 4;
+                               break;
+                                                       
+                       case JAVA_LOOKUPSWITCH:
+                               nextp = ALIGN((p + 1), 4);
+                               num = code_get_u4(nextp + 4);
+                               nextp = nextp + 8 + 8 * num;
+                               break;
+
+                       case JAVA_TABLESWITCH:
+                               nextp = ALIGN ((p + 1),4);
+                               num = code_get_s4(nextp + 4);
+                               num = code_get_s4(nextp + 8) - num;
+                               nextp = nextp + 16 + 4 * num;
+                               break;
+
+                       case JAVA_LDC1:
+                               i = code_get_u1(p+1);
+                               goto pushconstantitem;
+                       case JAVA_LDC2:
+                       case JAVA_LDC2W:
+                               i = code_get_u2(p + 1);
+                       pushconstantitem:
+                               if (class_constanttype(class, i) == CONSTANT_String) {
+                                       s = class_getconstant(class, i, CONSTANT_String);
+                                       (void) literalstring_new(s);
+                                       }
+                               break;
+                       } /* end switch */
+               } /* end while */
+}
+
+
+
+/*******************************************************************************
+
+       function 'parse' scans the JavaVM code and generates intermediate code
+
+       During parsing the block index table is used to store at bit pos 0
+       a flag which marks basic block starts and at position 1 to 31 the
+       intermediate instruction index. After parsing the block index table
+       is scanned, for marked positions a block is generated and the block
+       number is stored in the block index table.
+
+*******************************************************************************/
+
+/* intermediate code generating macros */
+
+#define PINC           iptr++;ipc++
+#define LOADCONST_I(v) iptr->opc=ICMD_ICONST;iptr->op1=0;iptr->val.i=(v);PINC
+#define LOADCONST_L(v) iptr->opc=ICMD_LCONST;iptr->op1=0;iptr->val.l=(v);PINC
+#define LOADCONST_F(v) iptr->opc=ICMD_FCONST;iptr->op1=0;iptr->val.f=(v);PINC
+#define LOADCONST_D(v) iptr->opc=ICMD_DCONST;iptr->op1=0;iptr->val.d=(v);PINC
+#define LOADCONST_A(v) iptr->opc=ICMD_ACONST;iptr->op1=0;iptr->val.a=(v);PINC
+#define OP(o)          iptr->opc=(o);iptr->op1=0;iptr->val.l=0;PINC
+#define OP1(o,o1)      iptr->opc=(o);iptr->op1=(o1);iptr->val.l=(0);PINC
+#define OP2I(o,o1,v)   iptr->opc=(o);iptr->op1=(o1);iptr->val.i=(v);PINC
+#define OP2A(o,o1,v)   iptr->opc=(o);iptr->op1=(o1);iptr->val.a=(v);PINC
+#define BUILTIN1(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN1;iptr->op1=t;\
+                       iptr->val.a=(v);PINC
+#define BUILTIN2(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN2;iptr->op1=t;\
+                       iptr->val.a=(v);PINC
+#define BUILTIN3(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN3;iptr->op1=t;\
+                       iptr->val.a=(v);PINC
+
+
+/* block generating and checking macros */
+
+#define block_insert(i)    {if(!(block_index[i]&1))\
+                               {b_count++;block_index[i] |= 1;}}
+#define bound_check(i)     {if((i< 0) || (i>=jcodelength)) \
+                               panic("branch target out of code-boundary");}
+#define bound_check1(i)    {if((i< 0) || (i>jcodelength)) \
+                               panic("branch target out of code-boundary");}
+
+
+static void parse()
+{
+       int  p;                     /* java instruction counter                   */
+       int  nextp;                 /* start of next java instruction             */
+       int  opcode;                /* java opcode                                */
+       int  i;                     /* temporary for different uses (counters)    */
+       int  ipc = 0;               /* intermediate instruction counter           */
+       int  b_count = 0;           /* basic block counter                        */
+       int  s_count = 0;           /* stack element counter                      */
+       bool blockend = false;      /* true if basic block end has reached        */
+       bool iswide = false;        /* true if last instruction was a wide        */
+       instruction *iptr;          /* current pointer into instruction array     */
+
+
+       /* allocate instruction array and block index table */
+       
+       /* 1 additional for end ipc and 3 for loop unrolling */
+       
+       block_index = DMNEW(int, jcodelength + 3);
+
+       /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
+       /* additional MONITOREXITS are reached by branches which are 3 bytes */
+       
+       iptr = instr = DMNEW(instruction, jcodelength + 5);
+       
+       /* initialize block_index table (unrolled four times) */
+
+       {
+       int *ip;
+       
+       for (i = 0, ip = block_index; i <= jcodelength; i += 4, ip += 4) {
+               ip[0] = 0;
+               ip[1] = 0;
+               ip[2] = 0;
+               ip[3] = 0;
+               }
+       }
+
+       /* compute branch targets of exception table */
+
+       for (i = 0; i < exceptiontablelength; i++) {
+               p = extable[i].startpc;
+               bound_check(p);
+               block_insert(p);
+               p = extable[i].endpc;
+               bound_check1(p);
+               if (p < jcodelength)
+                       block_insert(p);
+               p = extable[i].handlerpc;
+               bound_check(p);
+               block_insert(p);
+               }
+
+       s_count = 1 + exceptiontablelength; /* initialize stack element counter   */
+
+       if (runverbose) {
+/*             isleafmethod=false; */
+               }
+
+#ifdef USE_THREADS
+       if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
+               isleafmethod=false;
+               }                       
+#endif
+
+       /* scan all java instructions */
+
+       for (p = 0; p < jcodelength; p = nextp) {
+
+               opcode = code_get_u1 (p);           /* fetch op code                  */
+
+               block_index[p] |= (ipc << 1);       /* store intermediate count       */
+
+               if (blockend) {
+                       block_insert(p);                /* start new block                */
+                       blockend = false;
+                       }
+
+               nextp = p + jcommandsize[opcode];   /* compute next instruction start */
+               s_count += stackreq[opcode];            /* compute stack element count    */
+
+               switch (opcode) {
+
+                       case JAVA_NOP:
+                               break;
+
+                       /* pushing constants onto the stack p */
+
+                       case JAVA_BIPUSH:
+                               LOADCONST_I(code_get_s1(p+1));
+                               break;
+
+                       case JAVA_SIPUSH:
+                               LOADCONST_I(code_get_s2(p+1));
+                               break;
+
+                       case JAVA_LDC1:
+                               i = code_get_u1(p+1);
+                               goto pushconstantitem;
+                       case JAVA_LDC2:
+                       case JAVA_LDC2W:
+                               i = code_get_u2(p + 1);
+
+                       pushconstantitem:
+
+                               if (i >= class->cpcount) 
+                                       panic ("Attempt to access constant outside range");
+
+                               switch (class->cptags[i]) {
+                                       case CONSTANT_Integer:
+                                               LOADCONST_I(((constant_integer*)
+                                                            (class->cpinfos[i]))->value);
+                                               break;
+                                       case CONSTANT_Long:
+                                               LOADCONST_L(((constant_long*)
+                                                            (class->cpinfos[i]))->value);
+                                               break;
+                                       case CONSTANT_Float:
+                                               LOADCONST_F(((constant_float*)
+                                                            (class->cpinfos[i]))->value);
+                                               break;
+                                       case CONSTANT_Double:
+                                               LOADCONST_D(((constant_double*)
+                                                            (class->cpinfos[i]))->value);
+                                               break;
+                                       case CONSTANT_String:
+                                               LOADCONST_A(literalstring_new((unicode*)
+                                                                             (class->cpinfos[i])));
+                                               break;
+                                       default: panic("Invalid constant type to push");
+                                       }
+                               break;
+
+                       case JAVA_ACONST_NULL:
+                               LOADCONST_A(NULL);
+                               break;
+
+                       case JAVA_ICONST_M1:
+                       case JAVA_ICONST_0:
+                       case JAVA_ICONST_1:
+                       case JAVA_ICONST_2:
+                       case JAVA_ICONST_3:
+                       case JAVA_ICONST_4:
+                       case JAVA_ICONST_5:
+                               LOADCONST_I(opcode - JAVA_ICONST_0);
+                               break;
+
+                       case JAVA_LCONST_0:
+                       case JAVA_LCONST_1:
+                               LOADCONST_L(opcode - JAVA_LCONST_0);
+                               break;
+
+                       case JAVA_FCONST_0:
+                       case JAVA_FCONST_1:
+                       case JAVA_FCONST_2:
+                               LOADCONST_F(opcode - JAVA_FCONST_0);
+                               break;
+
+                       case JAVA_DCONST_0:
+                       case JAVA_DCONST_1:
+                               LOADCONST_D(opcode - JAVA_DCONST_0);
+                               break;
+
+                       /* loading variables onto the stack */
+
+                       case JAVA_ILOAD:
+                       case JAVA_LLOAD:
+                       case JAVA_FLOAD:
+                       case JAVA_DLOAD:
+                       case JAVA_ALOAD:
+                               if (!iswide)
+                                       i = code_get_u1(p+1);
+                               else {
+                                       i = code_get_u2(p+1);
+                                       nextp = p+3;
+                                       iswide = false;
+                                       }
+                               OP1(opcode, i);
+                               break;
+
+                       case JAVA_ILOAD_0:
+                       case JAVA_ILOAD_1:
+                       case JAVA_ILOAD_2:
+                       case JAVA_ILOAD_3:
+                               OP1(ICMD_ILOAD, opcode - JAVA_ILOAD_0);
+                               break;
+
+                       case JAVA_LLOAD_0:
+                       case JAVA_LLOAD_1:
+                       case JAVA_LLOAD_2:
+                       case JAVA_LLOAD_3:
+                               OP1(ICMD_LLOAD, opcode - JAVA_LLOAD_0);
+                               break;
+
+                       case JAVA_FLOAD_0:
+                       case JAVA_FLOAD_1:
+                       case JAVA_FLOAD_2:
+                       case JAVA_FLOAD_3:
+                               OP1(ICMD_FLOAD, opcode - JAVA_FLOAD_0);
+                               break;
+
+                       case JAVA_DLOAD_0:
+                       case JAVA_DLOAD_1:
+                       case JAVA_DLOAD_2:
+                       case JAVA_DLOAD_3:
+                               OP1(ICMD_DLOAD, opcode - JAVA_DLOAD_0);
+                               break;
+
+                       case JAVA_ALOAD_0:
+                       case JAVA_ALOAD_1:
+                       case JAVA_ALOAD_2:
+                       case JAVA_ALOAD_3:
+                               OP1(ICMD_ALOAD, opcode - JAVA_ALOAD_0);
+                               break;
+
+                       /* storing stack values into local variables */
+
+                       case JAVA_ISTORE:
+                       case JAVA_LSTORE:
+                       case JAVA_FSTORE:
+                       case JAVA_DSTORE:
+                       case JAVA_ASTORE:
+                               if (!iswide)
+                                       i = code_get_u1(p+1);
+                               else {
+                                       i = code_get_u2(p+1);
+                                       iswide=false;
+                                       nextp = p+3;
+                                       }
+                               OP1(opcode, i);
+                               break;
+
+                       case JAVA_ISTORE_0:
+                       case JAVA_ISTORE_1:
+                       case JAVA_ISTORE_2:
+                       case JAVA_ISTORE_3:
+                               OP1(ICMD_ISTORE, opcode - JAVA_ISTORE_0);
+                               break;
+
+                       case JAVA_LSTORE_0:
+                       case JAVA_LSTORE_1:
+                       case JAVA_LSTORE_2:
+                       case JAVA_LSTORE_3:
+                               OP1(ICMD_LSTORE, opcode - JAVA_LSTORE_0);
+                               break;
+
+                       case JAVA_FSTORE_0:
+                       case JAVA_FSTORE_1:
+                       case JAVA_FSTORE_2:
+                       case JAVA_FSTORE_3:
+                               OP1(ICMD_FSTORE, opcode - JAVA_FSTORE_0);
+                               break;
+
+                       case JAVA_DSTORE_0:
+                       case JAVA_DSTORE_1:
+                       case JAVA_DSTORE_2:
+                       case JAVA_DSTORE_3:
+                               OP1(ICMD_DSTORE, opcode - JAVA_DSTORE_0);
+                               break;
+
+                       case JAVA_ASTORE_0:
+                       case JAVA_ASTORE_1:
+                       case JAVA_ASTORE_2:
+                       case JAVA_ASTORE_3:
+                               OP1(ICMD_ASTORE, opcode - JAVA_ASTORE_0);
+                               break;
+
+                       case JAVA_IINC:
+                               {
+                               int v;
+                               
+                               if (!iswide) {
+                                       i = code_get_u1(p + 1);
+                                       v = code_get_s1(p + 2);
+                                       }
+                               else {
+                                       i = code_get_u2(p + 1);
+                                       v = code_get_s2(p + 3);
+                                       iswide = false;
+                                       nextp = p+5;
+                                       }
+                               OP2I(opcode, i, v);
+                               }
+                               break;
+
+                       /* wider index for loading, storing and incrementing */
+
+                       case JAVA_WIDE:
+                               iswide = true;
+                               nextp = p + 1;
+                               break;
+
+                       /* managing arrays ************************************************/
+
+                       case JAVA_NEWARRAY:
+                               OP2I(ICMD_CHECKASIZE, 0, 0);
+                               switch (code_get_s1(p+1)) {
+                                       case 4:
+                                               BUILTIN1((functionptr)builtin_newarray_boolean, TYPE_ADR);
+                                               break;
+                                       case 5:
+                                               BUILTIN1((functionptr)builtin_newarray_char, TYPE_ADR);
+                                               break;
+                                       case 6:
+                                               BUILTIN1((functionptr)builtin_newarray_float, TYPE_ADR);
+                                               break;
+                                       case 7:
+                                               BUILTIN1((functionptr)builtin_newarray_double, TYPE_ADR);
+                                               break;
+                                       case 8:
+                                               BUILTIN1((functionptr)builtin_newarray_byte, TYPE_ADR);
+                                               break;
+                                       case 9:
+                                               BUILTIN1((functionptr)builtin_newarray_short, TYPE_ADR);
+                                               break;
+                                       case 10:
+                                               BUILTIN1((functionptr)builtin_newarray_int, TYPE_ADR);
+                                               break;
+                                       case 11:
+                                               BUILTIN1((functionptr)builtin_newarray_long, TYPE_ADR);
+                                               break;
+                                       default: panic("Invalid array-type to create");
+                                       }
+                               break;
+
+                       case JAVA_ANEWARRAY:
+                               OP2I(ICMD_CHECKASIZE, 0, 0);
+                               i = code_get_u2(p+1);
+                               /* array or class type ? */
+                               if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
+                                       LOADCONST_A(class_getconstant(class, i,
+                                                                     CONSTANT_Arraydescriptor));
+                                       BUILTIN2((functionptr)builtin_newarray_array, TYPE_ADR);
+                                       }
+                               else {
+                                       LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+                                       BUILTIN2((functionptr)builtin_anewarray, TYPE_ADR);
+                                       }
+                               break;
+
+                       case JAVA_MULTIANEWARRAY:
+                               isleafmethod=false;
+                               i = code_get_u2(p+1);
+                               {
+                               int v = code_get_u1(p+3);
+                               constant_arraydescriptor *desc =
+                                   class_getconstant (class, i, CONSTANT_Arraydescriptor);
+                               OP2A(opcode, v, desc);
+                               }
+                               break;
+
+                       case JAVA_IFEQ:
+                       case JAVA_IFLT:
+                       case JAVA_IFLE:
+                       case JAVA_IFNE:
+                       case JAVA_IFGT:
+                       case JAVA_IFGE:
+                       case JAVA_IFNULL:
+                       case JAVA_IFNONNULL:
+                       case JAVA_IF_ICMPEQ:
+                       case JAVA_IF_ICMPNE:
+                       case JAVA_IF_ICMPLT:
+                       case JAVA_IF_ICMPGT:
+                       case JAVA_IF_ICMPLE:
+                       case JAVA_IF_ICMPGE:
+                       case JAVA_IF_ACMPEQ:
+                       case JAVA_IF_ACMPNE:
+                       case JAVA_GOTO:
+                       case JAVA_JSR:
+                               i = p + code_get_s2(p+1);
+                               bound_check(i);
+                               block_insert(i);
+                               blockend = true;
+                               OP1(opcode, i);
+                               break;
+                       case JAVA_GOTO_W:
+                       case JAVA_JSR_W:
+                               i = p + code_get_s4(p+1);
+                               bound_check(i);
+                               block_insert(i);
+                               blockend = true;
+                               OP1(opcode, i);
+                               break;
+
+                       case JAVA_RET:
+                               if (!iswide)
+                                       i = code_get_u1(p+1);
+                               else {
+                                       i = code_get_u2(p+1);
+                                       nextp = p+3;
+                                       iswide = false;
+                                       }
+                               blockend = true;
+                               OP1(opcode, i);
+                               break;
+
+                       case JAVA_IRETURN:
+                       case JAVA_LRETURN:
+                       case JAVA_FRETURN:
+                       case JAVA_DRETURN:
+                       case JAVA_ARETURN:
+                       case JAVA_RETURN:
+                               blockend = true;
+                               OP(opcode);
+                               break;
+
+                       case JAVA_ATHROW:
+                               blockend = true;
+                               OP(opcode);
+                               break;
+                               
+
+                       /* table jumps ********************************/
+
+                       case JAVA_LOOKUPSWITCH:
+                               {
+                               s4 num, j;
+
+                               blockend = true;
+                               nextp = ALIGN((p + 1), 4);
+                               OP2A(opcode, 0, jcode + nextp);
+
+                               /* default target */
+
+                               j =  p + code_get_s4(nextp);
+                               *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
+                               nextp += 4;
+                               bound_check(j);
+                               block_insert(j);
+
+                               /* number of pairs */
+
+                               num = code_get_u4(nextp);
+                               *((s4*)(jcode + nextp)) = num;
+                               nextp += 4;
+
+                               for (i = 0; i < num; i++) {
+
+                                       /* value */
+
+                                       j = code_get_s4(nextp);
+                                       *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+                                       nextp += 4;
+
+                                       /* target */
+
+                                       j = p + code_get_s4(nextp);
+                                       *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+                                       nextp += 4;
+                                       bound_check(j);
+                                       block_insert(j);
+                                       }
+
+                               break;
+                               }
+
+
+                       case JAVA_TABLESWITCH:
+                               {
+                               s4 num, j;
+
+                               blockend = true;
+                               nextp = ALIGN((p + 1), 4);
+                               OP2A(opcode, 0, jcode + nextp);
+
+                               /* default target */
+
+                               j = p + code_get_s4(nextp);
+                               *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
+                               nextp += 4;
+                               bound_check(j);
+                               block_insert(j);
+
+                               /* lower bound */
+
+                               j = code_get_s4(nextp);
+                               *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
+                               nextp += 4;
+
+                               /* upper bound */
+
+                               num = code_get_s4(nextp);
+                               *((s4*)(jcode + nextp)) = num;   /* restore for little endian */
+                               nextp += 4;
+
+                               num -= j;
+
+                               for (i = 0; i <= num; i++) {
+                                       j = p + code_get_s4(nextp);
+                                       *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+                                       nextp += 4;
+                                       bound_check(j);
+                                       block_insert(j);
+                                       }
+
+                               break;
+                               }
+
+
+                       /* load and store of object fields *******************/
+
+                       case JAVA_AASTORE:
+                               BUILTIN3((functionptr) asm_builtin_aastore, TYPE_VOID);
+                               break;
+
+                       case JAVA_PUTSTATIC:
+                       case JAVA_GETSTATIC:
+                               i = code_get_u2(p + 1);
+                               {
+                               constant_FMIref *fr;
+                               fieldinfo *fi;
+                               fr = class_getconstant (class, i, CONSTANT_Fieldref);
+                               fi = class_findfield (fr->class, fr->name, fr->descriptor);
+                               compiler_addinitclass (fr->class);
+                               OP2A(opcode, fi->type, fi);
+                               }
+                               break;
+                       case JAVA_PUTFIELD:
+                       case JAVA_GETFIELD:
+                               i = code_get_u2(p + 1);
+                               {
+                               constant_FMIref *fr;
+                               fieldinfo *fi;
+                               fr = class_getconstant (class, i, CONSTANT_Fieldref);
+                               fi = class_findfield (fr->class, fr->name, fr->descriptor);
+                               OP2A(opcode, fi->type, fi);
+                               }
+                               break;
+
+
+                       /* method invocation *****/
+
+                       case JAVA_INVOKESTATIC:
+                               i = code_get_u2(p + 1);
+                               {
+                               constant_FMIref *mr;
+                               methodinfo *mi;
+                               
+                               mr = class_getconstant (class, i, CONSTANT_Methodref);
+                               mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+                               if (! (mi->flags & ACC_STATIC))
+                                       panic ("Static/Nonstatic mismatch calling static method");
+                               descriptor2types(mi);
+                               isleafmethod=false;
+                               OP2A(opcode, mi->paramcount, mi);
+                               }
+                               break;
+                       case JAVA_INVOKESPECIAL:
+                       case JAVA_INVOKEVIRTUAL:
+                               i = code_get_u2(p + 1);
+                               {
+                               constant_FMIref *mr;
+                               methodinfo *mi;
+                               
+                               mr = class_getconstant (class, i, CONSTANT_Methodref);
+                               mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+                               if (mi->flags & ACC_STATIC)
+                                       panic ("Static/Nonstatic mismatch calling static method");
+                               descriptor2types(mi);
+                               isleafmethod=false;
+                               OP2A(opcode, mi->paramcount, mi);
+                               }
+                               break;
+                       case JAVA_INVOKEINTERFACE:
+                               i = code_get_u2(p + 1);
+                               {
+                               constant_FMIref *mr;
+                               methodinfo *mi;
+                               
+                               mr = class_getconstant (class, i, CONSTANT_InterfaceMethodref);
+                               mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+                               if (mi->flags & ACC_STATIC)
+                                       panic ("Static/Nonstatic mismatch calling static method");
+                               descriptor2types(mi);
+                               isleafmethod=false;
+                               OP2A(opcode, mi->paramcount, mi);
+                               }
+                               break;
+
+                       /* miscellaneous object operations *******/
+
+                       case JAVA_NEW:
+                               i = code_get_u2 (p+1);
+                               LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+                               BUILTIN1((functionptr) builtin_new, TYPE_ADR);
+                               break;
+
+                       case JAVA_CHECKCAST:
+                               i = code_get_u2(p+1);
+
+                               /* array type cast-check */
+                               if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
+                                       LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
+                                       BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
+                                       }
+                               else { /* object type cast-check */
+                                       OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
+                                       }
+                               break;
+
+                       case JAVA_INSTANCEOF:
+                               i = code_get_u2(p+1);
+
+                               /* array type cast-check */
+                               if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
+                                       LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
+                                       BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
+                                       }
+                               else { /* object type cast-check */
+                                       OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
+                                       }
+                               break;
+
+                       case JAVA_MONITORENTER:
+#ifdef USE_THREADS
+                               if (checksync) {
+#ifdef SOFTNULLPTRCHECK
+                                       if (checknull) {
+                                               BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+                                               }
+                                       else {
+/*                                             BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID); */
+                                               BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+                                               }
+#else
+                                       BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
+#endif
+                                       }
+                               else
+#endif
+                                       {
+                                       OP(ICMD_NULLCHECKPOP);
+                                       }
+                               break;
+
+                       case JAVA_MONITOREXIT:
+#ifdef USE_THREADS
+                               if (checksync) {
+                                       BUILTIN1((functionptr) builtin_monitorexit, TYPE_VOID);
+                                       }
+                               else
+#endif
+                                       {
+                                       OP(ICMD_POP);
+                                       }
+                               break;
+
+                       /* any other basic operation **************************************/
+
+                       case JAVA_IDIV:
+                               OP(opcode);
+                               break;
+
+                       case JAVA_IREM:
+                               OP(opcode);
+                               break;
+
+                       case JAVA_LDIV:
+                               OP(opcode);
+                               break;
+
+                       case JAVA_LREM:
+                               OP(opcode);
+                               break;
+
+                       case JAVA_FREM:
+                               BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
+                               break;
+
+                       case JAVA_DREM:
+                               BUILTIN2((functionptr) builtin_drem, TYPE_DOUBLE);
+                               break;
+
+                       case JAVA_F2I:
+                               if (checkfloats) {
+                                       BUILTIN1((functionptr) builtin_f2i, TYPE_INT);
+                                       }
+                               else {
+                                       OP(opcode);
+                                       }
+                               break;
+
+                       case JAVA_F2L:
+                               if (checkfloats) {
+                                       BUILTIN1((functionptr) builtin_f2l, TYPE_LONG);
+                                       }
+                               else {
+                                       OP(opcode);
+                                       }
+                               break;
+
+                       case JAVA_D2I:
+                               if (checkfloats) {
+                                       BUILTIN1((functionptr) builtin_d2i, TYPE_INT);
+                                       }
+                               else {
+                                       OP(opcode);
+                                       }
+                               break;
+
+                       case JAVA_D2L:
+                               if (checkfloats) {
+                                       BUILTIN1((functionptr) builtin_d2l, TYPE_LONG);
+                                       }
+                               else {
+                                       OP(opcode);
+                                       }
+                               break;
+
+                       case JAVA_BREAKPOINT:
+                               panic("Illegal opcode Breakpoint encountered");
+                               break;
+
+                       case 203:
+                       case 204:
+                       case 205:
+                       case 206:
+                       case 207:
+                       case 208:
+                       case 209:
+                       case 210:
+                       case 211:
+                       case 212:
+                       case 213:
+                       case 214:
+                       case 215:
+                       case 216:
+                       case 217:
+                       case 218:
+                       case 219:
+                       case 220:
+                       case 221:
+                       case 222:
+                       case 223:
+                       case 224:
+                       case 225:
+                       case 226:
+                       case 227:
+                       case 228:
+                       case 229:
+                       case 230:
+                       case 231:
+                       case 232:
+                       case 233:
+                       case 234:
+                       case 235:
+                       case 236:
+                       case 237:
+                       case 238:
+                       case 239:
+                       case 240:
+                       case 241:
+                       case 242:
+                       case 243:
+                       case 244:
+                       case 245:
+                       case 246:
+                       case 247:
+                       case 248:
+                       case 249:
+                       case 250:
+                       case 251:
+                       case 252:
+                       case 253:
+                       case 254:
+                       case 255:
+                               printf("Illegal opcode %d at instr %d", opcode, ipc);
+                               panic("encountered");
+                               break;
+
+                       default:
+                               OP(opcode);
+                               break;
+
+                       } /* end switch */
+
+               } /* end for */
+
+       if (p != jcodelength)
+               panic("Command-sequence crosses code-boundary");
+
+       if (!blockend)
+               panic("Code does not end with branch/return/athrow - stmt");    
+
+       /* adjust block count if target 0 is not first intermediate instruction   */
+
+       if (!block_index[0] || (block_index[0] > 1))
+               b_count++;
+
+       /* copy local to global variables   */
+
+       instr_count = ipc;
+       block_count = b_count;
+       stack_count = s_count + block_count * maxstack;
+
+       /* allocate stack table */
+
+       stack = DMNEW(stackelement, stack_count);
+
+       {
+       basicblock  *bptr;
+
+       bptr = block = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
+
+       b_count = 0;
+       
+       /* additional block if target 0 is not first intermediate instruction     */
+
+       if (!block_index[0] || (block_index[0] > 1)) {
+               bptr->iinstr = instr;
+               bptr->mpc = -1;
+               bptr->flags = -1;
+               bptr->type = BBTYPE_STD;
+               bptr->branchrefs = NULL;
+               bptr->pre_count = 0;
+               bptr++;
+               b_count++;
+               }
+
+       /* allocate blocks */
+
+       for (p = 0; p < jcodelength; p++)
+               if (block_index[p] & 1) {
+                       bptr->iinstr = instr + (block_index[p] >> 1);
+                       if (b_count != 0)
+                               (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
+                       bptr->mpc = -1;
+                       bptr->flags = -1;
+                       bptr->type = BBTYPE_STD;
+                       bptr->branchrefs = NULL;
+                       block_index[p] = b_count;
+                       bptr->pre_count = 0;
+                       bptr++;
+                       b_count++;
+                       }
+
+       /* allocate additional block at end */
+
+       bptr->iinstr = NULL;
+       (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
+       bptr->icount = 0;
+       bptr->mpc = -1;
+       bptr->flags = -1;
+       bptr->type = BBTYPE_STD;
+       bptr->branchrefs = NULL;
+       bptr->pre_count = 0;
+       }
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff --git a/src/vm/jit/stack.c b/src/vm/jit/stack.c
new file mode 100644 (file)
index 0000000..ef56f35
--- /dev/null
@@ -0,0 +1,1966 @@
+/* jit/stack.c *****************************************************************
+
+       Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+       See file COPYRIGHT for information on usage and disclaimer of warranties
+
+       Parser for JavaVM to intermediate code translation
+       
+       Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
+
+       Last Change: 1997/11/18
+
+*******************************************************************************/
+
+#define CONDITIONAL_LOADCONST
+
+#ifdef STATISTICS
+#define COUNT(cnt) cnt++
+#else
+#define COUNT(cnt)
+#endif
+
+#define STACKRESET {curstack=0;stackdepth=0;}
+
+#define TYPEPANIC  {show_icmd_method();panic("Stack type mismatch");}
+#define CURKIND    curstack->varkind
+#define CURTYPE    curstack->type
+
+#define NEWSTACK(s,v,n) {new->prev=curstack;new->type=s;new->flags=0;\
+                        new->varkind=v;new->varnum=n;curstack=new;new++;}
+#define NEWSTACKn(s,n)  NEWSTACK(s,UNDEFVAR,n)
+#define NEWSTACK0(s)    NEWSTACK(s,UNDEFVAR,0)
+#define NEWXSTACK   {NEWSTACK(TYPE_ADR,STACKVAR,0);curstack=0;}
+
+#define SETDST      {iptr->dst=curstack;}
+#define POP(s)      {if(s!=curstack->type){TYPEPANIC;}\
+                     if(curstack->varkind==UNDEFVAR)curstack->varkind=TEMPVAR;\
+                     curstack=curstack->prev;}
+#define POPANY      {if(curstack->varkind==UNDEFVAR)curstack->varkind=TEMPVAR;\
+                     curstack=curstack->prev;}
+#define COPY(s,d)   {(d)->flags=0;(d)->type=(s)->type;\
+                     (d)->varkind=(s)->varkind;(d)->varnum=(s)->varnum;}
+
+#define PUSHCONST(s){NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
+#define LOAD(s,v,n) {NEWSTACK(s,v,n);SETDST;stackdepth++;}
+#define STORE(s)    {POP(s);SETDST;stackdepth--;}
+#define OP1_0(s)    {POP(s);SETDST;stackdepth--;}
+#define OP1_0ANY    {POPANY;SETDST;stackdepth--;}
+#define OP0_1(s)    {NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
+#define OP1_1(s,d)  {POP(s);NEWSTACKn(d,stackdepth-1);SETDST;}
+#define OP2_0(s)    {POP(s);POP(s);SETDST;stackdepth-=2;}
+#define OPTT2_0(t,b){POP(t);POP(b);SETDST;stackdepth-=2;}
+#define OP2_1(s)    {POP(s);POP(s);NEWSTACKn(s,stackdepth-2);SETDST;stackdepth--;}
+#define OP2IAT_1(s) {POP(TYPE_INT);POP(TYPE_ADR);NEWSTACKn(s,stackdepth-2);\
+                     SETDST;stackdepth--;}
+#define OP2IT_1(s)  {POP(TYPE_INT);POP(s);NEWSTACKn(s,stackdepth-2);\
+                     SETDST;stackdepth--;}
+#define OPTT2_1(s,d){POP(s);POP(s);NEWSTACKn(d,stackdepth-2);SETDST;stackdepth--;}
+#define OP2_2(s)    {POP(s);POP(s);NEWSTACKn(s,stackdepth-2);\
+                     NEWSTACKn(s,stackdepth-1);SETDST;}
+#define OP3TIA_0(s) {POP(s);POP(TYPE_INT);POP(TYPE_ADR);SETDST;stackdepth-=3;}
+#define OP3_0(s)    {POP(s);POP(s);POP(s);SETDST;stackdepth-=3;}
+#define POPMANY(i)  {stackdepth-=i;while(--i>=0){POPANY;}SETDST;}
+#define DUP         {NEWSTACK(CURTYPE,CURKIND,curstack->varnum);SETDST;\
+                    stackdepth++;}
+#define SWAP        {COPY(curstack,new);POPANY;COPY(curstack,new+1);POPANY;\
+                    new[0].prev=curstack;new[1].prev=new;\
+                    curstack=new+1;new+=2;SETDST;}
+#define DUP_X1      {COPY(curstack,new);COPY(curstack,new+2);POPANY;\
+                    COPY(curstack,new+1);POPANY;new[0].prev=curstack;\
+                    new[1].prev=new;new[2].prev=new+1;\
+                    curstack=new+2;new+=3;SETDST;stackdepth++;}
+#define DUP2_X1     {COPY(curstack,new+1);COPY(curstack,new+4);POPANY;\
+                    COPY(curstack,new);COPY(curstack,new+3);POPANY;\
+                    COPY(curstack,new+2);POPANY;new[0].prev=curstack;\
+                    new[1].prev=new;new[2].prev=new+1;\
+                    new[3].prev=new+2;new[4].prev=new+3;\
+                    curstack=new+4;new+=5;SETDST;stackdepth+=2;}
+#define DUP_X2      {COPY(curstack,new);COPY(curstack,new+3);POPANY;\
+                    COPY(curstack,new+2);POPANY;COPY(curstack,new+1);POPANY;\
+                    new[0].prev=curstack;new[1].prev=new;\
+                    new[2].prev=new+1;new[3].prev=new+2;\
+                    curstack=new+3;new+=4;SETDST;stackdepth++;}
+#define DUP2_X2     {COPY(curstack,new+1);COPY(curstack,new+5);POPANY;\
+                    COPY(curstack,new);COPY(curstack,new+4);POPANY;\
+                    COPY(curstack,new+3);POPANY;COPY(curstack,new+2);POPANY;\
+                    new[0].prev=curstack;new[1].prev=new;\
+                    new[2].prev=new+1;new[3].prev=new+2;\
+                    new[4].prev=new+3;new[5].prev=new+4;\
+                    curstack=new+5;new+=6;SETDST;stackdepth+=2;}
+
+#define COPYCURSTACK(copy) {\
+       int d;\
+       stackptr s;\
+       if(curstack){\
+               s=curstack;\
+               new+=stackdepth;\
+               d=stackdepth;\
+               copy=new;\
+               while(s){\
+                       copy--;d--;\
+                       copy->prev=copy-1;\
+                       copy->type=s->type;\
+                       copy->flags=0;\
+                       copy->varkind=STACKVAR;\
+                       copy->varnum=d;\
+                       s=s->prev;\
+                       }\
+               copy->prev=NULL;\
+               copy=new-1;\
+               }\
+       else\
+               copy=NULL;\
+}
+
+
+#define BBEND(s,i){\
+       i=stackdepth-1;\
+       copy=s;\
+       while(copy){\
+               if((copy->varkind==STACKVAR)&&(copy->varnum>i))\
+                       copy->varkind=TEMPVAR;\
+               else {\
+                       copy->varkind=STACKVAR;\
+                       copy->varnum=i;\
+                       }\
+               interfaces[i][copy->type].type = copy->type;\
+               interfaces[i][copy->type].flags |= copy->flags;\
+               i--;copy=copy->prev;\
+               }\
+       i=bptr->indepth-1;\
+       copy=bptr->instack;\
+       while(copy){\
+               interfaces[i][copy->type].type = copy->type;\
+               if(copy->varkind==STACKVAR){\
+                       if (copy->flags & SAVEDVAR)\
+                               interfaces[i][copy->type].flags |= SAVEDVAR;\
+                       }\
+               i--;copy=copy->prev;\
+               }\
+}
+
+       
+#define MARKREACHED(b,c) {\
+       if(b->flags<0)\
+               {COPYCURSTACK(c);b->flags=0;b->instack=c;b->indepth=stackdepth;}\
+       else {stackptr s=curstack;stackptr t=b->instack;\
+               if(b->indepth!=stackdepth)\
+                       {show_icmd_method();panic("Stack depth mismatch");}\
+               while(s){if (s->type!=t->type)\
+                               TYPEPANIC\
+                       s=s->prev;t=t->prev;\
+                       }\
+               }\
+}
+
+
+static void show_icmd_method();
+
+static void analyse_stack()
+{
+       int b_count, b_index;
+       int stackdepth;
+       stackptr curstack, new, copy;
+       int opcode, i, len, loops;
+       int superblockend, repeat, deadcode;
+       instruction *iptr = instr;
+       basicblock *bptr, *tbptr;
+       s4  *s4ptr;
+       
+       arguments_num = 0;
+       new = stack;
+       loops = 0;
+       block[0].flags = BBREACHED;
+       block[0].instack = 0;
+       block[0].indepth = 0;
+
+       for (i = 0; i < exceptiontablelength; i++) {
+               bptr = &block[block_index[extable[i].handlerpc]];
+               bptr->flags = BBREACHED;
+               bptr->type = BBTYPE_EXH;
+               bptr->instack = new;
+               bptr->indepth = 1;
+               bptr->pre_count = 10000;
+               STACKRESET;
+               NEWXSTACK;
+               }
+
+#ifdef CONDITIONAL_LOADCONST
+       b_count = block_count;
+       bptr = block;
+       while (--b_count >= 0) {
+               if (bptr->icount != 0) {
+                       iptr = bptr->iinstr + bptr->icount - 1;
+                       switch (iptr->opc) {
+                               case ICMD_RET:
+                               case ICMD_RETURN:
+                               case ICMD_IRETURN:
+                               case ICMD_LRETURN:
+                               case ICMD_FRETURN:
+                               case ICMD_DRETURN:
+                               case ICMD_ARETURN:
+                               case ICMD_ATHROW:
+                                       break;
+
+                               case ICMD_IFEQ:
+                               case ICMD_IFNE:
+                               case ICMD_IFLT:
+                               case ICMD_IFGE:
+                               case ICMD_IFGT:
+                               case ICMD_IFLE:
+
+                               case ICMD_IFNULL:
+                               case ICMD_IFNONNULL:
+
+                               case ICMD_IF_ICMPEQ:
+                               case ICMD_IF_ICMPNE:
+                               case ICMD_IF_ICMPLT:
+                               case ICMD_IF_ICMPGE:
+                               case ICMD_IF_ICMPGT:
+                               case ICMD_IF_ICMPLE:
+
+                               case ICMD_IF_ACMPEQ:
+                               case ICMD_IF_ACMPNE:
+                                       bptr[1].pre_count++;
+                               case ICMD_GOTO:
+                                       block[block_index[iptr->op1]].pre_count++;
+                                       break;
+
+                               case ICMD_TABLESWITCH:
+                                       s4ptr = iptr->val.a;
+                                       block[block_index[*s4ptr++]].pre_count++;   /* default */
+                                       i = *s4ptr++;                               /* low     */
+                                       i = *s4ptr++ - i + 1;                       /* high    */
+                                       while (--i >= 0) {
+                                               block[block_index[*s4ptr++]].pre_count++;
+                                               }
+                                       break;
+                                       
+                               case ICMD_LOOKUPSWITCH:
+                                       s4ptr = iptr->val.a;
+                                       block[block_index[*s4ptr++]].pre_count++;   /* default */
+                                       i = *s4ptr++;                               /* count   */
+                                       while (--i >= 0) {
+                                               block[block_index[s4ptr[1]]].pre_count++;
+                                               s4ptr += 2;
+                                               }
+                                       break;
+                               default:
+                                       bptr[1].pre_count++;
+                                       break;
+                               }
+                       }
+               bptr++;
+               }
+#endif
+
+
+       do {
+               loops++;
+               b_count = block_count;
+               bptr = block;
+               superblockend = true;
+               repeat = false;
+               STACKRESET;
+               deadcode = true;
+               while (--b_count >= 0) {
+                       if (bptr->flags == BBDELETED) {
+                               /* do nothing */
+                               }
+                       else if (superblockend && (bptr->flags < BBREACHED))
+                               repeat = true;
+                       else if (bptr->flags <= BBREACHED) {
+                               if (superblockend)
+                                       stackdepth = bptr->indepth;
+                               else if (bptr->flags < BBREACHED) {
+                                       COPYCURSTACK(copy);
+                                       bptr->instack = copy;
+                                       bptr->indepth = stackdepth;
+                                       }
+                               else if (bptr->indepth != stackdepth) {
+                                       show_icmd_method();
+                                       panic("Stack depth mismatch");
+                                       
+                                       }
+                               curstack = bptr->instack;
+                               deadcode = false;
+                               superblockend = false;
+                               bptr->flags = BBFINISHED;
+                               len = bptr->icount;
+                               iptr = bptr->iinstr;
+                               b_index = bptr - block;
+                               while (--len >= 0)  {
+                                       opcode = iptr->opc;
+                                       switch (opcode) {
+
+                                               /* pop 0 push 0 */
+
+                                               case ICMD_NOP:
+                                               case ICMD_CHECKASIZE:
+
+                                               case ICMD_IFEQ_ICONST:
+                                               case ICMD_IFNE_ICONST:
+                                               case ICMD_IFLT_ICONST:
+                                               case ICMD_IFGE_ICONST:
+                                               case ICMD_IFGT_ICONST:
+                                               case ICMD_IFLE_ICONST:
+                                               case ICMD_ELSE_ICONST:
+                                                       SETDST;
+                                                       break;
+
+                                               case ICMD_RET:
+                                                       locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
+                                               case ICMD_RETURN:
+                                                       COUNT(count_pcmd_return);
+                                                       SETDST;
+                                                       superblockend = true;
+                                                       break;
+
+                                               /* pop 0 push 1 const */
+                                               
+                                               case ICMD_ICONST:
+                                                       COUNT(count_pcmd_load);
+                                                       if (len > 0) {
+                                                               switch (iptr[1].opc) {
+                                                                       case ICMD_IADD:
+                                                                               iptr[0].opc = ICMD_IADDCONST;
+icmd_iconst_tail:
+                                                                               iptr[1].opc = ICMD_NOP;
+                                                                               OP1_1(TYPE_INT,TYPE_INT);
+                                                                               COUNT(count_pcmd_op);
+                                                                               break;
+                                                                       case ICMD_ISUB:
+                                                                               iptr[0].opc = ICMD_ISUBCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IMUL:
+                                                                               iptr[0].opc = ICMD_IMULCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IDIV:
+                                                                               if (iptr[0].val.i == 0x00000002)
+                                                                                       iptr[0].val.i = 1;
+                                                                               else if (iptr[0].val.i == 0x00000004)
+                                                                                       iptr[0].val.i = 2;
+                                                                               else if (iptr[0].val.i == 0x00000008)
+                                                                                       iptr[0].val.i = 3;
+                                                                               else if (iptr[0].val.i == 0x00000010)
+                                                                                       iptr[0].val.i = 4;
+                                                                               else if (iptr[0].val.i == 0x00000020)
+                                                                                       iptr[0].val.i = 5;
+                                                                               else if (iptr[0].val.i == 0x00000040)
+                                                                                       iptr[0].val.i = 6;
+                                                                               else if (iptr[0].val.i == 0x00000080)
+                                                                                       iptr[0].val.i = 7;
+                                                                               else if (iptr[0].val.i == 0x00000100)
+                                                                                       iptr[0].val.i = 8;
+                                                                               else if (iptr[0].val.i == 0x00000200)
+                                                                                       iptr[0].val.i = 9;
+                                                                               else if (iptr[0].val.i == 0x00000400)
+                                                                                       iptr[0].val.i = 10;
+                                                                               else if (iptr[0].val.i == 0x00000800)
+                                                                                       iptr[0].val.i = 11;
+                                                                               else if (iptr[0].val.i == 0x00001000)
+                                                                                       iptr[0].val.i = 12;
+                                                                               else if (iptr[0].val.i == 0x00002000)
+                                                                                       iptr[0].val.i = 13;
+                                                                               else if (iptr[0].val.i == 0x00004000)
+                                                                                       iptr[0].val.i = 14;
+                                                                               else if (iptr[0].val.i == 0x00008000)
+                                                                                       iptr[0].val.i = 15;
+                                                                               else if (iptr[0].val.i == 0x00010000)
+                                                                                       iptr[0].val.i = 16;
+                                                                               else if (iptr[0].val.i == 0x00020000)
+                                                                                       iptr[0].val.i = 17;
+                                                                               else if (iptr[0].val.i == 0x00040000)
+                                                                                       iptr[0].val.i = 18;
+                                                                               else if (iptr[0].val.i == 0x00080000)
+                                                                                       iptr[0].val.i = 19;
+                                                                               else if (iptr[0].val.i == 0x00100000)
+                                                                                       iptr[0].val.i = 20;
+                                                                               else if (iptr[0].val.i == 0x00200000)
+                                                                                       iptr[0].val.i = 21;
+                                                                               else if (iptr[0].val.i == 0x00400000)
+                                                                                       iptr[0].val.i = 22;
+                                                                               else if (iptr[0].val.i == 0x00800000)
+                                                                                       iptr[0].val.i = 23;
+                                                                               else if (iptr[0].val.i == 0x01000000)
+                                                                                       iptr[0].val.i = 24;
+                                                                               else if (iptr[0].val.i == 0x02000000)
+                                                                                       iptr[0].val.i = 25;
+                                                                               else if (iptr[0].val.i == 0x04000000)
+                                                                                       iptr[0].val.i = 26;
+                                                                               else if (iptr[0].val.i == 0x08000000)
+                                                                                       iptr[0].val.i = 27;
+                                                                               else if (iptr[0].val.i == 0x10000000)
+                                                                                       iptr[0].val.i = 28;
+                                                                               else if (iptr[0].val.i == 0x20000000)
+                                                                                       iptr[0].val.i = 29;
+                                                                               else if (iptr[0].val.i == 0x40000000)
+                                                                                       iptr[0].val.i = 30;
+                                                                               else if (iptr[0].val.i == 0x80000000)
+                                                                                       iptr[0].val.i = 31;
+                                                                               else {
+                                                                                       PUSHCONST(TYPE_INT);
+                                                                                       break;
+                                                                                       }
+                                                                               iptr[0].opc = ICMD_IDIVPOW2;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IREM:
+                                                                               if (iptr[0].val.i == 0x10001) {
+                                                                                       iptr[0].opc = ICMD_IREM0X10001;
+                                                                                       goto icmd_iconst_tail;
+                                                                                       }
+                                                                               if ((iptr[0].val.i == 0x00000002) ||
+                                                                                   (iptr[0].val.i == 0x00000004) ||
+                                                                                   (iptr[0].val.i == 0x00000008) ||
+                                                                                   (iptr[0].val.i == 0x00000010) ||
+                                                                                   (iptr[0].val.i == 0x00000020) ||
+                                                                                   (iptr[0].val.i == 0x00000040) ||
+                                                                                   (iptr[0].val.i == 0x00000080) ||
+                                                                                   (iptr[0].val.i == 0x00000100) ||
+                                                                                   (iptr[0].val.i == 0x00000200) ||
+                                                                                   (iptr[0].val.i == 0x00000400) ||
+                                                                                   (iptr[0].val.i == 0x00000800) ||
+                                                                                   (iptr[0].val.i == 0x00001000) ||
+                                                                                   (iptr[0].val.i == 0x00002000) ||
+                                                                                   (iptr[0].val.i == 0x00004000) ||
+                                                                                   (iptr[0].val.i == 0x00008000) ||
+                                                                                   (iptr[0].val.i == 0x00010000) ||
+                                                                                   (iptr[0].val.i == 0x00020000) ||
+                                                                                   (iptr[0].val.i == 0x00040000) ||
+                                                                                   (iptr[0].val.i == 0x00080000) ||
+                                                                                   (iptr[0].val.i == 0x00100000) ||
+                                                                                   (iptr[0].val.i == 0x00200000) ||
+                                                                                   (iptr[0].val.i == 0x00400000) ||
+                                                                                   (iptr[0].val.i == 0x00800000) ||
+                                                                                   (iptr[0].val.i == 0x01000000) ||
+                                                                                   (iptr[0].val.i == 0x02000000) ||
+                                                                                   (iptr[0].val.i == 0x04000000) ||
+                                                                                   (iptr[0].val.i == 0x08000000) ||
+                                                                                   (iptr[0].val.i == 0x10000000) ||
+                                                                                   (iptr[0].val.i == 0x20000000) ||
+                                                                                   (iptr[0].val.i == 0x40000000) ||
+                                                                                   (iptr[0].val.i == 0x80000000)) {
+                                                                                       iptr[0].opc = ICMD_IREMPOW2;
+                                                                                       iptr[0].val.i -= 1;
+                                                                                       goto icmd_iconst_tail;
+                                                                                       }
+                                                                               PUSHCONST(TYPE_INT);
+                                                                               break;
+                                                                       case ICMD_IAND:
+                                                                               iptr[0].opc = ICMD_IANDCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IOR:
+                                                                               iptr[0].opc = ICMD_IORCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IXOR:
+                                                                               iptr[0].opc = ICMD_IXORCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_ISHL:
+                                                                               iptr[0].opc = ICMD_ISHLCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_ISHR:
+                                                                               iptr[0].opc = ICMD_ISHRCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IUSHR:
+                                                                               iptr[0].opc = ICMD_IUSHRCONST;
+                                                                               goto icmd_iconst_tail;
+                                                                       case ICMD_IF_ICMPEQ:
+                                                                               iptr[0].opc = ICMD_IFEQ;
+icmd_if_icmp_tail:
+                                                                               iptr[0].op1 = iptr[1].op1;
+                                                                               bptr->icount--;
+                                                                               len--;
+                                                                               /* iptr[1].opc = ICMD_NOP; */
+                                                                               OP1_0(TYPE_INT);
+                                                                               tbptr = block + block_index[iptr->op1];
+                                                                               MARKREACHED(tbptr, copy);
+                                                                               COUNT(count_pcmd_bra);
+                                                                               break;
+                                                                       case ICMD_IF_ICMPLT:
+                                                                               iptr[0].opc = ICMD_IFLT;
+                                                                               goto icmd_if_icmp_tail;
+                                                                       case ICMD_IF_ICMPLE:
+                                                                               iptr[0].opc = ICMD_IFLE;
+                                                                               goto icmd_if_icmp_tail;
+                                                                       case ICMD_IF_ICMPNE:
+                                                                               iptr[0].opc = ICMD_IFNE;
+                                                                               goto icmd_if_icmp_tail;
+                                                                       case ICMD_IF_ICMPGT:
+                                                                               iptr[0].opc = ICMD_IFGT;
+                                                                               goto icmd_if_icmp_tail;
+                                                                       case ICMD_IF_ICMPGE:
+                                                                               iptr[0].opc = ICMD_IFGE;
+                                                                               goto icmd_if_icmp_tail;
+                                                                       default:
+                                                                               PUSHCONST(TYPE_INT);
+                                                                       }
+                                                               }
+                                                       else
+                                                               PUSHCONST(TYPE_INT);
+                                                       break;
+                                               case ICMD_LCONST:
+                                                       COUNT(count_pcmd_load);
+                                                       if (len > 0) {
+                                                               switch (iptr[1].opc) {
+                                                                       case ICMD_LADD:
+                                                                               iptr[0].opc = ICMD_LADDCONST;
+icmd_lconst_tail:
+                                                                               iptr[1].opc = ICMD_NOP;
+                                                                               OP1_1(TYPE_LNG,TYPE_LNG);
+                                                                               COUNT(count_pcmd_op);
+                                                                               break;
+                                                                       case ICMD_LSUB:
+                                                                               iptr[0].opc = ICMD_LSUBCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LMUL:
+                                                                               iptr[0].opc = ICMD_LMULCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LDIV:
+                                                                               if (iptr[0].val.l == 0x00000002)
+                                                                                       iptr[0].val.l = 1;
+                                                                               else if (iptr[0].val.l == 0x00000004)
+                                                                                       iptr[0].val.l = 2;
+                                                                               else if (iptr[0].val.l == 0x00000008)
+                                                                                       iptr[0].val.l = 3;
+                                                                               else if (iptr[0].val.l == 0x00000010)
+                                                                                       iptr[0].val.l = 4;
+                                                                               else if (iptr[0].val.l == 0x00000020)
+                                                                                       iptr[0].val.l = 5;
+                                                                               else if (iptr[0].val.l == 0x00000040)
+                                                                                       iptr[0].val.l = 6;
+                                                                               else if (iptr[0].val.l == 0x00000080)
+                                                                                       iptr[0].val.l = 7;
+                                                                               else if (iptr[0].val.l == 0x00000100)
+                                                                                       iptr[0].val.l = 8;
+                                                                               else if (iptr[0].val.l == 0x00000200)
+                                                                                       iptr[0].val.l = 9;
+                                                                               else if (iptr[0].val.l == 0x00000400)
+                                                                                       iptr[0].val.l = 10;
+                                                                               else if (iptr[0].val.l == 0x00000800)
+                                                                                       iptr[0].val.l = 11;
+                                                                               else if (iptr[0].val.l == 0x00001000)
+                                                                                       iptr[0].val.l = 12;
+                                                                               else if (iptr[0].val.l == 0x00002000)
+                                                                                       iptr[0].val.l = 13;
+                                                                               else if (iptr[0].val.l == 0x00004000)
+                                                                                       iptr[0].val.l = 14;
+                                                                               else if (iptr[0].val.l == 0x00008000)
+                                                                                       iptr[0].val.l = 15;
+                                                                               else if (iptr[0].val.l == 0x00010000)
+                                                                                       iptr[0].val.l = 16;
+                                                                               else if (iptr[0].val.l == 0x00020000)
+                                                                                       iptr[0].val.l = 17;
+                                                                               else if (iptr[0].val.l == 0x00040000)
+                                                                                       iptr[0].val.l = 18;
+                                                                               else if (iptr[0].val.l == 0x00080000)
+                                                                                       iptr[0].val.l = 19;
+                                                                               else if (iptr[0].val.l == 0x00100000)
+                                                                                       iptr[0].val.l = 20;
+                                                                               else if (iptr[0].val.l == 0x00200000)
+                                                                                       iptr[0].val.l = 21;
+                                                                               else if (iptr[0].val.l == 0x00400000)
+                                                                                       iptr[0].val.l = 22;
+                                                                               else if (iptr[0].val.l == 0x00800000)
+                                                                                       iptr[0].val.l = 23;
+                                                                               else if (iptr[0].val.l == 0x01000000)
+                                                                                       iptr[0].val.l = 24;
+                                                                               else if (iptr[0].val.l == 0x02000000)
+                                                                                       iptr[0].val.l = 25;
+                                                                               else if (iptr[0].val.l == 0x04000000)
+                                                                                       iptr[0].val.l = 26;
+                                                                               else if (iptr[0].val.l == 0x08000000)
+                                                                                       iptr[0].val.l = 27;
+                                                                               else if (iptr[0].val.l == 0x10000000)
+                                                                                       iptr[0].val.l = 28;
+                                                                               else if (iptr[0].val.l == 0x20000000)
+                                                                                       iptr[0].val.l = 29;
+                                                                               else if (iptr[0].val.l == 0x40000000)
+                                                                                       iptr[0].val.l = 30;
+                                                                               else if (iptr[0].val.l == 0x80000000)
+                                                                                       iptr[0].val.l = 31;
+                                                                               else {
+                                                                                       PUSHCONST(TYPE_LNG);
+                                                                                       break;
+                                                                                       }
+                                                                               iptr[0].opc = ICMD_LDIVPOW2;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LREM:
+                                                                               if (iptr[0].val.l == 0x10001) {
+                                                                                       iptr[0].opc = ICMD_LREM0X10001;
+                                                                                       goto icmd_lconst_tail;
+                                                                                       }
+                                                                               if ((iptr[0].val.l == 0x00000002) ||
+                                                                                   (iptr[0].val.l == 0x00000004) ||
+                                                                                   (iptr[0].val.l == 0x00000008) ||
+                                                                                   (iptr[0].val.l == 0x00000010) ||
+                                                                                   (iptr[0].val.l == 0x00000020) ||
+                                                                                   (iptr[0].val.l == 0x00000040) ||
+                                                                                   (iptr[0].val.l == 0x00000080) ||
+                                                                                   (iptr[0].val.l == 0x00000100) ||
+                                                                                   (iptr[0].val.l == 0x00000200) ||
+                                                                                   (iptr[0].val.l == 0x00000400) ||
+                                                                                   (iptr[0].val.l == 0x00000800) ||
+                                                                                   (iptr[0].val.l == 0x00001000) ||
+                                                                                   (iptr[0].val.l == 0x00002000) ||
+                                                                                   (iptr[0].val.l == 0x00004000) ||
+                                                                                   (iptr[0].val.l == 0x00008000) ||
+                                                                                   (iptr[0].val.l == 0x00010000) ||
+                                                                                   (iptr[0].val.l == 0x00020000) ||
+                                                                                   (iptr[0].val.l == 0x00040000) ||
+                                                                                   (iptr[0].val.l == 0x00080000) ||
+                                                                                   (iptr[0].val.l == 0x00100000) ||
+                                                                                   (iptr[0].val.l == 0x00200000) ||
+                                                                                   (iptr[0].val.l == 0x00400000) ||
+                                                                                   (iptr[0].val.l == 0x00800000) ||
+                                                                                   (iptr[0].val.l == 0x01000000) ||
+                                                                                   (iptr[0].val.l == 0x02000000) ||
+                                                                                   (iptr[0].val.l == 0x04000000) ||
+                                                                                   (iptr[0].val.l == 0x08000000) ||
+                                                                                   (iptr[0].val.l == 0x10000000) ||
+                                                                                   (iptr[0].val.l == 0x20000000) ||
+                                                                                   (iptr[0].val.l == 0x40000000) ||
+                                                                                   (iptr[0].val.l == 0x80000000)) {
+                                                                                       iptr[0].opc = ICMD_LREMPOW2;
+                                                                                       iptr[0].val.l -= 1;
+                                                                                       goto icmd_lconst_tail;
+                                                                                       }
+                                                                               PUSHCONST(TYPE_LNG);
+                                                                               break;
+                                                                       case ICMD_LAND:
+                                                                               iptr[0].opc = ICMD_LANDCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LOR:
+                                                                               iptr[0].opc = ICMD_LORCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LXOR:
+                                                                               iptr[0].opc = ICMD_LXORCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LSHL:
+                                                                               iptr[0].opc = ICMD_LSHLCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LSHR:
+                                                                               iptr[0].opc = ICMD_LSHRCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LUSHR:
+                                                                               iptr[0].opc = ICMD_LUSHRCONST;
+                                                                               goto icmd_lconst_tail;
+                                                                       case ICMD_LCMP:
+                                                                               if ((len > 1) && (iptr[2].val.i == 0)) {
+                                                                                       switch (iptr[2].opc) {
+                                                                                       case ICMD_IFEQ:
+                                                                                               iptr[0].opc = ICMD_IF_LEQ;
+icmd_lconst_lcmp_tail:
+                                                                                               iptr[0].op1 = iptr[2].op1;
+                                                                                               bptr->icount -= 2;
+                                                                                               len -= 2;
+                                                                                               /* iptr[1].opc = ICMD_NOP;
+                                                                                               iptr[2].opc = ICMD_NOP; */
+                                                                                               OP1_0(TYPE_LNG);
+                                                                                               tbptr = block + block_index[iptr->op1];
+                                                                                               MARKREACHED(tbptr, copy);
+                                                                                               COUNT(count_pcmd_bra);
+                                                                                               COUNT(count_pcmd_op);
+                                                                                               break;
+                                                                                       case ICMD_IFNE:
+                                                                                               iptr[0].opc = ICMD_IF_LNE;
+                                                                                               goto icmd_lconst_lcmp_tail;
+                                                                                       case ICMD_IFLT:
+                                                                                               iptr[0].opc = ICMD_IF_LLT;
+                                                                                               goto icmd_lconst_lcmp_tail;
+                                                                                       case ICMD_IFGT:
+                                                                                               iptr[0].opc = ICMD_IF_LGT;
+                                                                                               goto icmd_lconst_lcmp_tail;
+                                                                                       case ICMD_IFLE:
+                                                                                               iptr[0].opc = ICMD_IF_LLE;
+                                                                                               goto icmd_lconst_lcmp_tail;
+                                                                                       case ICMD_IFGE:
+                                                                                               iptr[0].opc = ICMD_IF_LGE;
+                                                                                               goto icmd_lconst_lcmp_tail;
+                                                                                       default:
+                                                                                               PUSHCONST(TYPE_LNG);
+                                                                                       } /* switch (iptr[2].opc) */
+                                                                                       } /* if (iptr[2].val.i == 0) */
+                                                                               else
+                                                                                       PUSHCONST(TYPE_LNG);
+                                                                               break;
+                                                                       default:
+                                                                               PUSHCONST(TYPE_LNG);
+                                                                       }
+                                                               }
+                                                       else
+                                                               PUSHCONST(TYPE_LNG);
+                                                       break;
+                                               case ICMD_FCONST:
+                                                       COUNT(count_pcmd_load);
+                                                       PUSHCONST(TYPE_FLT);
+                                                       break;
+                                               case ICMD_DCONST:
+                                                       COUNT(count_pcmd_load);
+                                                       PUSHCONST(TYPE_DBL);
+                                                       break;
+                                               case ICMD_ACONST:
+                                                       COUNT(count_pcmd_load);
+                                                       PUSHCONST(TYPE_ADR);
+                                                       break;
+
+                                               /* pop 0 push 1 load */
+                                               
+                                               case ICMD_ILOAD:
+                                               case ICMD_LLOAD:
+                                               case ICMD_FLOAD:
+                                               case ICMD_DLOAD:
+                                               case ICMD_ALOAD:
+                                                       COUNT(count_load_instruction);
+                                                       i = opcode-ICMD_ILOAD;
+                                                       locals[iptr->op1][i].type = i;
+                                                       LOAD(i, LOCALVAR, iptr->op1);
+                                                       break;
+
+                                               /* pop 2 push 1 */
+
+                                               case ICMD_IALOAD:
+                                               case ICMD_LALOAD:
+                                               case ICMD_FALOAD:
+                                               case ICMD_DALOAD:
+                                               case ICMD_AALOAD:
+                                                       COUNT(count_check_null);
+                                                       COUNT(count_check_bound);
+                                                       COUNT(count_pcmd_mem);
+                                                       OP2IAT_1(opcode-ICMD_IALOAD);
+                                                       break;
+
+                                               case ICMD_BALOAD:
+                                               case ICMD_CALOAD:
+                                               case ICMD_SALOAD:
+                                                       COUNT(count_check_null);
+                                                       COUNT(count_check_bound);
+                                                       COUNT(count_pcmd_mem);
+                                                       OP2IAT_1(TYPE_INT);
+                                                       break;
+
+                                               /* pop 0 push 0 iinc */
+
+                                               case ICMD_IINC:
+#ifdef STATISTICS
+                                                       i = stackdepth;
+                                                       if (i >= 10)
+                                                               count_store_depth[10]++;
+                                                       else
+                                                               count_store_depth[i]++;
+#endif
+                                                       copy = curstack;
+                                                       i = stackdepth - 1;
+                                                       while (copy) {
+                                                               if ((copy->varkind == LOCALVAR) &&
+                                                                   (copy->varnum == curstack->varnum)) {
+                                                                       copy->varkind = TEMPVAR;
+                                                                       copy->varnum = i;
+                                                                       }
+                                                               i--;
+                                                               copy = copy->prev;
+                                                               }
+                                                       SETDST;
+                                                       break;
+
+                                               /* pop 1 push 0 store */
+
+                                               case ICMD_ISTORE:
+                                               case ICMD_LSTORE:
+                                               case ICMD_FSTORE:
+                                               case ICMD_DSTORE:
+                                               case ICMD_ASTORE:
+                                                       i = opcode-ICMD_ISTORE;
+                                                       locals[iptr->op1][i].type = i;
+#ifdef STATISTICS
+                                                       count_pcmd_store++;
+                                                       i = new - curstack;
+                                                       if (i >= 20)
+                                                               count_store_length[20]++;
+                                                       else
+                                                               count_store_length[i]++;
+                                                       i = stackdepth - 1;
+                                                       if (i >= 10)
+                                                               count_store_depth[10]++;
+                                                       else
+                                                               count_store_depth[i]++;
+#endif
+                                                       copy = curstack->prev;
+                                                       i = stackdepth - 2;
+                                                       while (copy) {
+                                                               if ((copy->varkind == LOCALVAR) &&
+                                                                   (copy->varnum == curstack->varnum)) {
+                                                                       copy->varkind = TEMPVAR;
+                                                                       copy->varnum = i;
+                                                                       }
+                                                               i--;
+                                                               copy = copy->prev;
+                                                               }
+                                                       if ((new - curstack) == 1) {
+                                                               curstack->varkind = LOCALVAR;
+                                                               curstack->varnum = iptr->op1;
+                                                               };
+                                                       STORE(opcode-ICMD_ISTORE);
+                                                       break;
+
+                                               /* pop 3 push 0 */
+
+                                               case ICMD_IASTORE:
+                                               case ICMD_LASTORE:
+                                               case ICMD_FASTORE:
+                                               case ICMD_DASTORE:
+                                               case ICMD_AASTORE:
+                                                       COUNT(count_check_null);
+                                                       COUNT(count_check_bound);
+                                                       COUNT(count_pcmd_mem);
+                                                       OP3TIA_0(opcode-ICMD_IASTORE);
+                                                       break;
+                                               case ICMD_BASTORE:
+                                               case ICMD_CASTORE:
+                                               case ICMD_SASTORE:
+                                                       COUNT(count_check_null);
+                                                       COUNT(count_check_bound);
+                                                       COUNT(count_pcmd_mem);
+                                                       OP3TIA_0(TYPE_INT);
+                                                       break;
+
+                                               /* pop 1 push 0 */
+
+                                               case ICMD_POP:
+                                                       OP1_0ANY;
+                                                       break;
+
+                                               case ICMD_IRETURN:
+                                               case ICMD_LRETURN:
+                                               case ICMD_FRETURN:
+                                               case ICMD_DRETURN:
+                                               case ICMD_ARETURN:
+                                                       COUNT(count_pcmd_return);
+                                                       OP1_0(opcode-ICMD_IRETURN);
+                                                       superblockend = true;
+                                                       break;
+
+                                               case ICMD_ATHROW:
+                                                       COUNT(count_check_null);
+                                                       OP1_0(TYPE_ADR);
+                                                       STACKRESET;
+                                                       SETDST;
+                                                       superblockend = true;
+                                                       break;
+
+                                               case ICMD_PUTSTATIC:
+                                                       COUNT(count_pcmd_mem);
+                                                       OP1_0(iptr->op1);
+                                                       break;
+
+                                               /* pop 1 push 0 branch */
+
+                                               case ICMD_IFNULL:
+                                               case ICMD_IFNONNULL:
+                                                       COUNT(count_pcmd_bra);
+                                                       OP1_0(TYPE_ADR);
+                                                       tbptr = block + block_index[iptr->op1];
+                                                       MARKREACHED(tbptr, copy);
+                                                       break;
+
+                                               case ICMD_IFEQ:
+                                               case ICMD_IFNE:
+                                               case ICMD_IFLT:
+                                               case ICMD_IFGE:
+                                               case ICMD_IFGT:
+                                               case ICMD_IFLE:
+                                                       COUNT(count_pcmd_bra);
+#ifdef CONDITIONAL_LOADCONST
+                                                       {
+                                                       tbptr = block + b_index;
+                                                       if ((b_count >= 3) &&
+                                                           ((b_index + 2) == block_index[iptr[0].op1]) &&
+                                                           (tbptr[1].pre_count == 1) &&
+                                                           (iptr[1].opc == ICMD_ICONST) &&
+                                                           (iptr[2].opc == ICMD_GOTO)   &&
+                                                           ((b_index + 3) == block_index[iptr[2].op1]) &&
+                                                           (tbptr[2].pre_count == 1) &&
+                                                           (iptr[3].opc == ICMD_ICONST)) {
+                                                               OP1_1(TYPE_INT, TYPE_INT);
+                                                               switch (iptr[0].opc) {
+                                                                       case ICMD_IFEQ:
+                                                                               iptr[0].opc = ICMD_IFNE_ICONST;
+                                                                               break;
+                                                                       case ICMD_IFNE:
+                                                                               iptr[0].opc = ICMD_IFEQ_ICONST;
+                                                                               break;
+                                                                       case ICMD_IFLT:
+                                                                               iptr[0].opc = ICMD_IFGE_ICONST;
+                                                                               break;
+                                                                       case ICMD_IFGE:
+                                                                               iptr[0].opc = ICMD_IFLT_ICONST;
+                                                                               break;
+                                                                       case ICMD_IFGT:
+                                                                               iptr[0].opc = ICMD_IFLE_ICONST;
+                                                                               break;
+                                                                       case ICMD_IFLE:
+                                                                               iptr[0].opc = ICMD_IFGT_ICONST;
+                                                                               break;
+                                                                       }
+                                                               iptr[0].val.i = iptr[1].val.i;
+                                                               iptr[1].opc = ICMD_ELSE_ICONST;
+                                                               iptr[1].val.i = iptr[3].val.i;
+                                                               iptr[2].opc = ICMD_NOP;
+                                                               iptr[3].opc = ICMD_NOP;
+                                                               tbptr[1].flags = BBDELETED;
+                                                               tbptr[2].flags = BBDELETED;
+                                                               tbptr[1].icount = 0;
+                                                               tbptr[2].icount = 0;
+                                                               if (tbptr[3].pre_count == 2) {
+                                                                       len += tbptr[3].icount + 3;
+                                                                       bptr->icount += tbptr[3].icount + 3;
+                                                                       tbptr[3].flags = BBDELETED;
+                                                                       tbptr[3].icount = 0;
+                                                                       b_index++;
+                                                                       }
+                                                               else {
+                                                                       bptr->icount++;
+                                                                       len ++;
+                                                                       }
+                                                               b_index += 2;
+                                                               break;
+                                                               }
+                                                       }
+#endif
+                                                       OP1_0(TYPE_INT);
+                                                       tbptr = block + block_index[iptr->op1];
+                                                       MARKREACHED(tbptr, copy);
+                                                       break;
+
+                                               /* pop 0 push 0 branch */
+
+                                               case ICMD_GOTO:
+                                                       COUNT(count_pcmd_bra);
+                                                       tbptr = block + block_index[iptr->op1];
+                                                       MARKREACHED(tbptr, copy);
+                                                       SETDST;
+                                                       superblockend = true;
+                                                       break;
+
+                                               /* pop 1 push 0 table branch */
+
+                                               case ICMD_TABLESWITCH:
+                                                       COUNT(count_pcmd_table);
+                                                       OP1_0(TYPE_INT);
+                                                       s4ptr = iptr->val.a;
+                                                       tbptr = block + block_index[*s4ptr++]; /* default */
+                                                       MARKREACHED(tbptr, copy);
+                                                       i = *s4ptr++;                          /* low     */
+                                                       i = *s4ptr++ - i + 1;                  /* high    */
+                                                       while (--i >= 0) {
+                                                               tbptr = block + block_index[*s4ptr++];
+                                                               MARKREACHED(tbptr, copy);
+                                                               }
+                                                       SETDST;
+                                                       superblockend = true;
+                                                       break;
+                                                       
+                                               /* pop 1 push 0 table branch */
+
+                                               case ICMD_LOOKUPSWITCH:
+                                                       COUNT(count_pcmd_table);
+                                                       OP1_0(TYPE_INT);
+                                                       s4ptr = iptr->val.a;
+                                                       tbptr = block + block_index[*s4ptr++]; /* default */
+                                                       MARKREACHED(tbptr, copy);
+                                                       i = *s4ptr++;                          /* count   */
+                                                       while (--i >= 0) {
+                                                               tbptr = block + block_index[s4ptr[1]];
+                                                               MARKREACHED(tbptr, copy);
+                                                               s4ptr += 2;
+                                                               }
+                                                       SETDST;
+                                                       superblockend = true;
+                                                       break;
+
+                                               case ICMD_NULLCHECKPOP:
+                                               case ICMD_MONITORENTER:
+                                                       COUNT(count_check_null);
+                                               case ICMD_MONITOREXIT:
+                                                       OP1_0(TYPE_ADR);
+                                                       break;
+
+                                               /* pop 2 push 0 branch */
+
+                                               case ICMD_IF_ICMPEQ:
+                                               case ICMD_IF_ICMPNE:
+                                               case ICMD_IF_ICMPLT:
+                                               case ICMD_IF_ICMPGE:
+                                               case ICMD_IF_ICMPGT:
+                                               case ICMD_IF_ICMPLE:
+                                                       COUNT(count_pcmd_bra);
+                                                       OP2_0(TYPE_INT);
+                                                       tbptr = block + block_index[iptr->op1];
+                                                       MARKREACHED(tbptr, copy);
+                                                       break;
+
+                                               case ICMD_IF_ACMPEQ:
+                                               case ICMD_IF_ACMPNE:
+                                                       COUNT(count_pcmd_bra);
+                                                       OP2_0(TYPE_ADR);
+                                                       tbptr = block + block_index[iptr->op1];
+                                                       MARKREACHED(tbptr, copy);
+                                                       break;
+
+                                               /* pop 2 push 0 */
+
+                                               case ICMD_PUTFIELD:
+                                                       COUNT(count_check_null);
+                                                       COUNT(count_pcmd_mem);
+                                                       OPTT2_0(iptr->op1,TYPE_ADR);
+                                                       break;
+
+                                               case ICMD_POP2:
+                                                       if (! IS_2_WORD_TYPE(curstack->type)) {
+                                                               OP1_0ANY;                /* second pop */
+                                                               }
+                                                       else
+                                                               iptr->opc = ICMD_POP;
+                                                       OP1_0ANY;
+                                                       break;
+
+                                               /* pop 0 push 1 dup */
+                                               
+                                               case ICMD_DUP:
+                                                       COUNT(count_dup_instruction);
+                                                       DUP;
+                                                       break;
+
+                                               case ICMD_DUP2:
+                                                       if (IS_2_WORD_TYPE(curstack->type)) {
+                                                               iptr->opc = ICMD_DUP;
+                                                               DUP;
+                                                               }
+                                                       else {
+                                                               copy = curstack;
+                                                               NEWSTACK(copy[-1].type, copy[-1].varkind,
+                                                                        copy[-1].varnum);
+                                                               NEWSTACK(copy[ 0].type, copy[ 0].varkind,
+                                                                        copy[ 0].varnum);
+                                                               SETDST;
+                                                               stackdepth+=2;
+                                                               }
+                                                       break;
+
+                                               /* pop 2 push 3 dup */
+                                               
+                                               case ICMD_DUP_X1:
+                                                       DUP_X1;
+                                                       break;
+
+                                               case ICMD_DUP2_X1:
+                                                       if (IS_2_WORD_TYPE(curstack->type)) {
+                                                               iptr->opc = ICMD_DUP_X1;
+                                                               DUP_X1;
+                                                               }
+                                                       else {
+                                                               DUP2_X1;
+                                                               }
+                                                       break;
+
+                                               /* pop 3 push 4 dup */
+                                               
+                                               case ICMD_DUP_X2:
+                                                       if (IS_2_WORD_TYPE(curstack[-1].type)) {
+                                                               iptr->opc = ICMD_DUP_X1;
+                                                               DUP_X1;
+                                                               }
+                                                       else {
+                                                               DUP_X2;
+                                                               }
+                                                       break;
+
+                                               case ICMD_DUP2_X2:
+                                                       if (IS_2_WORD_TYPE(curstack->type)) {
+                                                               if (IS_2_WORD_TYPE(curstack[-1].type)) {
+                                                                       iptr->opc = ICMD_DUP_X1;
+                                                                       DUP_X1;
+                                                                       }
+                                                               else {
+                                                                       iptr->opc = ICMD_DUP_X2;
+                                                                       DUP_X2;
+                                                                       }
+                                                               }
+                                                       else
+                                                               if (IS_2_WORD_TYPE(curstack[-2].type)) {
+                                                                       iptr->opc = ICMD_DUP2_X1;
+                                                                       DUP2_X1;
+                                                                       }
+                                                               else {
+                                                                       DUP2_X2;
+                                                                       }
+                                                       break;
+
+                                               /* pop 2 push 2 swap */
+                                               
+                                               case ICMD_SWAP:
+                                                       SWAP;
+                                                       break;
+
+                                               /* pop 2 push 1 */
+                                               
+                                               case ICMD_IDIV:
+                                                       if (!(SUPPORT_DIVISION)) {
+                                                               iptr[0].opc = ICMD_BUILTIN2;
+                                                               iptr[0].op1 = TYPE_INT;
+                                                               iptr[0].val.a = (functionptr) asm_builtin_idiv;
+                                                               isleafmethod = false;
+                                                               goto builtin2;
+                                                               }
+
+                                               case ICMD_LDIV:
+                                                       if (!(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_MULDIV)) {
+                                                               iptr[0].opc = ICMD_BUILTIN2;
+                                                               iptr[0].op1 = TYPE_LNG;
+                                                               iptr[0].val.a = (functionptr) asm_builtin_ldiv;
+                                                               isleafmethod = false;
+                                                               goto builtin2;
+                                                               }
+
+                                               case ICMD_IREM:
+                                                       if (!(SUPPORT_DIVISION)) {
+                                                               iptr[0].opc = ICMD_BUILTIN2;
+                                                               iptr[0].op1 = TYPE_INT;
+                                                               iptr[0].val.a = (functionptr) asm_builtin_irem;
+                                                               isleafmethod = false;
+                                                               goto builtin2;
+                                                               }
+
+                                               case ICMD_LREM:
+                                                       if (!(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_MULDIV)) {
+                                                               iptr[0].opc = ICMD_BUILTIN2;
+                                                               iptr[0].op1 = TYPE_LNG;
+                                                               iptr[0].val.a = (functionptr) asm_builtin_lrem;
+                                                               isleafmethod = false;
+                                                               goto builtin2;
+                                                               }
+
+                                               case ICMD_IADD:
+                                               case ICMD_ISUB:
+                                               case ICMD_IMUL:
+
+                                               case ICMD_ISHL:
+                                               case ICMD_ISHR:
+                                               case ICMD_IUSHR:
+                                               case ICMD_IAND:
+                                               case ICMD_IOR:
+                                               case ICMD_IXOR:
+                                                       COUNT(count_pcmd_op);
+                                                       OP2_1(TYPE_INT);
+                                                       break;
+
+                                               case ICMD_LADD:
+                                               case ICMD_LSUB:
+                                               case ICMD_LMUL:
+
+                                               case ICMD_LOR:
+                                               case ICMD_LAND:
+                                               case ICMD_LXOR:
+                                                       COUNT(count_pcmd_op);
+                                                       OP2_1(TYPE_LNG);
+                                                       break;
+
+                                               case ICMD_LSHL:
+                                               case ICMD_LSHR:
+                                               case ICMD_LUSHR:
+                                                       COUNT(count_pcmd_op);
+                                                       OP2IT_1(TYPE_LNG);
+                                                       break;
+
+                                               case ICMD_FADD:
+                                               case ICMD_FSUB:
+                                               case ICMD_FMUL:
+                                               case ICMD_FDIV:
+                                               case ICMD_FREM:
+                                                       COUNT(count_pcmd_op);
+                                                       OP2_1(TYPE_FLT);
+                                                       break;
+
+                                               case ICMD_DADD:
+                                               case ICMD_DSUB:
+                                               case ICMD_DMUL:
+                                               case ICMD_DDIV:
+                                               case ICMD_DREM:
+                                                       COUNT(count_pcmd_op);
+                                                       OP2_1(TYPE_DBL);
+                                                       break;
+
+                                               case ICMD_LCMP:
+                                                       COUNT(count_pcmd_op);
+                                                       if ((len > 0) && (iptr[1].val.i == 0)) {
+                                                               switch (iptr[1].opc) {
+                                                                       case ICMD_IFEQ:
+                                                                               iptr[0].opc = ICMD_IF_LCMPEQ;
+icmd_lcmp_if_tail:
+                                                                               iptr[0].op1 = iptr[1].op1;
+                                                                               len--;
+                                                                               bptr->icount--;
+                                                                               /* iptr[1].opc = ICMD_NOP; */
+                                                                               OP2_0(TYPE_LNG);
+                                                                               tbptr = block + block_index[iptr->op1];
+                                                                               MARKREACHED(tbptr, copy);
+                                                                               COUNT(count_pcmd_bra);
+                                                                               break;
+                                                                       case ICMD_IFNE:
+                                                                               iptr[0].opc = ICMD_IF_LCMPNE;
+                                                                               goto icmd_lcmp_if_tail;
+                                                                       case ICMD_IFLT:
+                                                                               iptr[0].opc = ICMD_IF_LCMPLT;
+                                                                               goto icmd_lcmp_if_tail;
+                                                                       case ICMD_IFGT:
+                                                                               iptr[0].opc = ICMD_IF_LCMPGT;
+                                                                               goto icmd_lcmp_if_tail;
+                                                                       case ICMD_IFLE:
+                                                                               iptr[0].opc = ICMD_IF_LCMPLE;
+                                                                               goto icmd_lcmp_if_tail;
+                                                                       case ICMD_IFGE:
+                                                                               iptr[0].opc = ICMD_IF_LCMPGE;
+                                                                               goto icmd_lcmp_if_tail;
+                                                                       default:
+                                                                               OPTT2_1(TYPE_LNG, TYPE_INT);
+                                                                       }
+                                                               }
+                                                       else
+                                                               OPTT2_1(TYPE_LNG, TYPE_INT);
+                                                       break;
+                                               case ICMD_FCMPL:
+                                               case ICMD_FCMPG:
+                                                       COUNT(count_pcmd_op);
+                                                       OPTT2_1(TYPE_FLT, TYPE_INT);
+                                                       break;
+                                               case ICMD_DCMPL:
+                                               case ICMD_DCMPG:
+                                                       COUNT(count_pcmd_op);
+                                                       OPTT2_1(TYPE_DBL, TYPE_INT);
+                                                       break;
+
+                                               /* pop 1 push 1 */
+                                               
+                                               case ICMD_INEG:
+                                               case ICMD_INT2BYTE:
+                                               case ICMD_INT2CHAR:
+                                               case ICMD_INT2SHORT:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_INT, TYPE_INT);
+                                                       break;
+                                               case ICMD_LNEG:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_LNG, TYPE_LNG);
+                                                       break;
+                                               case ICMD_FNEG:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_FLT, TYPE_FLT);
+                                                       break;
+                                               case ICMD_DNEG:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_DBL, TYPE_DBL);
+                                                       break;
+
+                                               case ICMD_I2L:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_INT, TYPE_LNG);
+                                                       break;
+                                               case ICMD_I2F:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_INT, TYPE_FLT);
+                                                       break;
+                                               case ICMD_I2D:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_INT, TYPE_DBL);
+                                                       break;
+                                               case ICMD_L2I:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_LNG, TYPE_INT);
+                                                       break;
+                                               case ICMD_L2F:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_LNG, TYPE_FLT);
+                                                       break;
+                                               case ICMD_L2D:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_LNG, TYPE_DBL);
+                                                       break;
+                                               case ICMD_F2I:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_FLT, TYPE_INT);
+                                                       break;
+                                               case ICMD_F2L:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_FLT, TYPE_LNG);
+                                                       break;
+                                               case ICMD_F2D:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_FLT, TYPE_DBL);
+                                                       break;
+                                               case ICMD_D2I:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_DBL, TYPE_INT);
+                                                       break;
+                                               case ICMD_D2L:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_DBL, TYPE_LNG);
+                                                       break;
+                                               case ICMD_D2F:
+                                                       COUNT(count_pcmd_op);
+                                                       OP1_1(TYPE_DBL, TYPE_FLT);
+                                                       break;
+
+                                               case ICMD_CHECKCAST:
+                                                       OP1_1(TYPE_ADR, TYPE_ADR);
+                                                       break;
+
+                                               case ICMD_ARRAYLENGTH:
+                                               case ICMD_INSTANCEOF:
+                                                       OP1_1(TYPE_ADR, TYPE_INT);
+                                                       break;
+
+                                               case ICMD_NEWARRAY:
+                                               case ICMD_ANEWARRAY:
+                                                       OP1_1(TYPE_INT, TYPE_ADR);
+                                                       break;
+
+                                               case ICMD_GETFIELD:
+                                                       COUNT(count_check_null);
+                                                       COUNT(count_pcmd_mem);
+                                                       OP1_1(TYPE_ADR, iptr->op1);
+                                                       break;
+
+                                               /* pop 0 push 1 */
+                                               
+                                               case ICMD_GETSTATIC:
+                                                       COUNT(count_pcmd_mem);
+                                                       OP0_1(iptr->op1);
+                                                       break;
+
+                                               case ICMD_NEW:
+                                                       OP0_1(TYPE_ADR);
+                                                       break;
+
+                                               case ICMD_JSR:
+                                                       OP0_1(TYPE_ADR);
+                                                       tbptr = block + block_index[iptr->op1];
+                                                       tbptr->type=BBTYPE_SBR;
+                                                       MARKREACHED(tbptr, copy);
+                                                       OP1_0ANY;
+                                                       break;
+
+                                               /* pop many push any */
+                                               
+                                               case ICMD_INVOKEVIRTUAL:
+                                               case ICMD_INVOKESPECIAL:
+                                               case ICMD_INVOKEINTERFACE:
+                                               case ICMD_INVOKESTATIC:
+                                                       COUNT(count_pcmd_met);
+                                                       {
+                                                       methodinfo *m = iptr->val.a;
+                                                       if (m->flags & ACC_STATIC)
+                                                               {COUNT(count_check_null);}
+                                                       i = iptr->op1;
+                                                       if (i > arguments_num)
+                                                               arguments_num = i;
+                                                       copy = curstack;
+                                                       while (--i >= 0) {
+                                                               if (! (copy->flags & SAVEDVAR)) {
+                                                                       copy->varkind = ARGVAR;
+                                                                       copy->varnum = i;
+                                                                       }
+                                                               copy = copy->prev;
+                                                               }
+                                                       while (copy) {
+                                                               copy->flags |= SAVEDVAR;
+                                                               copy = copy->prev;
+                                                               }
+                                                       i = iptr->op1;
+                                                       POPMANY(i);
+                                                       if (m->returntype != TYPE_VOID) {
+                                                               OP0_1(m->returntype);
+                                                               }
+                                                       break;
+                                                       }
+
+                                               case ICMD_BUILTIN3:
+                                                       if (! (curstack->flags & SAVEDVAR)) {
+                                                               curstack->varkind = ARGVAR;
+                                                               curstack->varnum = 2;
+                                                               }
+                                                       OP1_0ANY;
+                                               case ICMD_BUILTIN2:
+builtin2:
+                                                       if (! (curstack->flags & SAVEDVAR)) {
+                                                               curstack->varkind = ARGVAR;
+                                                               curstack->varnum = 1;
+                                                               }
+                                                       OP1_0ANY;
+                                               case ICMD_BUILTIN1:
+                                                       if (! (curstack->flags & SAVEDVAR)) {
+                                                               curstack->varkind = ARGVAR;
+                                                               curstack->varnum = 0;
+                                                               }
+                                                       OP1_0ANY;
+                                                       copy = curstack;
+                                                       while (copy) {
+                                                               copy->flags |= SAVEDVAR;
+                                                               copy = copy->prev;
+                                                               }
+                                                       if (iptr->op1 != TYPE_VOID)
+                                                               OP0_1(iptr->op1);
+                                                       break;
+
+                                               case ICMD_MULTIANEWARRAY:
+                                                       i = iptr->op1;
+                                                       if ((i + intreg_argnum) > arguments_num)
+                                                               arguments_num = i + intreg_argnum;
+                                                       copy = curstack;
+                                                       while (--i >= 0) {
+                                                               if (! (copy->flags & SAVEDVAR)) {
+                                                                       copy->varkind = ARGVAR;
+                                                                       copy->varnum = i + intreg_argnum;
+                                                                       }
+                                                               copy = copy->prev;
+                                                               }
+                                                       while (copy) {
+                                                               copy->flags |= SAVEDVAR;
+                                                               copy = copy->prev;
+                                                               }
+                                                       i = iptr->op1;
+                                                       POPMANY(i);
+                                                       OP0_1(TYPE_ADR);
+                                                       break;
+
+                                               default:
+                                                       printf("ICMD %d at %d\n", iptr->opc, (int)(iptr-instr));
+                                                       panic("Missing ICMD code during stack analysis");
+                                               } /* switch */
+                                       iptr++;
+                                       } /* while instructions */
+                               bptr->outstack = curstack;
+                               bptr->outdepth = stackdepth;
+                               BBEND(curstack, i);
+                               } /* if */
+                       else
+                               superblockend = true;
+                       bptr++;
+               } /* while blocks */
+       } while (repeat && ! deadcode);
+
+#ifdef STATISTICS
+       if (block_count > count_max_basic_blocks)
+               count_max_basic_blocks = block_count;
+       count_basic_blocks += block_count;
+       if (instr_count > count_max_javainstr)
+               count_max_javainstr = instr_count;
+       count_javainstr += instr_count;
+       if (stack_count > count_upper_bound_new_stack)
+               count_upper_bound_new_stack = stack_count;
+       if ((new - stack) > count_max_new_stack)
+               count_max_new_stack = (new - stack);
+
+       b_count = block_count;
+       bptr = block;
+       while (--b_count >= 0) {
+               if (bptr->flags > BBREACHED) {
+                       if (bptr->indepth >= 10)
+                               count_block_stack[10]++;
+                       else
+                               count_block_stack[bptr->indepth]++;
+                       len = bptr->icount;
+                       if (len <= 10) 
+                               count_block_size_distribution[len - 1]++;
+                       else if (len <= 12)
+                               count_block_size_distribution[10]++;
+                       else if (len <= 14)
+                               count_block_size_distribution[11]++;
+                       else if (len <= 16)
+                               count_block_size_distribution[12]++;
+                       else if (len <= 18)
+                               count_block_size_distribution[13]++;
+                       else if (len <= 20)
+                               count_block_size_distribution[14]++;
+                       else if (len <= 25)
+                               count_block_size_distribution[15]++;
+                       else if (len <= 30)
+                               count_block_size_distribution[16]++;
+                       else
+                               count_block_size_distribution[17]++;
+                       }
+               bptr++;
+               }
+
+       if (loops == 1)
+               count_analyse_iterations[0]++;
+       else if (loops == 2)
+               count_analyse_iterations[1]++;
+       else if (loops == 3)
+               count_analyse_iterations[2]++;
+       else if (loops == 4)
+               count_analyse_iterations[3]++;
+       else
+               count_analyse_iterations[4]++;
+
+       if (block_count <= 5)
+               count_method_bb_distribution[0]++;
+       else if (block_count <= 10)
+               count_method_bb_distribution[1]++;
+       else if (block_count <= 15)
+               count_method_bb_distribution[2]++;
+       else if (block_count <= 20)
+               count_method_bb_distribution[3]++;
+       else if (block_count <= 30)
+               count_method_bb_distribution[4]++;
+       else if (block_count <= 40)
+               count_method_bb_distribution[5]++;
+       else if (block_count <= 50)
+               count_method_bb_distribution[6]++;
+       else if (block_count <= 75)
+               count_method_bb_distribution[7]++;
+       else
+               count_method_bb_distribution[8]++;
+#endif
+}
+
+
+static void print_stack(stackptr s) {
+       int i, j;
+       stackptr t;
+
+       i = maxstack;
+       t = s;
+       
+       while (t) {
+               i--;
+               t = t->prev;
+               }
+       j = maxstack - i;
+       while (--i >= 0)
+               printf("    ");
+       while (s) {
+               j--;
+               if (s->flags & SAVEDVAR)
+                       switch (s->varkind) {
+                               case TEMPVAR:
+                                       if (s->flags & INMEMORY)
+                                               printf(" m%02d", s->regoff);
+                                       else
+                                               printf(" r%02d", s->regoff);
+                                       break;
+                               case STACKVAR:
+                                       printf(" s%02d", s->varnum);
+                                       break;
+                               case LOCALVAR:
+                                       printf(" l%02d", s->varnum);
+                                       break;
+                               case ARGVAR:
+                                       printf(" a%02d", s->varnum);
+                                       break;
+                               default:
+                                       printf(" !%02d", j);
+                               }
+               else
+                       switch (s->varkind) {
+                               case TEMPVAR:
+                                       if (s->flags & INMEMORY)
+                                               printf(" M%02d", s->regoff);
+                                       else
+                                               printf(" R%02d", s->regoff);
+                                       break;
+                               case STACKVAR:
+                                       printf(" S%02d", s->varnum);
+                                       break;
+                               case LOCALVAR:
+                                       printf(" L%02d", s->varnum);
+                                       break;
+                               case ARGVAR:
+                                       printf(" A%02d", s->varnum);
+                                       break;
+                               default:
+                                       printf(" ?%02d", j);
+                               }
+               s = s->prev;
+               }
+}
+
+
+static void print_reg(stackptr s) {
+       if (s) {
+               if (s->flags & SAVEDVAR)
+                       switch (s->varkind) {
+                               case TEMPVAR:
+                                       if (s->flags & INMEMORY)
+                                               printf(" tm%02d", s->regoff);
+                                       else
+                                               printf(" tr%02d", s->regoff);
+                                       break;
+                               case STACKVAR:
+                                       printf(" s %02d", s->varnum);
+                                       break;
+                               case LOCALVAR:
+                                       printf(" l %02d", s->varnum);
+                                       break;
+                               case ARGVAR:
+                                       printf(" a %02d", s->varnum);
+                                       break;
+                               default:
+                                       printf(" ! %02d", s->varnum);
+                               }
+               else
+                       switch (s->varkind) {
+                               case TEMPVAR:
+                                       if (s->flags & INMEMORY)
+                                               printf(" Tm%02d", s->regoff);
+                                       else
+                                               printf(" Tr%02d", s->regoff);
+                                       break;
+                               case STACKVAR:
+                                       printf(" S %02d", s->varnum);
+                                       break;
+                               case LOCALVAR:
+                                       printf(" L %02d", s->varnum);
+                                       break;
+                               case ARGVAR:
+                                       printf(" A %02d", s->varnum);
+                                       break;
+                               default:
+                                       printf(" ? %02d", s->varnum);
+                               }
+               }
+       else
+               printf("     ");
+               
+}
+
+
+static char *builtin_name(functionptr bptr)
+{
+       builtin_descriptor *bdesc = builtin_desc;
+       while ((bdesc->bptr != NULL) && (bdesc->bptr != bptr))
+               bdesc++;
+       return bdesc->name;
+}
+
+
+static void show_icmd_method()
+{
+       int b, i, j, last;
+       int deadcode;
+       s4  *s4ptr;
+       instruction *iptr;
+       
+       printf("\n");
+       unicode_fprint(stdout, class->name);
+       printf(".");
+       unicode_fprint(stdout, method->name);
+       printf(" ");
+       unicode_fprint(stdout, method->descriptor);
+       printf ("\n\nMax locals: %d\n", (int) maxlocals);
+       printf ("Max stack:  %d\n", (int) maxstack);
+
+       printf ("Exceptions:\n");
+       for (i = 0; i < exceptiontablelength; i++) {
+               printf("    L%03d ... ", block_index[extable[i].startpc]);
+               printf("L%03d = ", block_index[extable[i].endpc]);
+               printf("L%03d\n", block_index[extable[i].handlerpc]);
+               }
+       
+       printf ("Local Table:\n");
+       for (i = 0; i < maxlocals; i++) {
+               printf("   %3d: ", i);
+               for (j = TYPE_INT; j <= TYPE_ADR; j++)
+                       if (locals[i][j].type >= 0) {
+                               printf("   (%d) ", j);
+                               if (locals[i][j].flags)
+                                       printf("m");
+                               else
+                                       printf("r");
+                               printf("%2d", locals[i][j].regoff);
+                               }
+               printf("\n");
+               }
+       printf("\n");
+
+       printf ("Interface Table:\n");
+       for (i = 0; i < maxstack; i++) {
+               if ((interfaces[i][0].type >= 0) || (interfaces[i][1].type >= 0) ||
+                   (interfaces[i][2].type >= 0) || (interfaces[i][3].type >= 0) ||
+                   (interfaces[i][4].type >= 0)) {
+                       printf("   %3d: ", i);
+                       for (j = TYPE_INT; j <= TYPE_ADR; j++)
+                               if (interfaces[i][j].type >= 0) {
+                                       printf("   (%d) ", j);
+                                       if (interfaces[i][j].flags & SAVEDVAR)
+                                               printf("s");
+                                       else
+                                               printf("t");
+                                       if (interfaces[i][j].flags & INMEMORY)
+                                               printf("m");
+                                       else
+                                               printf("r");
+                                       printf("%2d", interfaces[i][j].regoff);
+                                       }
+                       printf("\n");
+                       }
+               }
+       printf("\n");
+
+       if (showdisassemble) {
+               s4ptr = (s4 *) (method->mcode + dseglen);
+               for (i = 0; i < block[0].mpc; i += 4, s4ptr++) {
+                       disassinstr(*s4ptr, i); 
+                       }
+               printf("\n");
+               }
+
+       for (b = 0; b < block_count; b++)
+               if (block[b].flags != BBDELETED) {
+               deadcode = block[b].flags <= BBREACHED;
+               printf("[");
+               if (deadcode)
+                       for (j = maxstack; j > 0; j--)
+                               printf(" ?  ");
+               else
+                       print_stack(block[b].instack);
+               printf("] L%03d(%d):\n", b, block[b].pre_count);
+               iptr = block[b].iinstr;
+               i = iptr - instr;
+               for (last = i + block[b].icount; i < last; i++, iptr++) {
+                       printf("[");
+                       if (deadcode) {
+                               for (j = maxstack; j > 0; j--)
+                                       printf(" ?  ");
+                               }
+                       else
+                               print_stack(iptr->dst);
+                       printf("]     %4d  %s", i, icmd_names[iptr->opc]);
+                       switch ((int) iptr->opc) {
+                               case ICMD_IADDCONST:
+                               case ICMD_ISUBCONST:
+                               case ICMD_IMULCONST:
+                               case ICMD_IDIVPOW2:
+                               case ICMD_IREMPOW2:
+                               case ICMD_IREM0X10001:
+                               case ICMD_IANDCONST:
+                               case ICMD_IORCONST:
+                               case ICMD_IXORCONST:
+                               case ICMD_ISHLCONST:
+                               case ICMD_ISHRCONST:
+                               case ICMD_IUSHRCONST:
+                               case ICMD_ICONST:
+                               case ICMD_ELSE_ICONST:
+                               case ICMD_IFEQ_ICONST:
+                               case ICMD_IFNE_ICONST:
+                               case ICMD_IFLT_ICONST:
+                               case ICMD_IFGE_ICONST:
+                               case ICMD_IFGT_ICONST:
+                               case ICMD_IFLE_ICONST:
+                                       printf(" %d", iptr->val.i);
+                                       break;
+                               case ICMD_LADDCONST:
+                               case ICMD_LSUBCONST:
+                               case ICMD_LMULCONST:
+                               case ICMD_LDIVPOW2:
+                               case ICMD_LREMPOW2:
+                               case ICMD_LANDCONST:
+                               case ICMD_LORCONST:
+                               case ICMD_LXORCONST:
+                               case ICMD_LSHLCONST:
+                               case ICMD_LSHRCONST:
+                               case ICMD_LUSHRCONST:
+                               case ICMD_LCONST:
+                                       printf(" %ld", iptr->val.l);
+                                       break;
+                               case ICMD_FCONST:
+                                       printf(" %f", iptr->val.f);
+                                       break;
+                               case ICMD_DCONST:
+                                       printf(" %f", iptr->val.d);
+                                       break;
+                               case ICMD_ACONST:
+                                       printf(" %p", iptr->val.a);
+                                       break;
+                               case ICMD_GETFIELD:
+                               case ICMD_PUTFIELD:
+                                       printf(" %d,", ((fieldinfo *) iptr->val.a)->offset);
+                               case ICMD_PUTSTATIC:
+                               case ICMD_GETSTATIC:
+                                       printf(" ");
+                                       unicode_fprint(stdout,
+                                                       ((fieldinfo *) iptr->val.a)->name);
+                                       break;
+                               case ICMD_IINC:
+                                       printf(" %d + %d", iptr->op1, iptr->val.i);
+                                       break;
+                               case ICMD_RET:
+                               case ICMD_ILOAD:
+                               case ICMD_LLOAD:
+                               case ICMD_FLOAD:
+                               case ICMD_DLOAD:
+                               case ICMD_ALOAD:
+                               case ICMD_ISTORE:
+                               case ICMD_LSTORE:
+                               case ICMD_FSTORE:
+                               case ICMD_DSTORE:
+                               case ICMD_ASTORE:
+                                       printf(" %d", iptr->op1);
+                                       break;
+                               case ICMD_NEW:
+                                       printf(" ");
+                                       unicode_fprint(stdout,
+                                                      ((classinfo *) iptr->val.a)->name);
+                                       break;
+                               case ICMD_NEWARRAY:
+                                       switch (iptr->op1) {
+                                               case 4:
+                                                       printf(" boolean");
+                                                       break;
+                                               case 5:
+                                                       printf(" char");
+                                                       break;
+                                               case 6:
+                                                       printf(" float");
+                                                       break;
+                                               case 7:
+                                                       printf(" double");
+                                                       break;
+                                               case 8:
+                                                       printf(" byte");
+                                                       break;
+                                               case 9:
+                                                       printf(" short");
+                                                       break;
+                                               case 10:
+                                                       printf(" int");
+                                                       break;
+                                               case 11:
+                                                       printf(" long");
+                                                       break;
+                                               }
+                                       break;
+                               case ICMD_ANEWARRAY:
+                                       if (iptr->op1) {
+                                               printf(" ");
+                                               unicode_fprint(stdout,
+                                                              ((classinfo *) iptr->val.a)->name);
+                                               }
+                                       break;
+                               case ICMD_CHECKCAST:
+                               case ICMD_INSTANCEOF:
+                                       if (iptr->op1) {
+                                               classinfo *c = iptr->val.a;
+                                               if (c->flags & ACC_INTERFACE)
+                                                       printf(" (INTERFACE) ");
+                                               else
+                                                       printf(" (CLASS,%3d) ", c->vftbl->diffval);
+                                               unicode_fprint(stdout, c->name);
+                                               }
+                                       break;
+                               case ICMD_BUILTIN3:
+                               case ICMD_BUILTIN2:
+                               case ICMD_BUILTIN1:
+                                       printf(" %s", builtin_name((functionptr) iptr->val.a));
+                                       break;
+                               case ICMD_INVOKEVIRTUAL:
+                               case ICMD_INVOKESPECIAL:
+                               case ICMD_INVOKESTATIC:
+                               case ICMD_INVOKEINTERFACE:
+                                       printf(" ");
+                                       unicode_fprint(stdout,
+                                                      ((methodinfo *) iptr->val.a)->class->name);
+                                       printf(".");
+                                       unicode_fprint(stdout,
+                                                      ((methodinfo *) iptr->val.a)->name);
+                                       break;
+                               case ICMD_IFEQ:
+                               case ICMD_IFNE:
+                               case ICMD_IFLT:
+                               case ICMD_IFGE:
+                               case ICMD_IFGT:
+                               case ICMD_IFLE:
+                               case ICMD_IF_LEQ:
+                               case ICMD_IF_LNE:
+                               case ICMD_IF_LLT:
+                               case ICMD_IF_LGE:
+                               case ICMD_IF_LGT:
+                               case ICMD_IF_LLE:
+                                       printf("(%d) L%03d", iptr->val.i, block_index[iptr->op1]);
+                                       break;
+                               case ICMD_JSR:
+                               case ICMD_GOTO:
+                               case ICMD_IFNULL:
+                               case ICMD_IFNONNULL:
+                               case ICMD_IF_ICMPEQ:
+                               case ICMD_IF_ICMPNE:
+                               case ICMD_IF_ICMPLT:
+                               case ICMD_IF_ICMPGE:
+                               case ICMD_IF_ICMPGT:
+                               case ICMD_IF_ICMPLE:
+                               case ICMD_IF_LCMPEQ:
+                               case ICMD_IF_LCMPNE:
+                               case ICMD_IF_LCMPLT:
+                               case ICMD_IF_LCMPGE:
+                               case ICMD_IF_LCMPGT:
+                               case ICMD_IF_LCMPLE:
+                               case ICMD_IF_ACMPEQ:
+                               case ICMD_IF_ACMPNE:
+                                       printf(" L%03d", block_index[iptr->op1]);
+                                       break;
+                               case ICMD_TABLESWITCH:
+                                       s4ptr = iptr->val.a;
+                                       printf(" L%03d;", block_index[*s4ptr++]); /* default */
+                                       j = *s4ptr++;                               /* low     */
+                                       j = *s4ptr++ - j;                           /* high    */
+                                       while (j >= 0) {
+                                               printf(" L%03d", block_index[*s4ptr++]);
+                                               j--;
+                                               }
+                                       break;
+                               case ICMD_LOOKUPSWITCH:
+                                       s4ptr = iptr->val.a;
+                                       printf(" L%d", block_index[*s4ptr++]);   /* default */
+                                       j = *s4ptr++;                               /* count   */
+                                       while (--j >= 0) {
+                                               printf(" L%03d", block_index[s4ptr[1]]);
+                                               s4ptr += 2;
+                                               }
+                                       break;
+                               }
+                       printf("\n");
+                       }
+
+               if (showdisassemble && (!deadcode)) {
+                       printf("\n");
+                       i = block[b].mpc;
+                       s4ptr = (s4 *) (method->mcode + dseglen + i);
+                       for (; i < block[b + 1].mpc; i += 4, s4ptr++) {
+                               disassinstr(*s4ptr, i); 
+                               }
+                       printf("\n");
+                       }
+       }
+       i = block[b].mpc;
+       s4ptr = (s4 *) (method->mcode + dseglen + i);
+       if (showdisassemble && (s4ptr < (s4 *) (method->mcode + method->mcodelength))) {
+               printf("\n");
+               for (; s4ptr < (s4 *) (method->mcode + method->mcodelength); i += 4, s4ptr++) {
+                       disassinstr(*s4ptr, i); 
+                       }
+               printf("\n");
+               }
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
index 3927e3a7c719ea4974129d5840742e74c5e28cb1..9b58781060b1e91090a6343d6c6b9dceef55c842 100644 (file)
 #include "tables.h"
 #include "native.h"
 #include "builtin.h"
+#include "jit.h"
+#ifdef OLD_COMPILER
 #include "compiler.h"
+#endif
 #include "asmpart.h"
 
 #include "threads/thread.h"                        /* schani */
@@ -548,10 +551,14 @@ static void method_load (methodinfo *m, classinfo *c)
                functionptr f = native_findfunction 
                       (c->name, m->name, m->descriptor, (m->flags & ACC_STATIC) != 0);
                if (f) {
+#ifdef OLD_COMPILER
                if (newcompiler)
-                       m -> stubroutine = ncreatenativestub (f, m);
-               else
+#endif
                        m -> stubroutine = createnativestub (f, m);
+#ifdef OLD_COMPILER
+               else
+                       m -> stubroutine = oldcreatenativestub (f, m);
+#endif
                        }
                }