fixed builtin problem on alpha
[cacao.git] / src / vm / jit / jit.c
index be29f17e9ce4b8a3f8a916c03de734a0f3db264a..95bb7790a593b3684a0410718a13996e04ae907e 100644 (file)
@@ -27,7 +27,9 @@
    Authors: Andreas Krall
             Reinhard Grafl
 
-   $Id: jit.c 624 2003-11-13 14:06:52Z twisti $
+   Changes: Edwin Steiner
+
+   $Id: jit.c 789 2003-12-16 14:46:55Z edwin $
 
 */
 
 
 
 /* global switches ************************************************************/
-bool compileverbose =  false;
-bool showstack = false;
-bool showdisassemble = false; 
-bool showddatasegment = false; 
-bool showintermediate = false;
-int  optimizelevel = 0;
-
-bool useinlining = false;
-bool inlinevirtuals = false;
-bool inlineexceptions = false;
-bool inlineparamopt = false;
-bool inlineoutsiders = false;
-
-bool checkbounds = true;
-bool checknull = true;
-bool opt_noieee = false;
-bool checksync = true;
-bool opt_loops = false;
 
 bool getcompilingtime = false;
 long compilingtime = 0;
@@ -195,12 +179,21 @@ bool isleafmethod;              /* true if a method doesn't call subroutines  */
 
 basicblock *last_block;         /* points to the end of the BB list           */
 
+bool regs_ok;                   /* true if registers have been allocated      */
+
 /* list of all classes used by the compiled method which have to be           */
 /* initialised (if not already done) before execution of this method          */
 chain *uninitializedclasses;
 
 int stackreq[256];
+
                                 
+#if defined(__I386__)
+/* these define if a method has ICMDs which use %edx or %ecx */
+bool method_uses_ecx;
+bool method_uses_edx;
+#endif
+
 
 int jcommandsize[256] = {
 
@@ -1260,6 +1253,7 @@ char *opcode_names[256] = {
 
 #if defined(USEBUILTINTABLE)
 
+#if 0
 stdopdescriptor builtintable[] = {
        { ICMD_LCMP,   TYPE_LONG, TYPE_LONG, TYPE_INT, ICMD_BUILTIN2,
          (functionptr) builtin_lcmp , SUPPORT_LONG && SUPPORT_LONG_CMP, false },
@@ -1283,10 +1277,6 @@ stdopdescriptor builtintable[] = {
          (functionptr) builtin_lneg, SUPPORT_LONG && SUPPORT_LONG_ADD, true },
        { ICMD_LMUL,   TYPE_LONG, TYPE_LONG, TYPE_LONG, ICMD_BUILTIN2,
          (functionptr) builtin_lmul , SUPPORT_LONG && SUPPORT_LONG_MUL, false },
-       { ICMD_FREM,   TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, ICMD_BUILTIN2,
-         (functionptr) builtin_frem, SUPPORT_FLOAT && SUPPORT_FMOD, true },
-       { ICMD_DREM,   TYPE_DOUBLE, TYPE_DOUBLE, TYPE_DOUBLE, ICMD_BUILTIN2,
-         (functionptr) builtin_drem, SUPPORT_DOUBLE && SUPPORT_FMOD, true },
        { ICMD_I2F,    TYPE_INT, TYPE_VOID, TYPE_FLOAT, ICMD_BUILTIN1,
          (functionptr) builtin_i2f, SUPPORT_FLOAT && SUPPORT_IFCVT, true },
        { ICMD_I2D,    TYPE_INT, TYPE_VOID, TYPE_DOUBLE, ICMD_BUILTIN1, 
@@ -1296,19 +1286,126 @@ stdopdescriptor builtintable[] = {
        { ICMD_L2D,    TYPE_LONG, TYPE_VOID, TYPE_DOUBLE, ICMD_BUILTIN1, 
          (functionptr) builtin_l2d, SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_LONG_FCVT, true },
        { ICMD_F2L,    TYPE_FLOAT, TYPE_VOID, TYPE_LONG, ICMD_BUILTIN1,
-         (functionptr) builtin_f2l, SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_LONG_FCVT, true },
+         (functionptr) builtin_f2l, SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_LONG_ICVT, true },
        { ICMD_D2L,    TYPE_DOUBLE, TYPE_VOID, TYPE_LONG, ICMD_BUILTIN1,
-         (functionptr) builtin_d2l, SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_LONG_FCVT, true },
+         (functionptr) builtin_d2l, SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_LONG_ICVT, true },
        { ICMD_F2I,    TYPE_FLOAT, TYPE_VOID, TYPE_INT, ICMD_BUILTIN1,
          (functionptr) builtin_f2i, SUPPORT_FLOAT && SUPPORT_FICVT, true },
        { ICMD_D2I,    TYPE_DOUBLE, TYPE_VOID, TYPE_INT, ICMD_BUILTIN1,
          (functionptr) builtin_d2i, SUPPORT_DOUBLE && SUPPORT_FICVT, true },
-/*     { 0, 0, 0, 0, 0, NULL, false, false }, */
+       { 255, 0, 0, 0, 0, NULL, true, false },
 };
 
+#endif
+
+static int builtintablelen;
+
 #endif /* USEBUILTINTABLE */
 
 
+/*****************************************************************************
+                                                TABLE OF BUILTIN FUNCTIONS
+
+    This table lists the builtin functions which are used inside
+    BUILTIN* opcodes.
+
+    The first part of the table (up to the 255-marker) lists the
+    opcodes which are automatically replaced in stack.c.
+
+    The second part lists the builtin functions which are "manually"
+    used for BUILTIN* opcodes in parse.c and stack.c.
+
+*****************************************************************************/
+
+builtin_descriptor builtin_desc[] = {
+#if defined(USEBUILTINTABLE)
+       {ICMD_LCMP , BUILTIN_lcmp ,ICMD_BUILTIN2,TYPE_LONG  ,TYPE_LONG  ,TYPE_VOID ,TYPE_INT   ,
+                    SUPPORT_LONG && SUPPORT_LONG_CMP,false,"lcmp"},
+       
+       {ICMD_LAND , BUILTIN_land ,ICMD_BUILTIN2,TYPE_LONG  ,TYPE_LONG  ,TYPE_VOID ,TYPE_LONG  ,
+                    SUPPORT_LONG && SUPPORT_LONG_LOG,false,"land"},
+       {ICMD_LOR  , BUILTIN_lor  ,ICMD_BUILTIN2,TYPE_LONG  ,TYPE_LONG  ,TYPE_VOID ,TYPE_LONG  ,
+                    SUPPORT_LONG && SUPPORT_LONG_LOG,false,"lor"},
+       {ICMD_LXOR , BUILTIN_lxor ,ICMD_BUILTIN2,TYPE_LONG  ,TYPE_LONG  ,TYPE_VOID ,TYPE_LONG  ,
+                    SUPPORT_LONG && SUPPORT_LONG_LOG,false,"lxor"},
+       
+       {ICMD_LSHL , BUILTIN_lshl ,ICMD_BUILTIN2,TYPE_LONG  ,TYPE_INT   ,TYPE_VOID ,TYPE_LONG  ,
+                    SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lshl"},
+       {ICMD_LSHR , BUILTIN_lshr ,ICMD_BUILTIN2,TYPE_LONG  ,TYPE_INT   ,TYPE_VOID ,TYPE_LONG  ,
+                    SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lshr"},
+       {ICMD_LUSHR, BUILTIN_lushr,ICMD_BUILTIN2,TYPE_LONG  ,TYPE_INT   ,TYPE_VOID ,TYPE_LONG  ,
+                    SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lushr"},
+       
+       {ICMD_LADD , BUILTIN_ladd ,ICMD_BUILTIN2,TYPE_LONG  ,TYPE_LONG  ,TYPE_VOID ,TYPE_LONG  ,
+                    SUPPORT_LONG && SUPPORT_LONG_ADD,false,"ladd"},
+       {ICMD_LSUB , BUILTIN_lsub ,ICMD_BUILTIN2,TYPE_LONG  ,TYPE_LONG  ,TYPE_VOID ,TYPE_LONG  ,
+                    SUPPORT_LONG && SUPPORT_LONG_ADD,false,"lsub"},
+       {ICMD_LNEG , BUILTIN_lneg ,ICMD_BUILTIN1,TYPE_LONG  ,TYPE_VOID  ,TYPE_VOID ,TYPE_LONG  ,
+                    SUPPORT_LONG && SUPPORT_LONG_ADD,false,"lneg"},
+       {ICMD_LMUL , BUILTIN_lmul ,ICMD_BUILTIN2,TYPE_LONG  ,TYPE_LONG  ,TYPE_VOID ,TYPE_LONG  ,
+                    SUPPORT_LONG && SUPPORT_LONG_MUL,false,"lmul"},
+       
+       {ICMD_I2F  , BUILTIN_i2f  ,ICMD_BUILTIN1,TYPE_INT   ,TYPE_VOID  ,TYPE_VOID ,TYPE_FLOAT ,
+                    SUPPORT_FLOAT && SUPPORT_IFCVT,true ,"i2f"},
+       {ICMD_I2D  , BUILTIN_i2d  ,ICMD_BUILTIN1,TYPE_INT   ,TYPE_VOID  ,TYPE_VOID ,TYPE_DOUBLE,
+                    SUPPORT_DOUBLE && SUPPORT_IFCVT,true ,"i2d"},
+       {ICMD_L2F  , BUILTIN_l2f  ,ICMD_BUILTIN1,TYPE_LONG  ,TYPE_VOID  ,TYPE_VOID ,TYPE_FLOAT ,
+                    SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_LONG_FCVT,true ,"l2f"},
+       {ICMD_L2D  , BUILTIN_l2d  ,ICMD_BUILTIN1,TYPE_LONG  ,TYPE_VOID  ,TYPE_VOID ,TYPE_DOUBLE,
+                    SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_LONG_FCVT,true ,"l2d"},
+       {ICMD_F2L  , BUILTIN_f2l  ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID  ,TYPE_VOID ,TYPE_LONG  ,
+                    SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_LONG_ICVT,true ,"f2l"},
+       {ICMD_D2L  , BUILTIN_d2l  ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID  ,TYPE_VOID ,TYPE_LONG  ,
+                    SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_LONG_ICVT,true ,"d2l"},
+       {ICMD_F2I  , BUILTIN_f2i  ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID  ,TYPE_VOID ,TYPE_INT   ,
+                    SUPPORT_FLOAT && SUPPORT_FICVT,true ,"f2i"},
+       {ICMD_D2I  , BUILTIN_d2i  ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID  ,TYPE_VOID ,TYPE_INT   ,
+                    SUPPORT_DOUBLE && SUPPORT_FICVT,true ,"d2i"},
+#endif
+
+       /* this record marks the end of the automatically replaced opcodes */
+       {255       , NULL        ,0            ,0          ,0          ,0         ,0          ,
+                    true                            ,false,"<INVALID>"},
+
+#if defined(__ALPHA__)
+       {255, BUILTIN_f2l  ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID  ,TYPE_VOID ,TYPE_LONG  ,0,0,"f2l"},
+       {255, BUILTIN_d2l  ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID  ,TYPE_VOID ,TYPE_LONG  ,0,0,"d2l"},
+       {255, BUILTIN_f2i  ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID  ,TYPE_VOID ,TYPE_INT   ,0,0,"f2i"},
+       {255, BUILTIN_d2i  ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID  ,TYPE_VOID ,TYPE_INT   ,0,0,"d2i"},
+#endif
+
+       /* the following functions are not replaced automatically */
+       {255,BUILTIN_instanceof      ,ICMD_BUILTIN2,TYPE_ADR   ,TYPE_ADR   ,TYPE_VOID  ,TYPE_INT   ,0,0,"instanceof"},
+       {255,BUILTIN_arrayinstanceof ,ICMD_BUILTIN2,TYPE_ADR   ,TYPE_ADR   ,TYPE_VOID  ,TYPE_INT   ,0,0,"arrayinstanceof"},
+       {255,BUILTIN_checkarraycast  ,ICMD_BUILTIN2,TYPE_ADR   ,TYPE_ADR   ,TYPE_VOID  ,TYPE_VOID  ,0,0,"checkarraycast"},
+       {255,BUILTIN_aastore         ,ICMD_BUILTIN3,TYPE_ADR   ,TYPE_INT   ,TYPE_ADR   ,TYPE_VOID  ,0,0,"aastore"},
+       {255,BUILTIN_new             ,ICMD_BUILTIN1,TYPE_ADR   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"new"},
+       {255,BUILTIN_newarray        ,ICMD_BUILTIN1,TYPE_ADR   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray"},
+       {255,BUILTIN_newarray_boolean,ICMD_BUILTIN1,TYPE_INT   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray_boolean"},
+       {255,BUILTIN_newarray_char   ,ICMD_BUILTIN1,TYPE_INT   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray_char"},
+       {255,BUILTIN_newarray_float  ,ICMD_BUILTIN1,TYPE_INT   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray_float"},
+       {255,BUILTIN_newarray_double ,ICMD_BUILTIN1,TYPE_INT   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray_double"},
+       {255,BUILTIN_newarray_byte   ,ICMD_BUILTIN1,TYPE_INT   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray_byte"},
+       {255,BUILTIN_newarray_short  ,ICMD_BUILTIN1,TYPE_INT   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray_short"},
+       {255,BUILTIN_newarray_int    ,ICMD_BUILTIN1,TYPE_INT   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray_int"},
+       {255,BUILTIN_newarray_long   ,ICMD_BUILTIN1,TYPE_INT   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray_long"},
+       {255,BUILTIN_monitorenter    ,ICMD_BUILTIN1,TYPE_ADR   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_VOID  ,0,0,"monitorenter"},
+       {255,BUILTIN_monitorexit     ,ICMD_BUILTIN1,TYPE_ADR   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_VOID  ,0,0,"monitorexit"},
+#if !SUPPORT_DIVISION
+       {255,BUILTIN_idiv            ,ICMD_BUILTIN2,TYPE_INT   ,TYPE_INT   ,TYPE_VOID  ,TYPE_INT   ,0,0,"idiv"},
+       {255,BUILTIN_irem            ,ICMD_BUILTIN2,TYPE_INT   ,TYPE_INT   ,TYPE_VOID  ,TYPE_INT   ,0,0,"irem"},
+#endif
+#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
+       {255,BUILTIN_ldiv            ,ICMD_BUILTIN2,TYPE_LONG  ,TYPE_LONG  ,TYPE_VOID  ,TYPE_LONG  ,0,0,"ldiv"},
+       {255,BUILTIN_lrem            ,ICMD_BUILTIN2,TYPE_LONG  ,TYPE_LONG  ,TYPE_VOID  ,TYPE_LONG  ,0,0,"lrem"},
+#endif
+       {255,BUILTIN_frem            ,ICMD_BUILTIN2,TYPE_FLOAT ,TYPE_FLOAT ,TYPE_VOID  ,TYPE_FLOAT ,0,0,"frem"},
+       {255,BUILTIN_drem            ,ICMD_BUILTIN2,TYPE_DOUBLE,TYPE_DOUBLE,TYPE_VOID  ,TYPE_DOUBLE,0,0,"drem"},
+
+       /* this record marks the end of the list */
+       {  0,NULL,0,0,0,0,0,0,0,"<END>"}
+};
+
 /* include compiler subsystems ************************************************/
 
 /* from codegen.inc */
@@ -1344,8 +1441,13 @@ methodptr jit_compile(methodinfo *m)
 
        count_methods++;
 
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       pthread_mutex_lock(&compiler_mutex);
+#endif
+
        intsDisable();      /* disable interrupts */
-       
+
+       regs_ok = false;
 
        /* mark start of dump memory area */
 
@@ -1359,12 +1461,13 @@ methodptr jit_compile(methodinfo *m)
        /* if there is no javacode print error message and return empty method    */
 
        if (!m->jcode) {
+               char logtext[MAXLOGTEXT];
                sprintf(logtext, "No code given for: ");
                utf_sprint(logtext+strlen(logtext), m->class->name);
                strcpy(logtext+strlen(logtext), ".");
                utf_sprint(logtext+strlen(logtext), m->name);
                utf_sprint(logtext+strlen(logtext), m->descriptor);
-               dolog();
+               log_text(logtext);
                intsRestore();                             /* enable interrupts again */
                return (methodptr) do_nothing_function;    /* return empty method     */
        }
@@ -1372,12 +1475,13 @@ methodptr jit_compile(methodinfo *m)
        /* print log message for compiled method */
 
        if (compileverbose) {
+               char logtext[MAXLOGTEXT];
                sprintf(logtext, "Compiling: ");
                utf_sprint(logtext+strlen(logtext), m->class->name);
                strcpy(logtext+strlen(logtext), ".");
                utf_sprint(logtext+strlen(logtext), m->name);
                utf_sprint(logtext+strlen(logtext), m->descriptor);
-               dolog();
+               log_text(logtext);
        }
 
 
@@ -1410,23 +1514,48 @@ methodptr jit_compile(methodinfo *m)
 
        /* initialize class list with class the compiled method belongs to */
 
-       uninitializedclasses = chain_new(); 
+       uninitializedclasses = chain_new();
        compiler_addinitclass(m->class);
 
 
+#if defined(__I386__)
+       method_uses_ecx = true;
+       method_uses_edx = false;
+#endif
+
        /* call the compiler passes ***********************************************/
 
-       /* must be call before reg_init, because it can change maxlocals */
+       /* must be called before reg_init, because it can change maxlocals */
        if (useinlining)
                inlining_init(m);
 
-       reg_init(m);
+       reg_setup();
 
        codegen_init();
 
        parse();
        analyse_stack();
    
+#ifdef CACAO_TYPECHECK
+       /* print log message for compiled method */
+
+       if (compileverbose) {
+               char logtext[MAXLOGTEXT];
+               sprintf(logtext, "Typechecking: ");
+               utf_sprint(logtext+strlen(logtext), m->class->name);
+               strcpy(logtext+strlen(logtext), ".");
+               utf_sprint(logtext+strlen(logtext), m->name);
+               utf_sprint(logtext+strlen(logtext), m->descriptor);
+               log_text(logtext);
+       }
+
+       typecheck();
+       
+       if (compileverbose) {
+               dolog("Typechecking done.");
+       }
+#endif
+       
        if (opt_loops) {
                depthFirst();
                analyseGraph();
@@ -1438,6 +1567,7 @@ methodptr jit_compile(methodinfo *m)
 #endif
 
        regalloc();
+       regs_ok = true;
        codegen();
 
        /* intermediate and assembly code listings ********************************/
@@ -1458,7 +1588,7 @@ methodptr jit_compile(methodinfo *m)
 
        if (getcompilingtime) {
                stoptime = getcputime();
-               compilingtime += (stoptime-starttime); 
+               compilingtime += (stoptime - starttime);
        }
 
        /* initialize all used classes */
@@ -1477,6 +1607,10 @@ methodptr jit_compile(methodinfo *m)
 
        intsRestore();    /* enable interrupts again */
 
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       pthread_mutex_unlock(&compiler_mutex);
+#endif
+
        /* return pointer to the methods entry point */
        
        return m->entrypoint;
@@ -1488,30 +1622,79 @@ methodptr jit_compile(methodinfo *m)
 
 #ifdef USEBUILTINTABLE
 
+/* XXX delete */
+#if 0
 static int stdopcompare(const void *a, const void *b)
 {
        stdopdescriptor *o1 = (stdopdescriptor *) a;
        stdopdescriptor *o2 = (stdopdescriptor *) b;
+       if (!o1->supported && o2->supported)
+               return -1;
+       if (o1->supported && !o2->supported)
+               return 1;
+       return (o1->opcode < o2->opcode) ? -1 : (o1->opcode > o2->opcode);
+}
+#endif
+static int stdopcompare(const void *a, const void *b)
+{
+       builtin_descriptor *o1 = (builtin_descriptor *) a;
+       builtin_descriptor *o2 = (builtin_descriptor *) b;
+       if (!o1->supported && o2->supported)
+               return -1;
+       if (o1->supported && !o2->supported)
+               return 1;
        return (o1->opcode < o2->opcode) ? -1 : (o1->opcode > o2->opcode);
 }
 
-
+/* XXX delete */
+#if 0
 static inline void sort_builtintable()
 {
        int len;
 
        len = sizeof(builtintable) / sizeof(stdopdescriptor);
-       qsort(builtintable, len, sizeof(stdopdescriptor), stdopcompare);
+       qsort(builtintable, len, sizeof(builtin_descriptor), stdopcompare);
+
+       for (--len; len>=0 && builtintable[len].supported; len--);
+       builtintablelen = ++len;
+
+#if 0
+       {
+               int i;
+               for (i=0; i<len; i++)
+                       if (!builtintable[i].supported)
+                               printf("%s\n", icmd_names[builtintable[i].opcode]);
+       }
+#endif
+}
+#endif
+
+static inline void sort_builtintable()
+{
+       int len;
+
+       len = 0;
+       while (builtin_desc[len].opcode != 255) len++;
+       qsort(builtin_desc, len, sizeof(builtin_descriptor), stdopcompare);
+
+       for (--len; len>=0 && builtin_desc[len].supported; len--);
+       builtintablelen = ++len;
 }
 
 
+#if 0
 stdopdescriptor *find_builtin(int icmd)
 {
-       stdopdescriptor *first = builtintable;
-       stdopdescriptor *last = builtintable + sizeof(builtintable) / sizeof(stdopdescriptor);
+       builtin_descriptor *first = builtintable;
+       builtin_descriptor *last = builtintable + builtintablelen;
+#endif
+builtin_descriptor *find_builtin(int icmd)
+{
+       builtin_descriptor *first = builtin_desc;
+       builtin_descriptor *last = builtin_desc + builtintablelen;
        int len = last - first;
        int half;
-       stdopdescriptor *middle;
+       builtin_descriptor *middle;
 
        while (len > 0) {
                half = len / 2;
@@ -1522,7 +1705,7 @@ stdopdescriptor *find_builtin(int icmd)
                } else
                        len = half;
        }
-       return first;
+       return first != last ? first : NULL;
 }
 
 #endif
@@ -1621,7 +1804,8 @@ void jit_init()
        stackreq[JAVA_DUP_X2] = 4;
        stackreq[JAVA_DUP2_X1] = 3;
        stackreq[JAVA_DUP2_X2] = 4;
-       
+
+       reg_init();
        init_exceptions();
 }