* Removed all Id tags.
[cacao.git] / src / vm / jit / sparc64 / codegen.c
index 1ba11be8377b311f684640894365a6fc4bf8b646..d4f9483f382fbd84632355e2f528055c9d9545da 100644 (file)
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: codegen.c 4644 2006-03-16 18:44:46Z edwin $
-
 */
 
 
 #include "config.h"
 
 #include <assert.h>
+#include <stdint.h>
 #include <stdio.h>
 
 #include "vm/types.h"
@@ -42,6 +41,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 +96,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 +159,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 +187,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 +219,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 +333,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;
@@ -1343,7 +1366,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;
 
@@ -1355,7 +1378,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;
 
@@ -1368,7 +1391,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;                  
 
@@ -1381,7 +1404,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;
 
@@ -1394,7 +1417,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;
 
@@ -1407,7 +1430,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;
 
@@ -1420,7 +1443,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;
 
@@ -1433,7 +1456,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;
 
@@ -1446,7 +1469,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;
 
@@ -1459,7 +1482,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  ==> ...         */
@@ -1472,7 +1495,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  ==> ...         */
@@ -1484,7 +1507,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  ==> ...         */
@@ -1496,7 +1519,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  ==> ...         */
@@ -1508,7 +1531,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  ==> ...         */
@@ -1520,7 +1543,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;
 
 
@@ -1546,7 +1569,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;
 
 
@@ -1557,7 +1580,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  ==> ...            */
@@ -1569,7 +1592,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  ==> ...            */
@@ -1580,7 +1603,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  ==> ...            */
@@ -1591,7 +1614,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  ==> ...            */
@@ -1602,23 +1625,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);
@@ -1654,16 +1677,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);
@@ -1702,14 +1725,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);
@@ -2312,15 +2335,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 */
@@ -2556,7 +2579,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 */
@@ -2585,7 +2608,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);
 
@@ -2684,7 +2707,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);
@@ -2720,7 +2743,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;
@@ -2856,7 +2879,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);
@@ -2890,7 +2913,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;
@@ -3076,7 +3099,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;
 
 
@@ -3115,7 +3138,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);
 
@@ -3164,7 +3187,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 */
@@ -3183,7 +3206,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);
                        }
@@ -3217,25 +3240,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);
                                }
                        }
                }