Merged revisions 8321-8342 via svnmerge from
[cacao.git] / src / vm / jit / sparc64 / codegen.c
index 670246d0639d44a425e8e39366cde77257f7f29d..bee77ffc880e6fe72638e3f382ef868389e04d0f 100644 (file)
@@ -30,6 +30,7 @@
 #include "config.h"
 
 #include <assert.h>
+#include <stdint.h>
 #include <stdio.h>
 
 #include "vm/types.h"
@@ -42,6 +43,7 @@
 #include "mm/memory.h"
 
 #include "native/jni.h"
+#include "native/localref.h"
 #include "native/native.h"
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
@@ -96,6 +98,22 @@ s4 get_lopart_disp(disp)
                
        return lodisp;
 }
+
+#ifndef NDEBUG
+bool check_13bit_imm(s8 imm)
+{
+       s4 sign = (imm >> 12) & 0x1;
+
+       if (sign == 0) {
+               if ((imm & ~0xfff) == 0) return true; /* pos imm. */
+       }
+       else
+               if ((imm & ~0xfff) + 0xfff == -1) return true; /* neg imm. */
+       
+       printf("immediate out-of-bounds: %ld\n", imm);
+       return false;
+}
+#endif
        
 
 /* codegen_emit ****************************************************************
@@ -143,6 +161,7 @@ bool codegen_emit(jitdata *jd)
        {
        s4 i, p, t, l;
        s4 savedregs_num;
+       s4 framesize_disp;
 
 #if 0 /* no leaf optimization yet */
        savedregs_num = (jd->isleafmethod) ? 0 : 1;       /* space to save the RA */
@@ -170,7 +189,7 @@ bool codegen_emit(jitdata *jd)
        /* create method header */
 
        (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
-       (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
+       framesize_disp = dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
 
 #if defined(ENABLE_THREADS)
        /* IsSync contains the offset relative to the stack pointer for the
@@ -202,9 +221,15 @@ bool codegen_emit(jitdata *jd)
 
        /* save register window and create stack frame (if necessary) */
 
-       if (cd->stackframesize)
-               M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
-
+       if (cd->stackframesize) {
+               if (cd->stackframesize <= 4095)
+                       M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
+               else {
+                       M_ILD_INTERN(REG_ITMP3, REG_PV_CALLER, framesize_disp);
+                       M_SUB(REG_ZERO, REG_ITMP3, REG_ITMP3);
+                       M_SAVE_REG(REG_SP, REG_ITMP3, REG_SP);
+               }
+       }
 
        /* save callee saved float registers (none right now) */
 #if 0
@@ -310,7 +335,7 @@ bool codegen_emit(jitdata *jd)
                                        for (i = 0; i < jd->varcount; i++) {
                                                varinfo* uvar = VAR(i);
 
-                                               if (IS_FLT_DBL_TYPE(uvar->type))
+                                               if (IS_FLT_DBL_TYPE(uvar->type) || IS_INMEMORY(uvar->flags))
                                                        continue;
 
                                                s2 = uvar->vv.regoff;
@@ -1338,7 +1363,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        emit_nullpointer_check(cd, iptr, s1);
-                       M_ILD(d, s1, OFFSET(java_arrayheader, size));
+                       M_ILD(d, s1, OFFSET(java_array_t, size));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1350,7 +1375,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP3);
-                       M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
+                       M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1363,7 +1388,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP3);
                        M_AADD(s2, REG_ITMP3, REG_ITMP3);
-                       M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
+                       M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;                  
 
@@ -1376,7 +1401,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP3);
                        M_AADD(s2, REG_ITMP3, REG_ITMP3);
-                       M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
+                       M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1389,7 +1414,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 2, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
-                       M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
+                       M_ILD(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1402,7 +1427,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
-                       M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
+                       M_LDX(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1415,7 +1440,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 2, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
-                       M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
+                       M_FLD(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1428,7 +1453,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
-                       M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
+                       M_DLD(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1441,7 +1466,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
-                       M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
+                       M_ALD(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1454,7 +1479,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
+                       M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
                        break;
 
                case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1467,7 +1492,7 @@ bool codegen_emit(jitdata *jd)
                        M_AADD(s2, s1, REG_ITMP1);
                        M_AADD(s2, REG_ITMP1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
+                       M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
                        break;
 
                case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1479,7 +1504,7 @@ bool codegen_emit(jitdata *jd)
                        M_ASLL_IMM(s2, 2, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
+                       M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
                        break;
 
                case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1491,7 +1516,7 @@ bool codegen_emit(jitdata *jd)
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
+                       M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
                        break;
 
                case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1503,7 +1528,7 @@ bool codegen_emit(jitdata *jd)
                        M_ASLL_IMM(s2, 2, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_FTMP1);
-                       M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
+                       M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
                        break;
 
                case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1515,7 +1540,7 @@ bool codegen_emit(jitdata *jd)
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_FTMP1);
-                       M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
+                       M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
                        break;
 
 
@@ -1541,7 +1566,7 @@ bool codegen_emit(jitdata *jd)
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
                        /* implicit null-pointer check */
-                       M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
+                       M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
                        break;
 
 
@@ -1552,7 +1577,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP1);
-                       M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
+                       M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
                        break;
 
                case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
@@ -1564,7 +1589,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP1);
                        M_AADD(s2, REG_ITMP1, REG_ITMP1);
-                       M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
+                       M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
                        break;
 
                case ICMD_IASTORECONST:   /* ..., arrayref, index  ==> ...            */
@@ -1575,7 +1600,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 2, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
-                       M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
+                       M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
                        break;
 
                case ICMD_LASTORECONST:   /* ..., arrayref, index  ==> ...            */
@@ -1586,7 +1611,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
-                       M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
+                       M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
                        break;
 
                case ICMD_AASTORECONST:   /* ..., arrayref, index  ==> ...            */
@@ -1597,23 +1622,23 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
-                       M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
+                       M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
                        break;
                
 
                case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               uf = iptr->sx.s23.s3.uf;
+                               uf        = iptr->sx.s23.s3.uf;
                                fieldtype = uf->fieldref->parseddesc.fd->type;
                                disp      = dseg_add_unique_address(cd, uf);
 
                                codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
                        } 
                        else {
-                               fi = iptr->sx.s23.s3.fmiref->p.field;
+                               fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
-                               disp = dseg_add_address(cd, &(fi->value));
+                               disp      = dseg_add_address(cd, fi->value);
 
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
                                        codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
@@ -1649,16 +1674,16 @@ bool codegen_emit(jitdata *jd)
                case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               uf = iptr->sx.s23.s3.uf;
+                               uf        = iptr->sx.s23.s3.uf;
                                fieldtype = uf->fieldref->parseddesc.fd->type;
                                disp      = dseg_add_unique_address(cd, uf);
 
                                codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
                        } 
                        else {
-                               fi = iptr->sx.s23.s3.fmiref->p.field;
+                               fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
-                               disp = dseg_add_address(cd, &(fi->value));
+                               disp      = dseg_add_address(cd, fi->value);
 
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
                                        codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
@@ -1697,14 +1722,14 @@ bool codegen_emit(jitdata *jd)
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                uf        = iptr->sx.s23.s3.uf;
                                fieldtype = uf->fieldref->parseddesc.fd->type;
-                               disp = dseg_add_unique_address(cd, uf);
+                               disp      = dseg_add_unique_address(cd, uf);
 
                                codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
                        } 
                        else {
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
-                               disp      = dseg_add_address(cd, &(fi->value));
+                               disp      = dseg_add_address(cd, fi->value);
 
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
                                        codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
@@ -2315,15 +2340,15 @@ nowperformreturn:
                        if (l == 0) {
                                M_INTMOVE(s1, REG_ITMP1);
                        }
-                       else if (l <= 4095) {
+                       else if (-l >= 4096 && -l <= 4095) {
                                M_ADD_IMM(s1, -l, REG_ITMP1);
                        }
                        else {
                                ICONST(REG_ITMP2, l);
-                               /* XXX: do I need to truncate s1 to 32-bit ? */
                                M_SUB(s1, REG_ITMP2, REG_ITMP1);
                        }
-                       i = i - l + 1;
+
+                       i = i - l + 1; /* number of targets (>0) */
 
 
                        /* range check */
@@ -2570,7 +2595,7 @@ gen_method:
                                                sizeof(methodptr) * lm->vftblindex;
 
                                /* implicit null-pointer check */
-                               M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_object_t, vftbl));
                                M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
                                
                                /* generate the actual call */
@@ -2600,7 +2625,7 @@ gen_method:
                                }
 
                                /* implicit null-pointer check */
-                               M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_object_t, vftbl));
                                M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
                                M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
 
@@ -2700,7 +2725,7 @@ gen_method:
                                                emit_label_beqz(cd, BRANCH_LABEL_3, s1);
                                        }
 
-                                       M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
+                                       M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                        M_ILD(REG_ITMP3, REG_ITMP2,
                                                        OFFSET(vftbl_t, interfacetablelength));
                                        M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
@@ -2736,7 +2761,7 @@ gen_method:
                                                emit_label_beqz(cd, BRANCH_LABEL_5, s1);
                                        }
 
-                                       M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
+                                       M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                        M_ALD(REG_ITMP3, REG_PV, disp);
                                        
                                        CODEGEN_CRITICAL_SECTION_START;
@@ -2872,7 +2897,7 @@ gen_method:
                                        emit_label_beqz(cd, BRANCH_LABEL_3, s1);
                                }
 
-                               M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
                                M_CMP_IMM(REG_ITMP3, superindex);
                                M_BLE(4);
@@ -2906,7 +2931,7 @@ gen_method:
                                        emit_label_beqz(cd, BRANCH_LABEL_5, s1);
                                }
 
-                               M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_ALD(REG_ITMP2, REG_PV, disp);
 
                                CODEGEN_CRITICAL_SECTION_START;
@@ -3263,7 +3288,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
                sizeof(stackframeinfo) / SIZEOF_VOID_P +
                sizeof(localref_table) / SIZEOF_VOID_P +
                md->paramcount +                /* for saving arguments over calls    */
-               nmd->memuse +  /* nmd knows about the native stackframe layout */
+               nmd->memuse +              /* nmd->memuse includes the (6) abi params */
                WINSAVE_CNT;
 
 
@@ -3302,7 +3327,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
        }
 #endif
 
-       /* save float argument registers (into abi parameter slots) */
+       /* save float argument registers */
 
        assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
 
@@ -3351,7 +3376,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
                                s1 = REG_WINDOW_TRANSPOSE(s1);
 
                                if (!nmd->params[j].inmemory) {
-                                       s2 = nat_argintregs[nmd->params[j].regoff];
+                                       s2 = nmd->params[j].regoff;
                                        M_INTMOVE(s1, s2);
                                } else {
                                        /* nmd's regoff is relative to the start of the param array */
@@ -3370,7 +3395,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
                                }
 
                                s1 = md->params[i].regoff + cd->stackframesize * 8;
-                               s2 = BIAS + WINSAVE_CNT + 8 + nmd->params[j].regoff;
+                               s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
                                M_ALD(REG_ITMP1, REG_SP, CSTACK + s1);
                                M_AST(REG_ITMP1, REG_SP, s2);
                        }
@@ -3404,25 +3429,25 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
                        } 
                        else {
-                               s1 = md->params[i].regoff + cd->stackframesize * 8;
+                               s1 = md->params[i].regoff;
 
                                if (!nmd->params[j].inmemory) {
 
                                        /* JIT stack -> NAT reg */
 
-                                       s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff; 
-                                       M_DLD(s2, REG_SP, s1);
+                                       s2 = nmd->params[j].regoff;
+                                       M_DLD(s2, REG_FP, JITSTACK + s1);
                                }
                                else {
 
                                        /* JIT stack -> NAT stack */
 
-                                       s2 = nmd->params[j].regoff - 6 * 8;
+                                       s2 = WINSAVE_CNT * 8 + nmd->params[j].regoff;
 
                                        /* The FTMP register may already be loaded with args */
                                        /* we know $f0 is unused because of the env pointer  */
-                                       M_DLD(REG_F0, REG_SP, CSTACK + s1);
-                                       M_DST(REG_F0, REG_SP, CSTACK + s2);
+                                       M_DLD(REG_F0, REG_FP, JITSTACK + s1);
+                                       M_DST(REG_F0, REG_SP, BIAS + s2);
                                }
                        }
                }