2008-08-18 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / inssel-mips.brg
index 214237db7050fb8948165d7adb99935ac4b3921d..2a5229aca196b1803d468b0b8a825d6397c34672 100644 (file)
@@ -295,8 +295,13 @@ stmt: OP_SWITCH (reg) {
 
 stmt: CEE_STIND_I8 (OP_REGVAR, lreg) {
        /* this should only happen for methods returning a long */
-       MONO_EMIT_NEW_UNALU (s, OP_MOVE, mips_v0, state->right->reg1);
-       MONO_EMIT_NEW_UNALU (s, OP_MOVE, mips_v1, state->right->reg2);
+       if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
+               MONO_EMIT_NEW_UNALU (s, OP_MOVE, mips_v0, state->right->reg2);
+               MONO_EMIT_NEW_UNALU (s, OP_MOVE, mips_v1, state->right->reg1);
+       } else {
+               MONO_EMIT_NEW_UNALU (s, OP_MOVE, mips_v0, state->right->reg1);
+               MONO_EMIT_NEW_UNALU (s, OP_MOVE, mips_v1, state->right->reg2);
+       }
 }
 
 freg: OP_LCONV_TO_R8 (lreg) {
@@ -342,14 +347,23 @@ stmt: OP_SETRET (reg) {
 
 stmt: OP_SETRET (lreg) {
        tree->opcode = OP_SETLRET;
-       tree->sreg1 = state->left->reg1;
-       tree->sreg2 = state->left->reg2;
+       if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
+               tree->sreg1 = state->left->reg2;
+               tree->sreg2 = state->left->reg1;
+       } else {
+               tree->sreg1 = state->left->reg1;
+               tree->sreg2 = state->left->reg2;
+       }
        tree->dreg = mips_v0;
        mono_bblock_add_inst (s->cbb, tree);
 }
 
 stmt: OP_SETRET (freg) {
-       tree->opcode = OP_FMOVE;
+       if (mono_method_signature (s->method)->ret->type == MONO_TYPE_R4) {
+               tree->opcode = OP_MIPS_CVTSD;
+       } else {
+               tree->opcode = OP_FMOVE;
+       }
        tree->sreg1 = state->left->reg1;
        tree->dreg = mips_f0;
        mono_bblock_add_inst (s->cbb, tree);
@@ -439,11 +453,17 @@ stmt: OP_OUTARG (lreg) {
        MonoCallInst *call = tree->inst_call;
        int tdreg = mono_regstate_next_int (s->rs);
 
-       MONO_EMIT_NEW_UNALU (s, OP_MOVE, tdreg, state->left->reg2);
+       if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
+               MONO_EMIT_NEW_UNALU (s, OP_MOVE, tdreg, state->left->reg1);
+       else
+               MONO_EMIT_NEW_UNALU (s, OP_MOVE, tdreg, state->left->reg2);
        mono_call_inst_add_outarg_reg (s, call, tdreg, tree->backend.reg3, FALSE);
        tree->opcode = OP_MOVE;
        tree->dreg = mono_regstate_next_int (s->rs);
-       tree->sreg1 = state->left->reg1;
+       if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
+               tree->sreg1 = state->left->reg2;
+       else
+               tree->sreg1 = state->left->reg1;
        mono_bblock_add_inst (s->cbb, tree);
        mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3 + 1, FALSE);
 }
@@ -468,17 +488,6 @@ stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
        mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE);
 }
 
-stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
-       MonoCallInst *call = tree->inst_call;
-
-       tree->opcode = OP_MOVE;
-       tree->sreg1 = state->left->left->tree->dreg;
-       tree->dreg = mono_regstate_next_int (s->rs);
-       mono_bblock_add_inst (s->cbb, tree);
-       mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE);
-}
-
-
 #
 # FP calculation being passed in GP registers
 # Need to get FP bit pattern out in GP regs w/o conversion
@@ -517,9 +526,9 @@ stmt: OP_OUTARG_R8 (CEE_LDOBJ (base)) {
 #
 stmt: OP_OUTARG_MEMBASE (CEE_LDIND_R4 (base)) {
        MonoMIPSArgInfo *ai = tree->backend.data;
-       MonoCallInst *call = tree->inst_call;
-       int opcode = (tree->backend.arg_info & 0xff00) == 0x0400? OP_STORER4_MEMBASE_REG: OP_STORER8_MEMBASE_REG;
+       int opcode = ai->size == 4? OP_STORER4_MEMBASE_REG: OP_STORER8_MEMBASE_REG;
 
+       MONO_EMIT_NEW_LOAD_MEMBASE_OP(s, OP_LOADR4_MEMBASE, state->left->reg1, state->left->left->tree->inst_basereg, state->left->left->tree->inst_offset);
        MONO_EMIT_NEW_STORE_MEMBASE (s, opcode, mips_sp, ai->offset, state->left->reg1);
 }
 
@@ -577,13 +586,6 @@ stmt: OP_OUTARG_R4 (freg) {
 #      mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, TRUE);
 #}
 
-stmt: OP_OUTARG_MEMBASE (CEE_LDIND_R4 (base)) {
-       MonoMIPSArgInfo *ai = tree->backend.data;
-       int opcode = (tree->backend.arg_info & 0xff00) == 0x0400? OP_STORER4_MEMBASE_REG: OP_STORER8_MEMBASE_REG;
-
-       MONO_EMIT_NEW_STORE_MEMBASE (s, opcode, mips_sp, ai->offset, state->left->reg1);
-}
-
 #
 # single-precision floating point constant in a gp register.
 #
@@ -624,11 +626,10 @@ stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
                MONO_EMIT_NEW_LOAD_MEMBASE (s, dreg, vt->inst_basereg, soffset);
                mono_call_inst_add_outarg_reg (s, call, dreg, start_reg + i, FALSE);
                soffset += sizeof (gpointer);
-               doffset += sizeof (gpointer);
        }
        //g_printf ("vt size: %d at R%d + %d\n", ai->offset, vt->inst_basereg, vt->inst_offset);
        if (ovf_size != 0) {
-               mini_emit_memcpy (s, vt->inst_basereg, doffset, vt->inst_basereg, soffset, ovf_size * sizeof (gpointer), 0);
+               mini_emit_memcpy (s, mips_sp, doffset, vt->inst_basereg, soffset, ovf_size * sizeof (gpointer), 0);
        }
 }