* src/vm/jit/codegen-common.c (codegen_generate_stub_builtin): Set
authorChristian Thalinger <twisti@complang.tuwien.ac.at>
Mon, 10 Sep 2007 22:33:39 +0000 (00:33 +0200)
committerChristian Thalinger <twisti@complang.tuwien.ac.at>
Mon, 10 Sep 2007 22:33:39 +0000 (00:33 +0200)
skipparams and pass it to codegen_emit_stub_native.
(codegen_generate_stub_native): Likewise.
* src/vm/jit/codegen-common.h (codegen_emit_stub_native): Changed
signature.

* src/vm/jit/i386/codegen.c (codegen_emit): ICMD_BUILTIN: Removed
emit_exception_check.
(codegen_emit_stub_builtin): Removed.
(codegen_emit_stub_native): Changed signature.
* src/vm/jit/x86_64/codegen.c: Likewise.

--HG--
branch : michi

src/vm/jit/codegen-common.c
src/vm/jit/codegen-common.h
src/vm/jit/i386/codegen.c
src/vm/jit/x86_64/codegen.c

index 8a04bea20ebb5691c4520b1dea3534b9a95a5feb..a74df99477c65240100a532b7bbe8ab5ea70bb80 100644 (file)
@@ -1201,6 +1201,7 @@ void codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte)
 #if defined(__ARM__) || defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__SPARC64__) || defined(__X86_64__)
        jitdata  *jd;
        codeinfo *code;
+       int       skipparams;
        s4        dumpsize;
 
        /* mark dump memory */
@@ -1216,7 +1217,7 @@ void codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte)
 
        /* Allocate codeinfo memory from the heap as we need to keep them. */
 
-       jd->code  = code_codeinfo_new(m); /* XXX check allocation */
+       jd->code  = code_codeinfo_new(m);
 
        /* get required compiler data */
 
@@ -1226,6 +1227,10 @@ void codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte)
 
        codegen_setup(jd);
 
+       /* Set the number of native arguments we need to skip. */
+
+       skipparams = 0;
+
        /* generate the code */
 
 #if defined(ENABLE_JIT)
@@ -1233,7 +1238,7 @@ void codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte)
        if (!opt_intrp) {
 # endif
                assert(bte->fp != NULL);
-               codegen_emit_stub_native(jd, bte->md, bte->fp);
+               codegen_emit_stub_native(jd, bte->md, bte->fp, skipparams);
 # if defined(ENABLE_INTRP)
        }
 # endif
@@ -1290,7 +1295,7 @@ codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
        s4           dumpsize;
        methoddesc  *md;
        methoddesc  *nmd;       
-       s4           nativeparams;
+       int          skipparams;
 
        /* mark dump memory */
 
@@ -1305,7 +1310,7 @@ codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
 
        /* Allocate codeinfo memory from the heap as we need to keep them. */
 
-       jd->code  = code_codeinfo_new(m); /* XXX check allocation */
+       jd->code  = code_codeinfo_new(m);
 
        /* get required compiler data */
 
@@ -1335,13 +1340,19 @@ codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
        /* create new method descriptor with additional native parameters */
 
        md = m->parseddesc;
-       nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
+
+       /* Set the number of native arguments we need to skip. */
+
+       if (m->flags & ACC_STATIC)
+               skipparams = 2;
+       else
+               skipparams = 1;
        
        nmd = (methoddesc *) DMNEW(u1, sizeof(methoddesc) - sizeof(typedesc) +
                                                           md->paramcount * sizeof(typedesc) +
-                                                          nativeparams * sizeof(typedesc));
+                                                          skipparams * sizeof(typedesc));
 
-       nmd->paramcount = md->paramcount + nativeparams;
+       nmd->paramcount = md->paramcount + skipparams;
 
        nmd->params = DMNEW(paramdesc, nmd->paramcount);
 
@@ -1350,7 +1361,7 @@ codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
        if (m->flags & ACC_STATIC)
                nmd->paramtypes[1].type = TYPE_ADR; /* add class pointer              */
 
-       MCOPY(nmd->paramtypes + nativeparams, md->paramtypes, typedesc,
+       MCOPY(nmd->paramtypes + skipparams, md->paramtypes, typedesc,
                  md->paramcount);
 
 #if defined(ENABLE_JIT)
@@ -1370,7 +1381,7 @@ codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
                intrp_createnativestub(f, jd, nmd);
        else
 # endif
-               codegen_emit_stub_native(jd, nmd, f);
+               codegen_emit_stub_native(jd, nmd, f, skipparams);
 #else
        intrp_createnativestub(f, jd, nmd);
 #endif
@@ -1492,7 +1503,7 @@ java_handle_t *codegen_start_native_call(u1 *currentsp, u1 *pv)
        code      = *((codeinfo **) (pv + CodeinfoPointer));
        framesize = *((int32_t *)   (pv + FrameSize));
        assert(code);
-       assert(framesize > sizeof(stackframeinfo) + sizeof(localref_table));
+       assert(framesize >= sizeof(stackframeinfo) + sizeof(localref_table));
 
        /* get the methodinfo */
 
index fdae052bce9eb57f8618b8e8fe21128a22e40385..c545e151e8ff78bd1f269585258a35acfc85ddeb 100644 (file)
@@ -314,7 +314,7 @@ void      codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte);
 codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f);
 
 void      codegen_emit_stub_compiler(jitdata *jd);
-void      codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f);
+void      codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams);
 
 #if defined(ENABLE_INTRP)
 u1 *intrp_createcompilerstub(methodinfo *m);
index adfd947375c9dc240ff5790bb48092ea1831c18b..d90b981ae2040d57f3bf05e6fc5812826663262e 100644 (file)
@@ -2960,12 +2960,11 @@ gen_method:
 
                                if (bte->stub == NULL) {
                                        M_MOV_IMM(bte->fp, REG_ITMP1);
-                               } else {
+                               }
+                               else {
                                        M_MOV_IMM(bte->stub, REG_ITMP1);
                                }
                                M_CALL(REG_ITMP1);
-
-                               emit_exception_check(cd, iptr);
                                break;
 
                        case ICMD_INVOKESPECIAL:
@@ -3476,6 +3475,7 @@ gen_method:
        return true;
 }
 
+
 /* codegen_emit_stub_compiler **************************************************
 
    Emit a stub routine which calls the compiler.
@@ -3500,186 +3500,24 @@ void codegen_emit_stub_compiler(jitdata *jd)
 }
 
 
-/* codegen_emit_stub_builtin ***************************************************
-
-   Creates a stub routine which calls a builtin function.
-
-*******************************************************************************/
-
-void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
-{
-       codeinfo    *code;
-       codegendata *cd;
-       methoddesc  *md;
-       s4           i;
-       s4           disp;
-       s4           s1, s2;
-
-       /* get required compiler data */
-
-       code = jd->code;
-       cd   = jd->cd;
-
-       /* set some variables */
-
-       md = bte->md;
-
-       /* calculate stack frame size */
-
-       cd->stackframesize =
-               sizeof(stackframeinfo) / SIZEOF_VOID_P +
-               4;                              /* 4 arguments or return value        */
-
-       cd->stackframesize |= 0x3;          /* keep stack 16-byte aligned         */
-
-       /* create method header */
-
-       (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
-       (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
-       (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
-       (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
-       (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
-       (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
-       (void) dseg_addlinenumbertablesize(cd);
-       (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
-
-       /* generate stub code */
-
-       M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
-
-#if defined(ENABLE_GC_CACAO)
-       /* Save callee saved integer registers in stackframeinfo (GC may
-          need to recover them during a collection). */
-
-       disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
-               OFFSET(stackframeinfo, intregs);
-
-       for (i = 0; i < INT_SAV_CNT; i++)
-               M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
-#endif
-
-       /* create dynamic stack info */
-
-       M_MOV(REG_SP, REG_ITMP1);
-       M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
-       M_AST(REG_ITMP1, REG_SP, 0 * 4);
-
-       M_IST_IMM(0, REG_SP, 1 * 4);
-       dseg_adddata(cd);
-
-       M_MOV(REG_SP, REG_ITMP2);
-       M_AADD_IMM(cd->stackframesize * 4 + SIZEOF_VOID_P, REG_ITMP2);
-       M_AST(REG_ITMP2, REG_SP, 2 * 4);
-
-       M_ALD(REG_ITMP3, REG_SP, cd->stackframesize * 4);
-       M_AST(REG_ITMP3, REG_SP, 3 * 4);
-
-       M_MOV_IMM(codegen_stub_builtin_enter, REG_ITMP1);
-       M_CALL(REG_ITMP1);
-
-       /* copy arguments into new stackframe */
-
-       for (i = 0; i < md->paramcount; i++) {
-               if (!md->params[i].inmemory) {
-                       log_text("No integer argument registers available!");
-                       assert(0);
-
-               } else {       /* float/double in memory can be copied like int/longs */
-                       s1 = md->params[i].regoff + cd->stackframesize * 4 + 4;
-                       s2 = md->params[i].regoff;
-
-                       M_ILD(REG_ITMP1, REG_SP, s1);
-                       M_IST(REG_ITMP1, REG_SP, s2);
-                       if (IS_2_WORD_TYPE(md->paramtypes[i].type)) {
-                               M_ILD(REG_ITMP1, REG_SP, s1 + 4);
-                               M_IST(REG_ITMP1, REG_SP, s2 + 4);
-                       }
-
-               }
-       }
-
-       /* call the builtin function */
-
-       M_MOV_IMM(bte->fp, REG_ITMP3);
-       M_CALL(REG_ITMP3);
-
-       /* save return value */
-
-       if (md->returntype.type != TYPE_VOID) {
-               if (IS_INT_LNG_TYPE(md->returntype.type)) {
-                       if (IS_2_WORD_TYPE(md->returntype.type))
-                               M_IST(REG_RESULT2, REG_SP, 2 * 4);
-                       M_IST(REG_RESULT, REG_SP, 1 * 4);
-               }
-               else {
-                       if (IS_2_WORD_TYPE(md->returntype.type))
-                               emit_fstl_membase(cd, REG_SP, 1 * 4);
-                       else
-                               emit_fsts_membase(cd, REG_SP, 1 * 4);
-               }
-       }
-
-       /* remove native stackframe info */
-
-       M_MOV(REG_SP, REG_ITMP1);
-       M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
-       M_AST(REG_ITMP1, REG_SP, 0 * 4);
-
-       M_MOV_IMM(codegen_stub_builtin_exit, REG_ITMP1);
-       M_CALL(REG_ITMP1);
-
-       /* restore return value */
-
-       if (md->returntype.type != TYPE_VOID) {
-               if (IS_INT_LNG_TYPE(md->returntype.type)) {
-                       if (IS_2_WORD_TYPE(md->returntype.type))
-                               M_ILD(REG_RESULT2, REG_SP, 2 * 4);
-                       M_ILD(REG_RESULT, REG_SP, 1 * 4);
-               }
-               else {
-                       if (IS_2_WORD_TYPE(md->returntype.type))
-                               emit_fldl_membase(cd, REG_SP, 1 * 4);
-                       else
-                               emit_flds_membase(cd, REG_SP, 1 * 4);
-               }
-       }
-
-#if defined(ENABLE_GC_CACAO)
-       /* Restore callee saved integer registers from stackframeinfo (GC
-          might have modified them during a collection). */
-        
-       disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
-               OFFSET(stackframeinfo, intregs);
-
-       for (i = 0; i < INT_SAV_CNT; i++)
-               M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
-#endif
-
-       /* remove stackframe */
-
-       M_AADD_IMM(cd->stackframesize * 4, REG_SP);
-       M_RET;
-}
-
-
 /* codegen_emit_stub_native ****************************************************
 
    Emits a stub routine which calls a native method.
 
 *******************************************************************************/
 
-void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
+void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
 {
        methodinfo  *m;
        codeinfo    *code;
        codegendata *cd;
        methoddesc  *md;
-       s4           nativeparams;
-       s4           i, j;                 /* count variables                    */
-       s4           t;
-       s4           s1, s2;
-       s4           disp;
-       s4           funcdisp;
+       int          i, j;                 /* count variables                    */
+       int          s1, s2;
+       int          funcdisp;
+#if defined(ENABLE_GC_CACAO)
+       int          disp;
+#endif
 
        /* get required compiler data */
 
@@ -3690,14 +3528,12 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
        /* set some variables */
 
        md = m->parseddesc;
-       nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
 
        /* calculate stackframe size */
 
        cd->stackframesize =
                sizeof(stackframeinfo) / SIZEOF_VOID_P +
                sizeof(localref_table) / SIZEOF_VOID_P +
-               1 +                             /* function pointer                   */
                4 +                             /* 4 arguments (start_native_call)    */
                nmd->memuse;
 
@@ -3731,10 +3567,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
 
-#if !defined(NDEBUG)
-       emit_verbosecall_enter(jd);
-#endif
-
        /* get function address (this must happen before the stackframeinfo) */
 
        funcdisp = dseg_add_functionptr(cd, f);
@@ -3778,46 +3610,53 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
        /* remember class argument */
 
        if (m->flags & ACC_STATIC)
-               M_MOV(REG_RESULT, REG_ITMP2);
+               M_MOV(REG_RESULT, REG_ITMP3);
 
-       /* copy arguments into new stackframe */
+       /* Copy or spill arguments to new locations. */
 
-       for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
-               t = md->paramtypes[i].type;
+       for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
+               if (!md->params[i].inmemory)
+                       assert(0);
 
-               if (!md->params[i].inmemory) {
-                       /* no integer argument registers */
-               }
-               else {
-                       /* float/double in memory can be copied like int/longs */
+               s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
+               s2 = nmd->params[j].regoff;
 
-                       s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
-                       s2 = nmd->params[j].regoff;
+               /* float/double in memory can be copied like int/longs */
 
+               switch (md->paramtypes[i].type) {
+               case TYPE_INT:
+               case TYPE_FLT:
+               case TYPE_ADR:
                        M_ILD(REG_ITMP1, REG_SP, s1);
                        M_IST(REG_ITMP1, REG_SP, s2);
-                       if (IS_2_WORD_TYPE(t)) {
-                               M_ILD(REG_ITMP1, REG_SP, s1 + 4);
-                               M_IST(REG_ITMP1, REG_SP, s2 + 4);
-                       }
+                       break;
+               case TYPE_LNG:
+               case TYPE_DBL:
+                       M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
+                       M_LST(REG_ITMP12_PACKED, REG_SP, s2);
+                       break;
                }
        }
 
-       /* if function is static, put class into second argument */
+       /* Handle native Java methods. */
 
-       if (m->flags & ACC_STATIC)
-               M_AST(REG_ITMP2, REG_SP, 1 * 4);
+       if (m->flags & ACC_NATIVE) {
+               /* if function is static, put class into second argument */
+
+               if (m->flags & ACC_STATIC)
+                       M_AST(REG_ITMP3, REG_SP, 1 * 4);
 
-       /* put env into first argument */
+               /* put env into first argument */
 
-       M_AST_IMM(_Jv_env, REG_SP, 0 * 4);
+               M_AST_IMM(_Jv_env, REG_SP, 0 * 4);
+       }
 
        /* call the native function */
 
        emit_mov_imm_reg(cd, 0, REG_ITMP3);
        dseg_adddata(cd);
-       M_ALD(REG_ITMP3, REG_ITMP3, funcdisp);
-       M_CALL(REG_ITMP3);
+       M_ALD(REG_ITMP1, REG_ITMP3, funcdisp);
+       M_CALL(REG_ITMP1);
 
        /* save return value */
 
@@ -3839,10 +3678,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
                break;
        }
 
-#if !defined(NDEBUG)
-       emit_verbosecall_exit(jd);
-#endif
-
        /* remove native stackframe info */
 
        M_MOV(REG_SP, REG_ITMP1);
index 7a9b7755aba00659f1719895b625e588f76896b0..dff6060f7fab6d5e9264ccc9630a4a7de4da14ba 100644 (file)
@@ -2398,12 +2398,11 @@ gen_method:
                        case ICMD_BUILTIN:
                                if (bte->stub == NULL) {
                                        M_MOV_IMM(bte->fp, REG_ITMP1);
-                               } else {
+                               }
+                               else {
                                        M_MOV_IMM(bte->stub, REG_ITMP1);
                                }
                                M_CALL(REG_ITMP1);
-
-                               emit_exception_check(cd, iptr);
                                break;
 
                        case ICMD_INVOKESPECIAL:
@@ -2904,192 +2903,20 @@ void codegen_emit_stub_compiler(jitdata *jd)
 }
 
 
-/* codegen_emit_stub_builtin ***************************************************
-
-   Creates a stub routine which calls a builtin function.
-
-*******************************************************************************/
-
-void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
-{
-       codeinfo    *code;
-       codegendata *cd;
-       methoddesc  *md;
-       s4           i, j;
-       s4           s1, disp;
-
-       /* get required compiler data */
-
-       code = jd->code;
-       cd   = jd->cd;
-
-       md = bte->md;
-
-       /* calculate stack frame size */
-
-       cd->stackframesize =
-               sizeof(stackframeinfo) / SIZEOF_VOID_P +
-               md->paramcount +                          /* saved argument registers */
-               1;                                                    /* return value */
-
-       cd->stackframesize |= 0x1;                  /* keep stack 16-byte aligned */
-
-       /* create method header */
-
-       (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
-       (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
-       (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
-       (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
-       (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
-       (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
-       (void) dseg_addlinenumbertablesize(cd);
-       (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
-
-       /* generate stub code */
-
-       M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
-
-#if defined(ENABLE_GC_CACAO)
-       /* Save callee saved integer registers in stackframeinfo (GC may
-          need to recover them during a collection). */
-
-       disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
-               OFFSET(stackframeinfo, intregs);
-
-       for (i = 0; i < INT_SAV_CNT; i++)
-               M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
-#endif
-
-       /* save integer and float argument registers */
-
-       for (i = 0, j = 0; i < md->paramcount; i++) {
-               if (!md->params[i].inmemory) {
-                       s1 = md->params[i].regoff;
-
-                       switch (md->paramtypes[i].type) {
-                       case TYPE_INT:
-                       case TYPE_LNG:
-                       case TYPE_ADR:
-                               M_LST(s1, REG_SP, j * 8);
-                               break;
-                       case TYPE_FLT:
-                       case TYPE_DBL:
-                               M_DST(s1, REG_SP, j * 8);
-                               break;
-                       }
-
-                       j++;
-               }
-       }
-
-       /* create dynamic stack info */
-
-       M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
-       emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
-       M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
-       M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
-       M_MOV_IMM(codegen_stub_builtin_enter, REG_ITMP1);
-       M_CALL(REG_ITMP1);
-
-       /* restore integer and float argument registers */
-
-       for (i = 0, j = 0; i < md->paramcount; i++) {
-               if (!md->params[i].inmemory) {
-                       s1 = md->params[i].regoff;
-
-                       switch (md->paramtypes[i].type) {
-                       case TYPE_INT:
-                       case TYPE_LNG:
-                       case TYPE_ADR:
-                               M_LLD(s1, REG_SP, j * 8);
-                               break;
-                       case TYPE_FLT:
-                       case TYPE_DBL:
-                               M_DLD(s1, REG_SP, j * 8);
-                               break;
-                       }
-
-                       j++;
-               }
-       }
-
-       /* call the builtin function */
-
-       M_MOV_IMM(bte->fp, REG_ITMP3);
-       M_CALL(REG_ITMP3);
-
-       /* save return value */
-
-       switch (md->returntype.type) {
-       case TYPE_INT:
-       case TYPE_LNG:
-       case TYPE_ADR:
-               M_LST(REG_RESULT, REG_SP, 0 * 8);
-               break;
-       case TYPE_FLT:
-       case TYPE_DBL:
-               M_DST(REG_FRESULT, REG_SP, 0 * 8);
-               break;
-       case TYPE_VOID:
-               break;
-       }
-
-       /* remove native stackframe info */
-
-       M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
-       M_MOV_IMM(codegen_stub_builtin_exit, REG_ITMP1);
-       M_CALL(REG_ITMP1);
-
-       /* restore return value */
-
-       switch (md->returntype.type) {
-       case TYPE_INT:
-       case TYPE_LNG:
-       case TYPE_ADR:  
-               M_LLD(REG_RESULT, REG_SP, 0 * 8);
-               break;
-       case TYPE_FLT:
-       case TYPE_DBL:
-               M_DLD(REG_FRESULT, REG_SP, 0 * 8);
-               break;
-       case TYPE_VOID:
-               break;
-       }
-
-#if defined(ENABLE_GC_CACAO)
-       /* Restore callee saved integer registers from stackframeinfo (GC
-          might have modified them during a collection). */
-        
-       disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
-               OFFSET(stackframeinfo, intregs);
-
-       for (i = 0; i < INT_SAV_CNT; i++)
-               M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
-#endif
-
-       /* remove stackframe */
-
-       M_AADD_IMM(cd->stackframesize * 8, REG_SP);
-       M_RET;
-}
-
-
 /* codegen_emit_stub_native ****************************************************
 
    Emits a stub routine which calls a native method.
 
 *******************************************************************************/
 
-void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
+void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
 {
        methodinfo  *m;
        codeinfo    *code;
        codegendata *cd;
        methoddesc  *md;
-       s4           nativeparams;
-       s4           i, j;
-       s4           t;
-       s4           s1, s2;
+       int          i, j;
+       int          s1, s2;
        int          funcdisp;
 #if defined(ENABLE_GC_CACAO)
        int          disp;
@@ -3104,7 +2931,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
        /* initialize variables */
 
        md = m->parseddesc;
-       nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
 
        /* calculate stack frame size */
 
@@ -3112,10 +2938,9 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
                sizeof(stackframeinfo) / SIZEOF_VOID_P +
                sizeof(localref_table) / SIZEOF_VOID_P +
                md->paramcount +
-               1 +                       /* functionptr, TODO: store in data segment */
                nmd->memuse;
 
-       cd->stackframesize |= 0x1;                  /* keep stack 16-byte aligned */
+       ALIGN_ODD(cd->stackframesize);              /* keep stack 16-byte aligned */
 
        /* create method header */
 
@@ -3213,13 +3038,15 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
                }
        }
 
-       /* copy or spill arguments to new locations */
+       /* Copy or spill arguments to new locations. */
 
-       for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
-               t  = md->paramtypes[i].type;
+       for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
                s2 = nmd->params[j].regoff;
 
-               if (IS_INT_LNG_TYPE(t)) {
+               switch (md->paramtypes[i].type) {
+               case TYPE_INT:
+               case TYPE_LNG:
+               case TYPE_ADR:
                        if (!md->params[i].inmemory) {
                                s1 = md->params[i].regoff;
 
@@ -3233,34 +3060,40 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
                                M_LLD(REG_ITMP1, REG_SP, s1);
                                M_LST(REG_ITMP1, REG_SP, s2);
                        }
-               }
-               else {
+                       break;
+               case TYPE_FLT:
                        /* We only copy spilled float arguments, as the float
                           argument registers keep unchanged. */
 
                        if (md->params[i].inmemory) {
                                s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
 
-                               if (IS_2_WORD_TYPE(t)) {
-                                       M_DLD(REG_FTMP1, REG_SP, s1);
-                                       M_DST(REG_FTMP1, REG_SP, s2);
-                               }
-                               else {
-                                       M_FLD(REG_FTMP1, REG_SP, s1);
-                                       M_FST(REG_FTMP1, REG_SP, s2);
-                               }
+                               M_FLD(REG_FTMP1, REG_SP, s1);
+                               M_FST(REG_FTMP1, REG_SP, s2);
+                       }
+                       break;
+               case TYPE_DBL:
+                       if (md->params[i].inmemory) {
+                               s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
+                               M_DLD(REG_FTMP1, REG_SP, s1);
+                               M_DST(REG_FTMP1, REG_SP, s2);
                        }
+                       break;
                }
        }
 
-       /* put class into second argument register */
+       /* Handle native Java methods. */
 
-       if (m->flags & ACC_STATIC)
-               M_MOV(REG_ITMP2, REG_A1);
+       if (m->flags & ACC_NATIVE) {
+               /* put class into second argument register */
 
-       /* put env into first argument register */
+               if (m->flags & ACC_STATIC)
+                       M_MOV(REG_ITMP2, REG_A1);
 
-       M_MOV_IMM(_Jv_env, REG_A0);
+               /* put env into first argument register */
+
+               M_MOV_IMM(_Jv_env, REG_A0);
+       }
 
        /* do the native function call */