These are the core changes for supporting Mono on MIPS-EL. The problem in the existing code (MIPS in big-endian mode) is that it is assuming "lower-numbered reg is most significant", which is not true.
Test code: long long abc = 929; func(abc); gcc generates: li $2,929 # 0x3a1 move $3,$0 sw $2,24($fp) sw $3,28($fp) .loc 1 12 0 lw $4,24($fp) lw $5,28($fp) lw $25,%call16(func)($28) Note that the lower-numbered reg ($4) holds the less significant word, while $5 holds the more significant word. # svn diff mono/mini/mini-mips.c Index: mono/mini/mini-mips.c =================================================================== --- mono/mini/mini-mips.c (revision 136576) +++ mono/mini/mini-mips.c (working copy) @@ -1467,13 +1464,13 @@ ins->dreg = mono_alloc_ireg (cfg); ins->sreg1 = in->dreg + 1; MONO_ADD_INS (cfg->cbb, ins); - mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg + 1, FALSE); + mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg + REGPAIR_LOW, FALSE); MONO_INST_NEW (cfg, ins, OP_MOVE); ins->dreg = mono_alloc_ireg (cfg); ins->sreg1 = in->dreg + 2; MONO_ADD_INS (cfg->cbb, ins); - mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg, FALSE); + mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg + REGPAIR_HIGH, FALSE); } else #endif if (!t->byref && (t->type == MONO_TYPE_R4)) { @@ -1694,8 +1691,8 @@ MonoInst *ins; MONO_INST_NEW (cfg, ins, OP_SETLRET); - ins->sreg1 = val->dreg + 1; - ins->sreg2 = val->dreg + 2; + ins->sreg1 = val->dreg + 1 + REGPAIR_HIGH; + ins->sreg2 = val->dreg + 1 + REGPAIR_LOW; MONO_ADD_INS (cfg->cbb, ins); return; } @@ -3552,8 +3549,8 @@ mips_mtc1 (code, ins->dreg, ins->sreg1); break; case OP_MIPS_MTC1S_2: - mips_mtc1 (code, ins->dreg, ins->sreg1); - mips_mtc1 (code, ins->dreg+1, ins->sreg2); + mips_mtc1 (code, ins->dreg + REGPAIR_HIGH, ins->sreg1); + mips_mtc1 (code, ins->dreg + REGPAIR_LOW, ins->sreg2); break; case OP_MIPS_MFC1S: mips_mfc1 (code, ins->dreg, ins->sreg1); @@ -3565,8 +3562,8 @@ #if 0 mips_dmfc1 (code, ins->dreg, ins->sreg1); #else - mips_mfc1 (code, ins->dreg+1, ins->sreg1); - mips_mfc1 (code, ins->dreg, ins->sreg1+1); + mips_mfc1 (code, ins->dreg, ins->sreg1 + REGPAIR_LOW); + mips_mfc1 (code, ins->dreg+1, ins->sreg1 + REGPAIR_HIGH); #endif break; @@ -4012,8 +4009,8 @@ mips_ldc1 (code, ins->dreg, mips_at, ((guint32)ins->inst_p0) & 0xffff); #else mips_load_const (code, mips_at, ins->inst_p0); - mips_lwc1 (code, ins->dreg, mips_at, 4); - mips_lwc1 (code, ins->dreg+1, mips_at, 0); + mips_lwc1 (code, ins->dreg + REGPAIR_LOW, mips_at, 0); + mips_lwc1 (code, ins->dreg + REGPAIR_HIGH, mips_at, 4); #endif break; case OP_R4CONST: @@ -4029,31 +4026,31 @@ case OP_STORER8_MEMBASE_REG: if (mips_is_imm16 (ins->inst_offset)) { #if _MIPS_SIM == _ABIO32 - mips_swc1 (code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset+4); - mips_swc1 (code, ins->sreg1+1, ins->inst_destbasereg, ins->inst_offset); + mips_swc1 (code, ins->sreg1 + REGPAIR_LOW, ins->inst_destbasereg, ins->inst_offset); + mips_swc1 (code, ins->sreg1 + REGPAIR_HIGH, ins->inst_destbasereg, ins->inst_offset+4); #elif _MIPS_SIM == _ABIN32 mips_sdc1 (code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset); #endif } else { mips_load_const (code, mips_at, ins->inst_offset); mips_addu (code, mips_at, mips_at, ins->inst_destbasereg); - mips_swc1 (code, ins->sreg1, mips_at, 4); - mips_swc1 (code, ins->sreg1+1, mips_at, 0); + mips_swc1 (code, ins->sreg1 + REGPAIR_LOW, mips_at, 0); + mips_swc1 (code, ins->sreg1 + REGPAIR_HIGH, mips_at, 4); } break; case OP_LOADR8_MEMBASE: if (mips_is_imm16 (ins->inst_offset)) { #if _MIPS_SIM == _ABIO32 - mips_lwc1 (code, ins->dreg, ins->inst_basereg, ins->inst_offset+4); - mips_lwc1 (code, ins->dreg+1, ins->inst_basereg, ins->inst_offset); + mips_lwc1 (code, ins->dreg + REGPAIR_LOW, ins->inst_basereg, ins->inst_offset); + mips_lwc1 (code, ins->dreg + REGPAIR_HIGH, ins->inst_basereg, ins->inst_offset+4); #elif _MIPS_SIM == _ABIN32 mips_ldc1 (code, ins->dreg, ins->inst_basereg, ins->inst_offset); #endif } else { mips_load_const (code, mips_at, ins->inst_offset); mips_addu (code, mips_at, mips_at, ins->inst_basereg); - mips_lwc1 (code, ins->dreg, mips_at, 4); - mips_lwc1 (code, ins->dreg+1, mips_at, 0); + mips_lwc1 (code, ins->dreg + REGPAIR_LOW, mips_at, 0); + mips_lwc1 (code, ins->dreg + REGPAIR_HIGH, mips_at, 4); } break; case OP_STORER4_MEMBASE_REG: @@ -4781,8 +4778,8 @@ g_assert (mips_is_imm16 (inst->inst_offset)); if (ainfo->size == 8) { #if _MIPS_SIM == _ABIO32 - mips_swc1 (code, ainfo->reg, inst->inst_basereg, inst->inst_offset+4); - mips_swc1 (code, ainfo->reg+1, inst->inst_basereg, inst->inst_offset); + mips_swc1 (code, ainfo->reg + REGPAIR_LOW, inst->inst_basereg, inst->inst_offset); + mips_swc1 (code, ainfo->reg + REGPAIR_HIGH, inst->inst_basereg, inst->inst_offset + 4); #elif _MIPS_SIM == _ABIN32 mips_sdc1 (code, ainfo->reg, inst->inst_basereg, inst->inst_offset); #endif # svn diff mono/mini/mini-mips.h Index: mono/mini/mini-mips.h =================================================================== --- mono/mini/mini-mips.h (revision 136576) +++ mono/mini/mini-mips.h (working copy) @@ -175,16 +175,18 @@ /* Parameters used by the register allocator */ -/* On Mips, for regpairs, the lower-numbered reg is most significant - * This is true in both big and little endian - */ - #if G_BYTE_ORDER == G_LITTLE_ENDIAN #define RET_REG1 mips_v0 #define RET_REG2 mips_v1 + +#define REGPAIR_LOW 0 +#define REGPAIR_HIGH 1 #else #define RET_REG1 mips_v1 #define RET_REG2 mips_v0 + +#define REGPAIR_LOW 1 +#define REGPAIR_HIGH 0 #endif #define MONO_ARCH_INST_SREG2_MASK(ins) (0) Would be great if someone can take a quick look at my code. Thanks, Rayson _______________________________________________ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list