#include <mono/metadata/appdomain.h>
#include <mono/metadata/debug-helpers.h>
+#include <mono/arch/mips/mips-codegen.h>
+
#include "mini-mips.h"
#include "cpu-mips.h"
#include "trace.h"
#include "ir-emit.h"
-#warning "The mips backend is still being ported to the linear IR."
-
#define SAVE_FP_REGS 0
#define SAVE_ALL_REGS 0
#define EXTRA_STACK_SPACE 0 /* suppresses some s-reg corruption issues */
-#define LONG_BRANCH 0 /* needed for yyparse in mcs */
+#define LONG_BRANCH 1 /* needed for yyparse in mcs */
#define SAVE_LMF 1
#define ALWAYS_USE_FP 1
#define ALWAYS_SAVE_RA 1 /* call-handler & switch currently clobber ra */
#define PROMOTE_R4_TO_R8 1 /* promote single values in registers to doubles */
+#define USE_MUL 1 /* use mul instead of mult/mflo for multiply */
enum {
TLS_MODE_DETECT,
mono_bblock_add_inst (cfg->cbb, inst); \
} while (0)
-#define ins_is_compare(ins) ((ins) && (((ins)->opcode == OP_COMPARE) || ((ins)->opcode == OP_ICOMPARE)))
-#define ins_is_compare_imm(ins) ((ins) && (((ins)->opcode == OP_COMPARE_IMM) || ((ins)->opcode == OP_ICOMPARE_IMM)))
+#define ins_is_compare(ins) ((ins) && (((ins)->opcode == OP_COMPARE) \
+ || ((ins)->opcode == OP_ICOMPARE) \
+ || ((ins)->opcode == OP_LCOMPARE)))
+#define ins_is_compare_imm(ins) ((ins) && (((ins)->opcode == OP_COMPARE_IMM) \
+ || ((ins)->opcode == OP_ICOMPARE_IMM) \
+ || ((ins)->opcode == OP_LCOMPARE_IMM)))
#define INS_REWRITE(ins, op, _s1, _s2) do { \
int s1 = _s1; \
void patch_lui_addiu(guint32 *ip, guint32 val);
guint8 *mono_arch_emit_epilog_sub (MonoCompile *cfg, guint8 *code);
+guint8 *mips_emit_cond_branch (MonoCompile *cfg, guint8 *code, int op, MonoInst *ins);
+void mips_adjust_stackframe(MonoCompile *cfg);
+void mono_arch_emit_this_vret_args (MonoCompile *cfg, MonoCallInst *inst, int this_reg, int this_type, int vt_reg);
+MonoInst *mono_arch_get_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args);
+
void
mono_arch_flush_icache (guint8 *code, gint size)
mips_emit_exc_by_name(guint8 *code, const char *name)
{
guint32 addr;
+ MonoClass *exc_class;
+
+ exc_class = mono_class_from_name (mono_defaults.corlib, "System", patch_info->data.name);
+ g_assert (exc_class);
- mips_load_const (code, mips_a0, name);
- addr = (guint32) mono_arch_get_throw_exception_by_name ();
+ mips_load_const (code, mips_a0, exc_class->type_token);
+ addr = (guint32) mono_arch_get_throw_corlib_exception ();
mips_load_const (code, mips_t9, addr);
mips_jalr (code, mips_t9, mips_ra);
mips_nop (code);
}
+guint8 *
+mips_emit_load_const(guint8 *code, int dreg, mgreg_t v)
+{
+ if (mips_is_imm16 (v))
+ mips_addiu (code, dreg, mips_zero, ((guint32)v) & 0xffff);
+ else {
+#ifdef SIZEOF_REGISTER == 8
+ if (v != (long) v) {
+ /* v is not a sign-extended 32-bit value */
+ mips_lui (code, dreg, mips_zero, (guint32)((v >> (32+16)) & 0xffff));
+ mips_ori (code, dreg, dreg, (guint32)((v >> (32)) & 0xffff));
+ mips_dsll (code, dreg, dreg, 16);
+ mips_ori (code, dreg, dreg, (guint32)((v >> (16)) & 0xffff));
+ mips_dsll (code, dreg, dreg, 16);
+ mips_ori (code, dreg, dreg, (guint32)(v & 0xffff));
+ return code;
+ }
+#endif
+ if (((guint32)v) & (1 << 15)) {
+ mips_lui (code, dreg, mips_zero, (((guint32)v)>>16)+1);
+ }
+ else {
+ mips_lui (code, dreg, mips_zero, (((guint32)v)>>16));
+ }
+ if (((guint32)v) & 0xffff)
+ mips_addiu (code, dreg, dreg, ((guint32)v) & 0xffff);
+ }
+ return code;
+}
+
guint8 *
mips_emit_cond_branch (MonoCompile *cfg, guint8 *code, int op, MonoInst *ins)
{
+#if LONG_BRANCH
int br_offset = 5;
+#endif
g_assert (ins);
#if LONG_BRANCH
}
}
+#if 0
static int
offsets_from_pthread_key (guint32 key, int *offset2)
{
*offset2 = idx2 * sizeof (gpointer);
return 284 + idx1 * sizeof (gpointer);
}
+#endif
const char*
mono_arch_regname (int reg) {
+#if _MIPS_SIM == _ABIO32
static const char * rnames[] = {
"zero", "at", "v0", "v1",
"a0", "a1", "a2", "a3",
"t8", "t9", "k0", "k1",
"gp", "sp", "fp", "ra"
};
+#elif _MIPS_SIM == _ABIN32
+ static const char * rnames[] = {
+ "zero", "at", "v0", "v1",
+ "a0", "a1", "a2", "a3",
+ "a4", "a5", "a6", "a7",
+ "t0", "t1", "t2", "t3",
+ "s0", "s1", "s2", "s3",
+ "s4", "s5", "s6", "s7",
+ "t8", "t9", "k0", "k1",
+ "gp", "sp", "fp", "ra"
+ };
+#endif
if (reg >= 0 && reg < 32)
return rnames [reg];
return "unknown";
switch (t->type) {
case MONO_TYPE_I4:
case MONO_TYPE_U4:
+#if (SIZEOF_REGISTER == 8)
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+#endif
case MONO_TYPE_I:
case MONO_TYPE_U:
case MONO_TYPE_PTR:
static void
args_onto_stack (CallInfo *info)
{
- g_assert(!info->on_stack);
- g_assert(info->stack_size <= MIPS_STACK_PARAM_OFFSET);
+ g_assert (!info->on_stack);
+ g_assert (info->stack_size <= MIPS_STACK_PARAM_OFFSET);
info->on_stack = TRUE;
info->stack_size = MIPS_STACK_PARAM_OFFSET;
}
+#if _MIPS_SIM == _ABIO32
/*
* O32 calling convention version
*/
/* Now, place the argument */
if (info->on_stack) {
- g_assert(info->stack_size % 4 == 0);
+ g_assert (info->stack_size % 4 == 0);
info->stack_size += (info->stack_size % 8);
ainfo->regtype = RegTypeBase;
}
info->stack_size += 8;
}
+#elif _MIPS_SIM == _ABIN32
+/*
+ * N32 calling convention version
+ */
+
+static void
+add_int32_arg (CallInfo *info, ArgInfo *ainfo) {
+ /* First, see if we need to drop onto the stack */
+ if (!info->on_stack && info->gr > MIPS_LAST_ARG_REG)
+ args_onto_stack (info);
+
+ /* Now, place the argument */
+ if (info->on_stack) {
+ ainfo->regtype = RegTypeBase;
+ ainfo->reg = mips_sp; /* in the caller */
+ ainfo->offset = info->stack_size;
+ info->stack_size += SIZEOF_REGISTER;
+ }
+ else {
+ ainfo->regtype = RegTypeGeneral;
+ ainfo->reg = info->gr;
+ info->gr += 1;
+ info->gr_passed = TRUE;
+ }
+}
+
+static void
+add_int64_arg (CallInfo *info, ArgInfo *ainfo) {
+ /* First, see if we need to drop onto the stack */
+ if (!info->on_stack && info->gr > MIPS_LAST_ARG_REG)
+ args_onto_stack (info);
+
+ /* Now, place the argument */
+ if (info->on_stack) {
+ g_assert (info->stack_size % 4 == 0);
+ info->stack_size += (info->stack_size % 8);
+
+ ainfo->regtype = RegTypeBase;
+ ainfo->reg = mips_sp; /* in the caller */
+ ainfo->offset = info->stack_size;
+ info->stack_size += SIZEOF_REGISTER;
+ }
+ else {
+ g_assert (info->gr <= MIPS_LAST_ARG_REG);
+
+ ainfo->regtype = RegTypeGeneral;
+ ainfo->reg = info->gr;
+ info->gr += 1;
+ info->gr_passed = TRUE;
+ }
+}
+
+static void
+add_float32_arg (CallInfo *info, ArgInfo *ainfo) {
+ /* First, see if we need to drop onto the stack */
+ if (!info->on_stack) {
+ if (info->gr > MIPS_LAST_ARG_REG)
+ args_onto_stack (info);
+ else if (info->fr > MIPS_LAST_FPARG_REG)
+ args_onto_stack (info);
+ }
+
+ /* Now, place the argument */
+ if (info->on_stack) {
+ ainfo->regtype = RegTypeBase;
+ ainfo->reg = mips_sp; /* in the caller */
+ ainfo->offset = info->stack_size;
+ info->stack_size += FREG_SIZE;
+ }
+ else {
+ ainfo->regtype = RegTypeFP;
+ ainfo->reg = info->fr;
+ info->fr += 1;
+ /* FP and GP slots do not overlap */
+ info->gr += 1;
+ }
+}
+
+static void
+add_float64_arg (CallInfo *info, ArgInfo *ainfo) {
+ /* First, see if we need to drop onto the stack */
+ if (!info->on_stack) {
+ if (info->gr > MIPS_LAST_ARG_REG)
+ args_onto_stack (info);
+ else if (info->fr > MIPS_LAST_FPARG_REG)
+ args_onto_stack (info);
+ }
+
+ /* Now, place the argument */
+ if (info->on_stack) {
+ g_assert(info->stack_size % 4 == 0);
+ info->stack_size += (info->stack_size % 8);
+
+ ainfo->regtype = RegTypeBase;
+ ainfo->reg = mips_sp; /* in the caller */
+ ainfo->offset = info->stack_size;
+ info->stack_size += FREG_SIZE;
+ }
+ else {
+ ainfo->regtype = RegTypeFP;
+ ainfo->reg = info->fr;
+ info->fr += 1;
+ /* FP and GP slots do not overlap */
+ info->gr += 1;
+ }
+}
+#endif
static CallInfo*
calculate_sizes (MonoMethodSignature *sig, gboolean is_pinvoke)
cinfo->stack_size, alignment);
#endif
nwords = (size + sizeof (gpointer) -1 ) / sizeof (gpointer);
- g_assert(cinfo->args [n].size == 0);
- g_assert(cinfo->args [n].vtsize == 0);
+ g_assert (cinfo->args [n].size == 0);
+ g_assert (cinfo->args [n].vtsize == 0);
for (j = 0; j < nwords; ++j) {
if (j == 0) {
add_int32_arg (cinfo, &cinfo->args [n]);
int i, offset, size, align, curinst;
int frame_reg = mips_sp;
guint32 iregs_to_save = 0;
+#if SAVE_FP_REGS
guint32 fregs_to_restore;
+#endif
/* spill down, we'll fix it in a separate pass */
// cfg->flags |= MONO_CFG_HAS_SPILLUP;
if (iregs_to_save) {
for (i = MONO_MAX_IREGS-1; i >= 0; --i) {
if (iregs_to_save & (1 << i)) {
- offset += sizeof (gulong);
+ offset += SIZEOF_REGISTER;
}
}
}
if (fregs_to_restore) {
for (i = MONO_MAX_FREGS-1; i >= 0; --i) {
if (fregs_to_restore & (1 << i)) {
- offset += sizeof (double);
+ offset += sizeof(double);
}
}
}
#endif
+#if _MIPS_SIM == _ABIO32
/* Now add space for saving the ra */
- offset += 4;
+ offset += SIZEOF_VOID_P;
/* change sign? */
offset = (offset + MIPS_STACK_ALIGNMENT - 1) & ~(MIPS_STACK_ALIGNMENT - 1);
cfg->stack_offset = offset;
cfg->arch.local_alloc_offset = cfg->stack_offset;
+#endif
/*
* Now allocate stack slots for the int arg regs (a0 - a3)
cfg->vret_addr->inst_c0 = mips_a0;
cfg->vret_addr->inst_offset = offset;
cfg->vret_addr->inst_basereg = frame_reg;
- offset += 4;
+ offset += SIZEOF_REGISTER;
}
for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
inst->opcode = OP_REGOFFSET;
size = mono_type_size (arg_type, &align);
- if (size < 4) {
- size = 4;
- align = 4;
+ if (size < SIZEOF_REGISTER) {
+ size = SIZEOF_REGISTER;
+ align = SIZEOF_REGISTER;
}
inst->inst_basereg = frame_reg;
offset = (offset + align - 1) & ~(align - 1);
// g_print ("allocating param %d to %d\n", i, inst->inst_offset);
}
else {
- /* Even a0-a3 get stack slots */
- size = sizeof (gpointer);
- align = sizeof (gpointer);
+#if _MIPS_SIM == _ABIO32
+ /* o32: Even a0-a3 get stack slots */
+ size = SIZEOF_REGISTER;
+ align = SIZEOF_REGISTER;
inst->inst_basereg = frame_reg;
offset = (offset + align - 1) & ~(align - 1);
inst->inst_offset = offset;
if ((sig->call_convention == MONO_CALL_VARARG) && (i < sig->sentinelpos))
cfg->sig_cookie += size;
// g_print ("allocating param %d to %d\n", i, inst->inst_offset);
+#endif
}
}
+#if _MIPS_SIM == _ABIN32
+ /* Now add space for saving the ra */
+ offset += SIZEOF_VOID_P;
+
+ /* change sign? */
+ offset = (offset + MIPS_STACK_ALIGNMENT - 1) & ~(MIPS_STACK_ALIGNMENT - 1);
+ cfg->stack_offset = offset;
+ cfg->arch.local_alloc_offset = cfg->stack_offset;
+#endif
}
void
}
in = call->args [i];
if (ainfo->regtype == RegTypeGeneral) {
+#if SIZEOF_REGISTER == 4
if (!t->byref && ((t->type == MONO_TYPE_I8) || (t->type == MONO_TYPE_U8))) {
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);
- } else if (!t->byref && (t->type == MONO_TYPE_R4)) {
+ } else
+#endif
+ if (!t->byref && (t->type == MONO_TYPE_R4)) {
int freg;
#if PROMOTE_R4_TO_R8
int dreg = mono_alloc_freg (cfg);
if (ainfo->size == 4) {
- MONO_EMIT_NEW_UNALU (cfg, OP_FCONV_TO_R4, dreg, in->dreg);
+ MONO_EMIT_NEW_UNALU (cfg, OP_MIPS_CVTSD, dreg, in->dreg);
} else {
MONO_INST_NEW (cfg, ins, OP_FMOVE);
ins->dreg = dreg;
#endif
call->stack_usage = cinfo->stack_usage;
cfg->param_area = MAX (cfg->param_area, cinfo->stack_usage);
- cfg->param_area = MAX (cfg->param_area, 16); /* a0-a3 always present */
+#if _MIPS_SIM == _ABIO32
+ /* a0-a3 always present */
+ cfg->param_area = MAX (cfg->param_area, 4 * SIZEOF_REGISTER);
+#endif
cfg->param_area = (cfg->param_area + MIPS_STACK_ALIGNMENT - 1) & ~(MIPS_STACK_ALIGNMENT - 1);
cfg->flags |= MONO_CFG_HAS_CALLS;
/*
dreg = mono_alloc_ireg (cfg);
MONO_EMIT_NEW_LOAD_MEMBASE (cfg, dreg, src->dreg, soffset);
mono_call_inst_add_outarg_reg (cfg, call, dreg, ainfo->reg + i, FALSE);
- soffset += sizeof (gpointer);
+ soffset += SIZEOF_REGISTER;
}
if (ovf_size != 0) {
- mini_emit_memcpy (cfg, mips_fp, doffset + soffset, src->dreg, soffset, ovf_size * sizeof (gpointer), 0);
+ mini_emit_memcpy (cfg, mips_fp, doffset, src->dreg, soffset, ovf_size * sizeof (gpointer), 0);
}
} else if (ainfo->regtype == RegTypeFP) {
int tmpr = mono_alloc_freg (cfg);
mono_method_signature (method)->ret);
if (!ret->byref) {
+#if (SIZEOF_REGISTER == 4)
if (ret->type == MONO_TYPE_I8 || ret->type == MONO_TYPE_U8) {
MonoInst *ins;
MONO_ADD_INS (cfg->cbb, ins);
return;
}
+#endif
if (ret->type == MONO_TYPE_R8) {
MONO_EMIT_NEW_UNALU (cfg, OP_FMOVE, cfg->ret->dreg, val->dreg);
return;
}
if (ret->type == MONO_TYPE_R4) {
- MONO_EMIT_NEW_UNALU (cfg, OP_FCONV_TO_R4, cfg->ret->dreg, val->dreg);
+ MONO_EMIT_NEW_UNALU (cfg, OP_MIPS_CVTSD, cfg->ret->dreg, val->dreg);
return;
}
}
break;
case OP_LADD_OVF_UN:
+ tmp1 = mono_alloc_ireg (cfg);
+ tmp2 = mono_alloc_ireg (cfg);
+
+ MONO_EMIT_NEW_BIALU (cfg, OP_IADD, ins->dreg+1, ins->sreg1+1, ins->sreg2+1);
+ MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLTU, tmp1, ins->dreg+1, ins->sreg1+1);
+ MONO_EMIT_NEW_BIALU (cfg, OP_IADD, ins->dreg+2, ins->sreg1+2, ins->sreg2+2);
+ MONO_EMIT_NEW_BIALU (cfg, OP_IADD, ins->dreg+2, tmp1, ins->dreg+2);
+ MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLTU, tmp2, ins->dreg+2, ins->sreg1+2);
+ MONO_EMIT_NEW_COMPARE_EXC (cfg, NE_UN, tmp2, mips_zero, "OverflowException");
+ ins->opcode = OP_NOP;
+ break;
+
case OP_LMUL_OVF:
case OP_LMUL_OVF_UN:
mono_print_ins (ins);
case OP_LBGT_UN:
case OP_LBLE_UN:
case OP_LBLT_UN:
+ mono_print_ins (ins);
+ g_assert_not_reached ();
+#if 0
case OP_LCONV_TO_R8_2:
case OP_LCONV_TO_R4_2:
case OP_LCONV_TO_R_UN_2:
+#endif
case OP_LCONV_TO_OVF_I4_2:
+ tmp1 = mono_alloc_ireg (cfg);
+
+ /* Overflows if reg2 != sign extension of reg1 */
+ MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SHR_IMM, tmp1, ins->sreg1, 31);
+ MONO_EMIT_NEW_COMPARE_EXC (cfg, NE_UN, ins->sreg2, tmp1, "OverflowException");
+ MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, ins->dreg, ins->sreg1);
+ ins->opcode = OP_NOP;
+ break;
+
case OP_LMIN_UN:
case OP_LMAX_UN:
case OP_LMIN:
ins->opcode = OP_NOP;
break;
+ case OP_IADD_OVF_UN:
+ tmp1 = mono_alloc_ireg (cfg);
+
+ MONO_EMIT_NEW_BIALU (cfg, OP_IADD, ins->dreg, ins->sreg1, ins->sreg2);
+ MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLTU, tmp1, ins->dreg, ins->sreg1);
+ MONO_EMIT_NEW_COMPARE_EXC (cfg, NE_UN, tmp1, mips_zero, "OverflowException");
+ ins->opcode = OP_NOP;
+ break;
+
case OP_ISUB_OVF:
tmp1 = mono_alloc_ireg (cfg);
tmp2 = mono_alloc_ireg (cfg);
MONO_EMIT_NEW_COMPARE_EXC (cfg, NE_UN, tmp1, mips_zero, "OverflowException");
ins->opcode = OP_NOP;
break;
-
- case OP_ICONV_TO_R_UN: {
- static const guint64 adjust_val = 0x4330000000000000ULL;
- int msw_reg = mono_alloc_ireg (cfg);
- int adj_reg = mono_alloc_freg (cfg);
- int tmp_reg = mono_alloc_freg (cfg);
- int basereg = mips_sp;
- int offset = -8;
-
- MONO_EMIT_NEW_ICONST (cfg, msw_reg, 0x43300000);
- if (!mips_is_imm16 (offset + 4)) {
- basereg = mono_alloc_ireg (cfg);
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_IADD_IMM, basereg, cfg->frame_reg, offset);
- }
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, basereg, offset, msw_reg);
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, basereg, offset + 4, ins->sreg1);
- MONO_EMIT_NEW_LOAD_R8 (cfg, adj_reg, &adjust_val);
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADR8_MEMBASE, tmp_reg, basereg, offset);
- MONO_EMIT_NEW_BIALU (cfg, OP_FSUB, ins->dreg, tmp_reg, adj_reg);
- ins->opcode = OP_NOP;
- break;
- }
- case OP_ICONV_TO_R4:
- case OP_ICONV_TO_R8: {
- /* FIXME: change precision for OP_ICONV_TO_R4 */
- static const guint64 adjust_val = 0x4330000080000000ULL;
- int msw_reg = mono_alloc_ireg (cfg);
- int xored = mono_alloc_ireg (cfg);
- int adj_reg = mono_alloc_freg (cfg);
- int tmp_reg = mono_alloc_freg (cfg);
- int basereg = mips_sp;
- int offset = -8;
-
- if (!mips_is_imm16 (offset + 4)) {
- basereg = mono_alloc_ireg (cfg);
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_IADD_IMM, basereg, cfg->frame_reg, offset);
- }
- MONO_EMIT_NEW_ICONST (cfg, msw_reg, 0x43300000);
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, basereg, offset, msw_reg);
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_XOR_IMM, xored, ins->sreg1, 0x80000000);
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, basereg, offset + 4, xored);
- MONO_EMIT_NEW_LOAD_R8 (cfg, adj_reg, (gpointer)&adjust_val);
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADR8_MEMBASE, tmp_reg, basereg, offset);
- MONO_EMIT_NEW_BIALU (cfg, OP_FSUB, ins->dreg, tmp_reg, adj_reg);
- if (ins->opcode == OP_ICONV_TO_R4)
- MONO_EMIT_NEW_UNALU (cfg, OP_FCONV_TO_R4, ins->dreg, ins->dreg);
- ins->opcode = OP_NOP;
- break;
- }
-#if 0
- case OP_CKFINITE: {
- int msw_reg = mono_alloc_ireg (cfg);
- int basereg = mips_sp;
- int offset = -8;
-
- if (!mips_is_imm16 (offset + 4)) {
- basereg = mono_alloc_ireg (cfg);
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_IADD_IMM, basereg, cfg->frame_reg, offset);
- }
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG, basereg, offset, ins->sreg1);
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, msw_reg, basereg, offset);
- MONO_EMIT_NEW_UNALU (cfg, OP_CHECK_FINITE, -1, msw_reg);
- MONO_EMIT_NEW_UNALU (cfg, OP_FMOVE, ins->dreg, ins->sreg1);
- ins->opcode = OP_NOP;
- break;
- }
-#endif
}
}
return OP_COMPARE;
case OP_ICOMPARE_IMM:
return OP_ICOMPARE;
+ case OP_LCOMPARE_IMM:
+ return OP_LCOMPARE;
case OP_ADDCC_IMM:
return OP_IADDCC;
case OP_ADC_IMM:
return OP_STOREI2_MEMBASE_REG;
case OP_STOREI4_MEMBASE_IMM:
return OP_STOREI4_MEMBASE_REG;
+ case OP_STOREI8_MEMBASE_IMM:
+ return OP_STOREI8_MEMBASE_REG;
}
return mono_op_imm_to_op (op);
}
switch (ins->opcode) {
case OP_COMPARE:
case OP_ICOMPARE:
+ case OP_LCOMPARE:
next = ins->next;
/* Branch opts can eliminate the branch */
if (!next || (!(MONO_IS_COND_BRANCH_OP (next) || MONO_IS_COND_EXC (next) || MONO_IS_SETCC (next)))) {
case OP_COMPARE_IMM:
case OP_ICOMPARE_IMM:
+ case OP_LCOMPARE_IMM:
next = ins->next;
/* Branch opts can eliminate the branch */
if (!next || (!(MONO_IS_COND_BRANCH_OP (next) || MONO_IS_COND_EXC (next) || MONO_IS_SETCC (next)))) {
ins->opcode = OP_COMPARE;
else if (ins->opcode == OP_ICOMPARE_IMM)
ins->opcode = OP_ICOMPARE;
+ else if (ins->opcode == OP_LCOMPARE_IMM)
+ ins->opcode = OP_LCOMPARE;
goto loop_start;
case OP_IDIV_UN_IMM:
}
break;
- case OP_FCOMPARE:
- next = ins->next;
- /* Branch opts can eliminate the branch */
- if (!next || (!(MONO_IS_COND_BRANCH_OP (next) || MONO_IS_COND_EXC (next) || MONO_IS_SETCC (next)))) {
- ins->opcode = OP_NOP;
- break;
- }
- g_assert(next);
-
- /*
- * remap compare/branch and compare/set
- * to MIPS specific opcodes.
- */
- ins->opcode = OP_NOP;
- next->opcode = map_to_mips_op (next->opcode);
- next->sreg1 = ins->sreg1;
- next->sreg2 = ins->sreg2;
- break;
-
case OP_SUB_IMM:
+ case OP_ISUB_IMM:
if (!mips_is_imm16 (-ins->inst_imm)) {
NEW_INS (cfg, last_ins, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
}
break;
- case OP_SBB_IMM:
- case OP_SUBCC_IMM:
- case OP_ADC_IMM:
- NEW_INS (cfg, last_ins, temp, OP_ICONST);
- temp->inst_c0 = ins->inst_imm;
- temp->dreg = mono_alloc_ireg (cfg);
- ins->sreg2 = temp->dreg;
- ins->opcode = map_to_reg_reg_op (ins->opcode);
- break;
-
case OP_MUL_IMM:
+ case OP_IMUL_IMM:
if (ins->inst_imm == 1) {
ins->opcode = OP_MOVE;
break;
ins->inst_imm = imm;
break;
}
- if (!mips_is_imm16 (ins->inst_imm)) {
- NEW_INS (cfg, last_ins, temp, OP_ICONST);
- temp->inst_c0 = ins->inst_imm;
- temp->dreg = mono_alloc_ireg (cfg);
- ins->sreg2 = temp->dreg;
- ins->opcode = map_to_reg_reg_op (ins->opcode);
- }
+ NEW_INS (cfg, last_ins, temp, OP_ICONST);
+ temp->inst_c0 = ins->inst_imm;
+ temp->dreg = mono_alloc_ireg (cfg);
+ ins->sreg2 = temp->dreg;
+ ins->opcode = map_to_reg_reg_op (ins->opcode);
+ break;
+
+ case OP_LOCALLOC_IMM:
+ NEW_INS (cfg, last_ins, temp, OP_ICONST);
+ temp->inst_c0 = ins->inst_imm;
+ temp->dreg = mono_alloc_ireg (cfg);
+ ins->sreg1 = temp->dreg;
+ ins->opcode = OP_LOCALLOC;
break;
case OP_LOAD_MEMBASE:
case OP_STOREI1_MEMBASE_IMM:
case OP_STOREI2_MEMBASE_IMM:
case OP_STOREI4_MEMBASE_IMM:
+ case OP_STOREI8_MEMBASE_IMM:
if (!ins->inst_imm) {
ins->sreg1 = mips_zero;
ins->opcode = map_to_reg_reg_op (ins->opcode);
}
break;
+ case OP_FCOMPARE:
+ next = ins->next;
+ /* Branch opts can eliminate the branch */
+ if (!next || (!(MONO_IS_COND_BRANCH_OP (next) || MONO_IS_COND_EXC (next) || MONO_IS_SETCC (next)))) {
+ ins->opcode = OP_NOP;
+ break;
+ }
+ g_assert(next);
+
+ /*
+ * remap compare/branch and compare/set
+ * to MIPS specific opcodes.
+ */
+ ins->opcode = OP_NOP;
+ next->opcode = map_to_mips_op (next->opcode);
+ next->sreg1 = ins->sreg1;
+ next->sreg2 = ins->sreg2;
+ break;
+
+#if 0
case OP_R8CONST:
case OP_R4CONST:
NEW_INS (cfg, last_ins, temp, OP_ICONST);
* later optimize to use lis + load_membase
*/
goto loop_start;
-
+#endif
case OP_IBEQ:
g_assert (ins_is_compare(last_ins));
INS_REWRITE(ins, OP_MIPS_BEQ, last_ins->sreg1, last_ins->sreg2);
case OP_COND_EXC_GE_UN:
case OP_COND_EXC_IGE_UN:
g_assert (ins_is_compare(last_ins));
- INS_REWRITE(ins, OP_MIPS_COND_EXC_GE, last_ins->sreg1, last_ins->sreg2);
+ INS_REWRITE(ins, OP_MIPS_COND_EXC_GE_UN, last_ins->sreg1, last_ins->sreg2);
MONO_DELETE_INS(bb, last_ins);
break;
case OP_COND_EXC_GT_UN:
case OP_COND_EXC_IGT_UN:
g_assert (ins_is_compare(last_ins));
- INS_REWRITE(ins, OP_MIPS_COND_EXC_GT, last_ins->sreg1, last_ins->sreg2);
+ INS_REWRITE(ins, OP_MIPS_COND_EXC_GT_UN, last_ins->sreg1, last_ins->sreg2);
MONO_DELETE_INS(bb, last_ins);
break;
case OP_COND_EXC_LT_UN:
case OP_COND_EXC_ILT_UN:
g_assert (ins_is_compare(last_ins));
- INS_REWRITE(ins, OP_MIPS_COND_EXC_LT, last_ins->sreg1, last_ins->sreg2);
+ INS_REWRITE(ins, OP_MIPS_COND_EXC_LT_UN, last_ins->sreg1, last_ins->sreg2);
MONO_DELETE_INS(bb, last_ins);
break;
static guchar*
emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size, gboolean is_signed)
{
- /* sreg is a float, dreg is an integer reg. mips_at is used a scratch */
+ /* sreg is a float, dreg is an integer reg. mips_at is used as scratch */
#if 1
mips_truncwd (code, mips_ftemp, sreg);
#else
/*
* emit_load_volatile_arguments:
*
- * Load volatile arguments from the stack to the original input registers.
+ * Load volatile arguments from the stack to the original input registers.
* Required before a tail call.
*/
static guint8 *
inst = cfg->args [i];
if (inst->opcode == OP_REGVAR) {
if (ainfo->regtype == RegTypeGeneral)
- mips_move (code, ainfo->reg, inst->dreg);
+ MIPS_MOVE (code, ainfo->reg, inst->dreg);
else if (ainfo->regtype == RegTypeFP)
g_assert_not_reached();
else if (ainfo->regtype == RegTypeBase) {
/* do nothing */
} else if (ainfo->regtype == RegTypeFP) {
g_assert (mips_is_imm16 (inst->inst_offset));
- if (ainfo->size == 8)
+ if (ainfo->size == 8) {
+#if _MIPS_SIM == _ABIO32
+ mips_lwc1 (code, ainfo->reg, inst->inst_basereg, inst->inst_offset+4);
+ mips_lwc1 (code, ainfo->reg+1, inst->inst_basereg, inst->inst_offset);
+#elif _MIPS_SIM == _ABIN32
mips_ldc1 (code, ainfo->reg, inst->inst_basereg, inst->inst_offset);
+#endif
+ }
else if (ainfo->size == 4)
mips_lwc1 (code, ainfo->reg, inst->inst_basereg, inst->inst_offset);
else
g_assert (mips_is_imm16 (inst->inst_offset + ainfo->size * sizeof (gpointer)));
for (i = 0; i < ainfo->size; ++i) {
mips_lw (code, ainfo->reg + i, inst->inst_basereg, doffset);
- doffset += sizeof (gpointer);
+ doffset += SIZEOF_REGISTER;
}
} else if (ainfo->regtype == RegTypeStructByAddr) {
g_assert (mips_is_imm16 (inst->inst_offset));
mips_sh (code, mips_temp, mips_at, ins->inst_destbasereg);
}
break;
+ case OP_STOREI8_MEMBASE_IMM:
+ mips_load_const (code, mips_temp, ins->inst_imm);
+ if (mips_is_imm16 (ins->inst_offset)) {
+ mips_sd (code, mips_temp, ins->inst_destbasereg, ins->inst_offset);
+ } else {
+ mips_load_const (code, mips_at, ins->inst_offset);
+ mips_sd (code, mips_temp, mips_at, ins->inst_destbasereg);
+ }
+ break;
case OP_STORE_MEMBASE_IMM:
case OP_STOREI4_MEMBASE_IMM:
mips_load_const (code, mips_temp, ins->inst_imm);
mips_sw (code, ins->sreg1, mips_at, 0);
}
break;
+ case OP_STOREI8_MEMBASE_REG:
+ if (mips_is_imm16 (ins->inst_offset)) {
+ mips_sd (code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset);
+ } else {
+ mips_load_const (code, mips_at, ins->inst_offset);
+ mips_addu (code, mips_at, mips_at, ins->inst_destbasereg);
+ mips_sd (code, ins->sreg1, mips_at, 0);
+ }
+ break;
case OP_LOADU4_MEM:
g_assert_not_reached ();
//x86_mov_reg_imm (code, ins->dreg, ins->inst_p0);
//x86_mov_reg_membase (code, ins->dreg, ins->dreg, 0, 4);
break;
+ case OP_LOADI8_MEMBASE:
+ if (mips_is_imm16 (ins->inst_offset)) {
+ mips_ld (code, ins->dreg, ins->inst_basereg, ins->inst_offset);
+ } else {
+ mips_load_const (code, mips_at, ins->inst_offset);
+ mips_addu (code, mips_at, mips_at, ins->inst_basereg);
+ mips_ld (code, ins->dreg, mips_at, 0);
+ }
+ break;
case OP_LOAD_MEMBASE:
case OP_LOADI4_MEMBASE:
case OP_LOADU4_MEMBASE:
case OP_IADD:
mips_addu (code, ins->dreg, ins->sreg1, ins->sreg2);
break;
+ case OP_LADD:
+ mips_daddu (code, ins->dreg, ins->sreg1, ins->sreg2);
+ break;
+
case OP_ADD_IMM:
case OP_IADD_IMM:
- if (mips_is_imm16 (ins->inst_imm)) {
- mips_addiu (code, ins->dreg, ins->sreg1, ins->inst_imm);
- } else {
- mips_load_const (code, mips_at, ins->inst_imm);
- mips_addu (code, ins->dreg, ins->sreg1, mips_at);
- }
+ g_assert (mips_is_imm16 (ins->inst_imm));
+ mips_addiu (code, ins->dreg, ins->sreg1, ins->inst_imm);
+ break;
+ case OP_LADD_IMM:
+ g_assert (mips_is_imm16 (ins->inst_imm));
+ mips_daddiu (code, ins->dreg, ins->sreg1, ins->inst_imm);
break;
+
case OP_ISUB:
mips_subu (code, ins->dreg, ins->sreg1, ins->sreg2);
break;
+ case OP_LSUB:
+ mips_dsubu (code, ins->dreg, ins->sreg1, ins->sreg2);
+ break;
+
case OP_ISUB_IMM:
case OP_SUB_IMM:
// we add the negated value
- if (mips_is_imm16 (-ins->inst_imm))
- mips_addi (code, ins->dreg, ins->sreg1, -ins->inst_imm);
- else {
- mips_load_const (code, mips_at, ins->inst_imm);
- mips_subu (code, ins->dreg, ins->sreg1, mips_at);
- }
+ g_assert (mips_is_imm16 (-ins->inst_imm));
+ mips_addiu (code, ins->dreg, ins->sreg1, -ins->inst_imm);
break;
+
+ case OP_LSUB_IMM:
+ // we add the negated value
+ g_assert (mips_is_imm16 (-ins->inst_imm));
+ mips_daddiu (code, ins->dreg, ins->sreg1, -ins->inst_imm);
+ break;
+
case OP_IAND:
+ case OP_LAND:
mips_and (code, ins->dreg, ins->sreg1, ins->sreg2);
break;
+
case OP_AND_IMM:
case OP_IAND_IMM:
- if (mips_is_imm16 (ins->inst_imm)) {
- mips_andi (code, ins->dreg, ins->sreg1, ins->inst_imm);
- } else {
- mips_load_const (code, mips_at, ins->inst_imm);
- mips_and (code, ins->dreg, ins->sreg1, mips_at);
- }
+ case OP_LAND_IMM:
+ g_assert (!(ins->inst_imm & 0xffff0000));
+ mips_andi (code, ins->dreg, ins->sreg1, ins->inst_imm);
break;
+
case OP_IDIV:
case OP_IREM: {
guint32 *divisor_is_m1;
/* */
mips_addiu (code, mips_at, mips_zero, 0xffff);
- divisor_is_m1 = (guint32 *)code;
+ divisor_is_m1 = (guint32 *)(void *)code;
mips_bne (code, ins->sreg2, mips_at, 0);
mips_nop (code);
mips_patch (divisor_is_m1, (guint32)code);
/* Put divide in branch delay slot (NOT YET) */
- divisor_is_zero = (guint32 *)code;
+ divisor_is_zero = (guint32 *)(void *)code;
mips_bne (code, ins->sreg2, mips_zero, 0);
mips_nop (code);
case OP_ISHR:
mips_srav (code, ins->dreg, ins->sreg1, ins->sreg2);
break;
+ case OP_LSHR:
+ mips_dsrav (code, ins->dreg, ins->sreg1, ins->sreg2);
+ break;
case OP_SHR_IMM:
case OP_ISHR_IMM:
mips_sra (code, ins->dreg, ins->sreg1, ins->inst_imm & 0x1f);
break;
+ case OP_LSHR_IMM:
+ mips_dsra (code, ins->dreg, ins->sreg1, ins->inst_imm & 0x3f);
+ break;
case OP_SHR_UN_IMM:
case OP_ISHR_UN_IMM:
mips_srl (code, ins->dreg, ins->sreg1, ins->inst_imm & 0x1f);
break;
+ case OP_LSHR_UN_IMM:
+ mips_dsrl (code, ins->dreg, ins->sreg1, ins->inst_imm & 0x3f);
+ break;
case OP_ISHR_UN:
mips_srlv (code, ins->dreg, ins->sreg1, ins->sreg2);
break;
+ case OP_LSHR_UN:
+ mips_dsrlv (code, ins->dreg, ins->sreg1, ins->sreg2);
+ break;
case OP_INOT:
+ case OP_LNOT:
mips_nor (code, ins->dreg, mips_zero, ins->sreg1);
break;
case OP_INEG:
mips_subu (code, ins->dreg, mips_zero, ins->sreg1);
break;
+ case OP_LNEG:
+ mips_dsubu (code, ins->dreg, mips_zero, ins->sreg1);
+ break;
case OP_IMUL:
-#if 1
+#if USE_MUL
mips_mul (code, ins->dreg, ins->sreg1, ins->sreg2);
#else
mips_mult (code, ins->sreg1, ins->sreg2);
mips_nop (code);
#endif
break;
- case OP_MUL_IMM:
- case OP_IMUL_IMM:
- mips_load_const (code, mips_at, ins->inst_imm);
-#if 1
- mips_mul (code, ins->dreg, ins->sreg1, mips_at);
-#else
- mips_mult (code, ins->sreg1, mips_at);
+#if SIZEOF_REGISTER == 8
+ case OP_LMUL:
+ mips_dmult (code, ins->sreg1, ins->sreg2);
mips_mflo (code, ins->dreg);
- mips_nop (code);
- mips_nop (code);
-#endif
break;
+#endif
case OP_IMUL_OVF: {
guint32 *patch;
mips_mult (code, ins->sreg1, ins->sreg2);
case OP_ICONST:
mips_load_const (code, ins->dreg, ins->inst_c0);
break;
+#if SIZEOF_REGISTER == 8
+ case OP_I8CONST:
+ mips_load_const (code, ins->dreg, ins->inst_c0);
+ break;
+#endif
case OP_AOTCONST:
mono_add_patch_info (cfg, offset, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
mips_load (code, ins->dreg, 0);
case OP_MIPS_MTC1S:
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);
+ break;
case OP_MIPS_MFC1S:
mips_mfc1 (code, ins->dreg, ins->sreg1);
break;
mips_dmtc1 (code, ins->dreg, ins->sreg1);
break;
case OP_MIPS_MFC1D:
+#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);
+#endif
break;
case OP_ICONV_TO_I4:
case OP_ICONV_TO_U4:
case OP_MOVE:
if (ins->dreg != ins->sreg1)
- mips_move (code, ins->dreg, ins->sreg1);
+ MIPS_MOVE (code, ins->dreg, ins->sreg1);
+ break;
+#if SIZEOF_REGISTER == 8
+ case OP_ZEXT_I4:
+ mips_dsll (code, ins->dreg, ins->sreg1, 32);
+ mips_dsrl (code, ins->dreg, ins->dreg, 32);
break;
+ case OP_SEXT_I4:
+ mips_dsll (code, ins->dreg, ins->sreg1, 32);
+ mips_dsra (code, ins->dreg, ins->dreg, 32);
+ break;
+#endif
case OP_SETLRET:
/* Get sreg1 into v1, sreg2 into v0 */
if (ins->sreg1 == mips_v0) {
if (ins->sreg1 != mips_at)
- mips_move (code, mips_at, ins->sreg1);
+ MIPS_MOVE (code, mips_at, ins->sreg1);
if (ins->sreg2 != mips_v0)
- mips_move (code, mips_v0, ins->sreg2);
- mips_move (code, mips_v1, mips_at);
+ MIPS_MOVE (code, mips_v0, ins->sreg2);
+ MIPS_MOVE (code, mips_v1, mips_at);
}
else {
if (ins->sreg2 != mips_v0)
- mips_move (code, mips_v0, ins->sreg2);
+ MIPS_MOVE (code, mips_v0, ins->sreg2);
if (ins->sreg1 != mips_v1)
- mips_move (code, mips_v1, ins->sreg1);
+ MIPS_MOVE (code, mips_v1, ins->sreg1);
}
break;
case OP_FMOVE:
mips_cvtsd (code, ins->dreg, ins->sreg1);
break;
case OP_FCONV_TO_R4:
- /* Convert from double to float */
- mips_cvtsd (code, ins->dreg, ins->sreg1);
#if 0
- /* and back again */
- mips_cvtds (code, ins->dreg, ins->dreg);
+ mips_cvtsd (code, ins->dreg, ins->sreg1);
+#else
+ /* Just a move, no precision change */
+ if (ins->dreg != ins->sreg1) {
+ mips_fmovd (code, ins->dreg, ins->sreg1);
+ }
#endif
break;
case OP_JMP:
case OP_VCALL2_REG:
case OP_VOIDCALL_REG:
case OP_CALL_REG:
- mips_move (code, mips_t9, ins->sreg1);
+ MIPS_MOVE (code, mips_t9, ins->sreg1);
break;
case OP_FCALL_MEMBASE:
case OP_LCALL_MEMBASE:
/* Round up ins->sreg1, mips_at ends up holding size */
mips_addiu (code, mips_at, ins->sreg1, 31);
- mips_andi (code, mips_at, mips_at, ~31);
+ mips_addiu (code, mips_temp, mips_zero, ~31);
+ mips_and (code, mips_at, mips_at, mips_temp);
mips_subu (code, mips_sp, mips_sp, mips_at);
+ g_assert (mips_is_imm16 (area_offset));
mips_addiu (code, ins->dreg, mips_sp, area_offset);
if (ins->flags & MONO_INST_INIT) {
mips_move (code, mips_temp, ins->dreg);
mips_sb (code, mips_zero, mips_temp, 0);
mips_addiu (code, mips_at, mips_at, -1);
- mips_bne (code, mips_at, mips_zero, -4);
+ mips_bne (code, mips_at, mips_zero, -3);
mips_addiu (code, mips_temp, mips_temp, 1);
}
break;
code = emit_unreserve_param_area (cfg, code);
if (ins->sreg1 != mips_v0)
- mips_move (code, mips_v0, ins->sreg1);
+ MIPS_MOVE (code, mips_v0, ins->sreg1);
if (mips_is_imm16 (spvar->inst_offset)) {
mips_lw (code, mips_ra, spvar->inst_basereg, spvar->inst_offset);
} else {
g_assert (ins->sreg1 != -1);
mips_sll (code, mips_at, ins->sreg1, 2);
if (1 || !(cfg->flags & MONO_CFG_HAS_CALLS))
- mips_move (code, mips_t8, mips_ra);
+ MIPS_MOVE (code, mips_t8, mips_ra);
mips_bgezal (code, mips_zero, 1); /* bal */
mips_nop (code);
mips_addu (code, mips_t9, mips_ra, mips_at);
/* Table is 16 or 20 bytes from target of bal above */
if (1 || !(cfg->flags & MONO_CFG_HAS_CALLS)) {
- mips_move (code, mips_ra, mips_t8);
+ MIPS_MOVE (code, mips_ra, mips_t8);
mips_lw (code, mips_t9, mips_t9, 20);
}
else
mips_addiu (code, ins->dreg, mips_zero, 1);
mips_beq (code, mips_at, mips_zero, 2);
mips_nop (code);
- mips_move (code, ins->dreg, mips_zero);
+ MIPS_MOVE (code, ins->dreg, mips_zero);
break;
case OP_CLT:
case OP_CLT_UN:
mips_addiu (code, ins->dreg, mips_zero, 1);
mips_bltz (code, mips_at, 2);
mips_nop (code);
- mips_move (code, ins->dreg, mips_zero);
+ MIPS_MOVE (code, ins->dreg, mips_zero);
break;
case OP_CGT:
case OP_CGT_UN:
mips_addiu (code, ins->dreg, mips_zero, 1);
mips_bgtz (code, mips_at, 2);
mips_nop (code);
- mips_move (code, ins->dreg, mips_zero);
+ MIPS_MOVE (code, ins->dreg, mips_zero);
break;
case OP_MIPS_COND_EXC_EQ:
mips_nop (code);
break;
+ case OP_MIPS_COND_EXC_GT_UN:
+ mips_sltu (code, mips_at, ins->sreg2, ins->sreg1);
+ throw = (guint32 *)(void *)code;
+ mips_bne (code, mips_at, mips_zero, 0);
+ mips_nop (code);
+ break;
+
case OP_MIPS_COND_EXC_LT:
mips_slt (code, mips_at, ins->sreg1, ins->sreg2);
throw = (guint32 *)(void *)code;
mips_nop (code);
break;
+ case OP_MIPS_COND_EXC_LT_UN:
+ mips_sltu (code, mips_at, ins->sreg1, ins->sreg2);
+ throw = (guint32 *)(void *)code;
+ mips_bne (code, mips_at, mips_zero, 0);
+ mips_nop (code);
+ break;
+
default:
/* Not yet implemented */
g_warning ("NYI conditional exception %s\n", mono_inst_name (ins->opcode));
/* floating point opcodes */
case OP_R8CONST:
+#if 0
if (((guint32)ins->inst_p0) & (1 << 15))
mips_lui (code, mips_at, mips_zero, (((guint32)ins->inst_p0)>>16)+1);
else
mips_lui (code, mips_at, mips_zero, (((guint32)ins->inst_p0)>>16));
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);
+#endif
break;
case OP_R4CONST:
if (((guint32)ins->inst_p0) & (1 << 15))
break;
case OP_STORER8_MEMBASE_REG:
if (mips_is_imm16 (ins->inst_offset)) {
-#if 1
- mips_sdc1 (code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset);
-#else
+#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);
+#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);
break;
case OP_LOADR8_MEMBASE:
if (mips_is_imm16 (ins->inst_offset)) {
-#if 1
- mips_ldc1 (code, ins->dreg, ins->inst_basereg, ins->inst_offset);
-#else
+#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);
+#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);
}
break;
case OP_STORER4_MEMBASE_REG:
+ g_assert (mips_is_imm16 (ins->inst_offset));
#if PROMOTE_R4_TO_R8
/* Need to convert ins->sreg1 to single-precision first */
mips_cvtsd (code, mips_ftemp, ins->sreg1);
#endif
- if (mips_is_imm16 (ins->inst_offset)) {
- mips_swc1 (code, mips_ftemp, ins->inst_destbasereg, ins->inst_offset);
- } else {
- mips_load_const (code, mips_at, ins->inst_offset);
- mips_addu (code, mips_at, mips_at, ins->inst_destbasereg);
- mips_swc1 (code, mips_ftemp, mips_at, 0);
- }
+ mips_swc1 (code, mips_ftemp, ins->inst_destbasereg, ins->inst_offset);
break;
case OP_MIPS_LWC1:
- if (mips_is_imm16 (ins->inst_offset)) {
- mips_lwc1 (code, ins->dreg, ins->inst_basereg, ins->inst_offset);
- } 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, 0);
- }
+ g_assert (mips_is_imm16 (ins->inst_offset));
+ mips_lwc1 (code, ins->dreg, ins->inst_basereg, ins->inst_offset);
break;
case OP_LOADR4_MEMBASE:
- if (mips_is_imm16 (ins->inst_offset)) {
- mips_lwc1 (code, ins->dreg, ins->inst_basereg, ins->inst_offset);
- } 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, 0);
- }
+ g_assert (mips_is_imm16 (ins->inst_offset));
+ mips_lwc1 (code, ins->dreg, ins->inst_basereg, ins->inst_offset);
#if PROMOTE_R4_TO_R8
/* Convert to double precision in place */
mips_cvtds (code, ins->dreg, ins->dreg);
case OP_FCONV_TO_U:
code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 4, FALSE);
break;
- case OP_FCONV_TO_I8:
- case OP_FCONV_TO_U8:
- g_assert_not_reached ();
- /* Implemented as helper calls */
- break;
- case OP_LCONV_TO_R_UN:
- g_assert_not_reached ();
- /* Implemented as helper calls */
- break;
- case OP_LCONV_TO_OVF_I:
- g_assert_not_reached ();
- /* split up by brg file */
- break;
case OP_SQRT:
mips_fsqrtd (code, ins->dreg, ins->sreg1);
break;
case OP_FNEG:
mips_fnegd (code, ins->dreg, ins->sreg1);
break;
- case OP_FREM:
- /* emulated */
- g_assert_not_reached ();
- break;
- case OP_FCOMPARE:
- g_assert_not_reached();
- break;
case OP_FCEQ:
mips_fcmpd (code, MIPS_FPU_EQ, ins->sreg1, ins->sreg2);
mips_addiu (code, ins->dreg, mips_zero, 1);
mips_fbtrue (code, 2);
mips_nop (code);
- mips_move (code, ins->dreg, mips_zero);
+ MIPS_MOVE (code, ins->dreg, mips_zero);
break;
case OP_FCLT:
mips_fcmpd (code, MIPS_FPU_LT, ins->sreg1, ins->sreg2);
mips_addiu (code, ins->dreg, mips_zero, 1);
mips_fbtrue (code, 2);
mips_nop (code);
- mips_move (code, ins->dreg, mips_zero);
+ MIPS_MOVE (code, ins->dreg, mips_zero);
break;
case OP_FCLT_UN:
/* Less than, or Unordered */
mips_addiu (code, ins->dreg, mips_zero, 1);
mips_fbtrue (code, 2);
mips_nop (code);
- mips_move (code, ins->dreg, mips_zero);
+ MIPS_MOVE (code, ins->dreg, mips_zero);
break;
case OP_FCGT:
mips_fcmpd (code, MIPS_FPU_ULE, ins->sreg1, ins->sreg2);
- mips_move (code, ins->dreg, mips_zero);
+ MIPS_MOVE (code, ins->dreg, mips_zero);
mips_fbtrue (code, 2);
mips_nop (code);
mips_addiu (code, ins->dreg, mips_zero, 1);
case OP_FCGT_UN:
/* Greater than, or Unordered */
mips_fcmpd (code, MIPS_FPU_OLE, ins->sreg1, ins->sreg2);
- mips_move (code, ins->dreg, mips_zero);
+ MIPS_MOVE (code, ins->dreg, mips_zero);
mips_fbtrue (code, 2);
mips_nop (code);
mips_addiu (code, ins->dreg, mips_zero, 1);
mips_fbtrue (code, 0);
mips_nop (code);
break;
- case OP_FBLT_UN:
+ case OP_MIPS_FBLT_UN:
mips_fcmpd (code, MIPS_FPU_ULT, ins->sreg1, ins->sreg2);
mips_nop (code);
if (ins->flags & MONO_INST_BRLABEL)
mips_nop (code);
break;
case OP_CKFINITE: {
- g_assert_not_reached();
-#if 0
- ppc_stfd (code, ins->sreg1, -8, ppc_sp);
- ppc_lwz (code, ppc_r11, -8, ppc_sp);
- ppc_rlwinm (code, ppc_r11, ppc_r11, 0, 1, 31);
- ppc_addis (code, ppc_r11, ppc_r11, -32752);
- ppc_rlwinmd (code, ppc_r11, ppc_r11, 1, 31, 31);
- EMIT_COND_SYSTEM_EXCEPTION (CEE_BEQ - CEE_BEQ, "ArithmeticException");
-#endif
+ guint32 *branch_patch;
+
+ mips_mfc1 (code, mips_at, ins->sreg1+1);
+ mips_srl (code, mips_at, mips_at, 16+4);
+ mips_andi (code, mips_at, mips_at, 2047);
+ mips_addiu (code, mips_at, mips_at, -2047);
+
+ branch_patch = (guint32 *)(void *)code;
+ mips_bne (code, mips_at, mips_zero, 0);
+ mips_nop (code);
+
+ EMIT_SYSTEM_EXCEPTION_NAME("ArithmeticException");
+ mips_patch (branch_patch, (guint32)code);
+ mips_fmovd (code, ins->dreg, ins->sreg1);
break;
}
case OP_JUMP_TABLE:
- mono_add_patch_info (cfg, offset, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
+ mono_add_patch_info (cfg, offset, (MonoJumpInfoType)ins->inst_c1, ins->inst_p0);
mips_load (code, ins->dreg, 0x0f0f0f0f);
break;
for (patch_info = ji; patch_info; patch_info = patch_info->next) {
unsigned char *ip = patch_info->ip.i + code;
- const unsigned char *target;
-
- target = mono_resolve_patch_target (method, domain, code, patch_info, run_cctors);
+ const unsigned char *target = NULL;
switch (patch_info->type) {
case MONO_PATCH_INFO_IP:
case MONO_PATCH_INFO_R4:
case MONO_PATCH_INFO_R8:
/* from OP_AOTCONST : lui + addiu */
+ target = mono_resolve_patch_target (method, domain, code, patch_info, run_cctors);
patch_lui_addiu ((guint32 *)(void *)ip, (guint32)target);
continue;
#if 0
/* everything is dealt with at epilog output time */
continue;
default:
+ target = mono_resolve_patch_target (method, domain, code, patch_info, run_cctors);
+ mips_patch ((guint32 *)(void *)ip, (guint32)target);
break;
}
- mips_patch ((guint32 *)(void *)ip, (guint32)target);
}
}
+#if 0
static
void
mono_trace_lmf_prolog (MonoLMF *new_lmf)
mono_trace_lmf_epilog (MonoLMF *old_lmf)
{
}
+#endif
/*
* Allow tracing to work with this interface (with an optional argument)
mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments)
{
guchar *code = p;
- int fp_stack_offset = 0;
+ int offset = cfg->arch.tracing_offset;
mips_nop (code);
mips_nop (code);
mips_nop (code);
- mips_sw (code, mips_a0, mips_sp, cfg->stack_offset + 0);
- mips_sw (code, mips_a1, mips_sp, cfg->stack_offset + 4);
- mips_sw (code, mips_a2, mips_sp, cfg->stack_offset + 8);
- mips_sw (code, mips_a3, mips_sp, cfg->stack_offset + 12);
-#if 0
-#if 0
- fp_stack_offset = MIPS_STACK_PARAM_OFFSET;
- mips_addiu (code, mips_sp, mips_sp, -64);
- mips_swc1 (code, mips_f12, mips_sp, fp_stack_offset + 16);
- mips_swc1 (code, mips_f13, mips_sp, fp_stack_offset + 20);
- mips_swc1 (code, mips_f14, mips_sp, fp_stack_offset + 24);
- mips_swc1 (code, mips_f15, mips_sp, fp_stack_offset + 28);
-#else
- mips_fmovs (code, mips_f22, mips_f12);
- mips_fmovs (code, mips_f23, mips_f13);
- mips_fmovs (code, mips_f24, mips_f14);
- mips_fmovs (code, mips_f25, mips_f15);
-#endif
+ /* For N32, need to know for each stack slot if it's an integer
+ * or float argument, and save/restore the appropriate register
+ */
+ MIPS_SW (code, mips_a0, mips_sp, offset + 0*SIZEOF_REGISTER);
+ MIPS_SW (code, mips_a1, mips_sp, offset + 1*SIZEOF_REGISTER);
+ MIPS_SW (code, mips_a2, mips_sp, offset + 2*SIZEOF_REGISTER);
+ MIPS_SW (code, mips_a3, mips_sp, offset + 3*SIZEOF_REGISTER);
+#if _MIPS_SIM == _ABIN32
+ MIPS_SW (code, mips_a4, mips_sp, offset + 4*SIZEOF_REGISTER);
+ MIPS_SW (code, mips_a5, mips_sp, offset + 5*SIZEOF_REGISTER);
+ MIPS_SW (code, mips_a6, mips_sp, offset + 6*SIZEOF_REGISTER);
+ MIPS_SW (code, mips_a7, mips_sp, offset + 7*SIZEOF_REGISTER);
#endif
+
mips_load_const (code, mips_a0, cfg->method);
- mips_addiu (code, mips_a1, mips_sp, cfg->stack_offset + fp_stack_offset);
+ mips_addiu (code, mips_a1, mips_sp, offset);
mips_load_const (code, mips_t9, func);
mips_jalr (code, mips_t9, mips_ra);
mips_nop (code);
- mips_lw (code, mips_a0, mips_sp, cfg->stack_offset + 0);
- mips_lw (code, mips_a1, mips_sp, cfg->stack_offset + 4);
- mips_lw (code, mips_a2, mips_sp, cfg->stack_offset + 8);
- mips_lw (code, mips_a3, mips_sp, cfg->stack_offset + 12);
-#if 0
-#if 0
- mips_lwc1 (code, mips_f12, mips_sp, fp_stack_offset + 16);
- mips_lwc1 (code, mips_f13, mips_sp, fp_stack_offset + 20);
- mips_lwc1 (code, mips_f14, mips_sp, fp_stack_offset + 24);
- mips_lwc1 (code, mips_f15, mips_sp, fp_stack_offset + 28);
- mips_addiu (code, mips_sp, mips_sp, 64);
-#else
- mips_fmovs (code, mips_f12, mips_f22);
- mips_fmovs (code, mips_f13, mips_f23);
- mips_fmovs (code, mips_f14, mips_f24);
- mips_fmovs (code, mips_f15, mips_f25);
-#endif
+ MIPS_LW (code, mips_a0, mips_sp, offset + 0*SIZEOF_REGISTER);
+ MIPS_LW (code, mips_a1, mips_sp, offset + 1*SIZEOF_REGISTER);
+ MIPS_LW (code, mips_a2, mips_sp, offset + 2*SIZEOF_REGISTER);
+ MIPS_LW (code, mips_a3, mips_sp, offset + 3*SIZEOF_REGISTER);
+#if _MIPS_SIM == _ABIN32
+ MIPS_LW (code, mips_a4, mips_sp, offset + 4*SIZEOF_REGISTER);
+ MIPS_LW (code, mips_a5, mips_sp, offset + 5*SIZEOF_REGISTER);
+ MIPS_LW (code, mips_a6, mips_sp, offset + 6*SIZEOF_REGISTER);
+ MIPS_LW (code, mips_a7, mips_sp, offset + 7*SIZEOF_REGISTER);
#endif
+
mips_nop (code);
mips_nop (code);
mips_nop (code);
return;
/* adjust cfg->stack_offset for account for down-spilling */
- cfg->stack_offset += 4;
+ cfg->stack_offset += SIZEOF_REGISTER;
/* re-align cfg->stack_offset if needed (due to var spilling) */
cfg->stack_offset = (cfg->stack_offset + MIPS_STACK_ALIGNMENT - 1) & ~(MIPS_STACK_ALIGNMENT - 1);
g_print ("\tspillvars allocated 0x%x -> 0x%x\n", cfg->arch.local_alloc_offset, cfg->stack_offset);
}
threshold = cfg->arch.local_alloc_offset;
- ra_offset = cfg->stack_offset - 4;
+ ra_offset = cfg->stack_offset - sizeof(gpointer);
if (cfg->verbose_level > 2) {
g_print ("\tra_offset %d/0x%x delta %d/0x%x\n", ra_offset, ra_offset, delta, delta);
}
g_print ("BASIC BLOCK %d:\n", bb->block_num);
}
MONO_BB_FOR_EACH_INS (bb, ins) {
+ int adj_c0 = 0;
+ int adj_imm = 0;
+
if (cfg->verbose_level > 2) {
mono_print_ins_index (ins_cnt, ins);
}
- if ((MONO_IS_LOAD_MEMBASE(ins) && (ins->inst_basereg == mips_fp)) || (MONO_IS_STORE_MEMBASE(ins) && (ins->dreg == mips_fp))) {
+ if (MONO_IS_LOAD_MEMBASE(ins) && (ins->inst_basereg == mips_fp))
+ adj_c0 = 1;
+ if (MONO_IS_STORE_MEMBASE(ins) && (ins->dreg == mips_fp))
+ adj_c0 = 1;
+ /* The following two catch FP spills */
+ if (MONO_IS_LOAD_MEMBASE(ins) && (ins->inst_basereg == mips_sp))
+ adj_c0 = 1;
+ if (MONO_IS_STORE_MEMBASE(ins) && (ins->dreg == mips_sp))
+ adj_c0 = 1;
+ if (((ins->opcode == OP_ADD_IMM) || (ins->opcode == OP_IADD_IMM)) && (ins->sreg1 == mips_fp))
+ adj_imm = 1;
+ if (adj_c0) {
if (ins->inst_c0 >= threshold) {
ins->inst_c0 += delta;
if (cfg->verbose_level > 2) {
}
g_assert (ins->inst_c0 != ra_offset);
}
+ if (adj_imm) {
+ if (ins->inst_imm >= threshold) {
+ ins->inst_imm += delta;
+ if (cfg->verbose_level > 2) {
+ g_print ("adj");
+ mono_print_ins_index (ins_cnt, ins);
+ }
+ }
+ g_assert (ins->inst_c0 != ra_offset);
+ }
+
++ins_cnt;
}
}
cfg->code_size = 768 + sig->param_count * 20;
code = cfg->native_code = g_malloc (cfg->code_size);
+ if (tracing) {
+#if _MIPS_SIM == _ABIO32
+ cfg->arch.tracing_offset = cfg->stack_offset;
+#elif _MIPS_SIM == _ABIN32
+ /* no stack slots by default for argument regs, reserve a special block */
+ cfg->arch.tracing_offset = cfg->stack_offset;
+ cfg->stack_offset += 8 * SIZEOF_REGISTER;
+#endif
+ }
+
/* adjust stackframe assignments for spillvars if needed */
mips_adjust_stackframe (cfg);
pos = cfg->arch.iregs_offset;
for (i = MONO_MAX_IREGS-1; i >= 0; --i) {
if (iregs_to_save & (1 << i)) {
- g_assert (pos < cfg->stack_usage - 4);
- mips_sw (code, i, mips_sp, pos);
- pos += sizeof (gulong);
+ g_assert (pos < cfg->stack_usage - sizeof(gpointer));
+ MIPS_SW (code, i, mips_sp, pos);
+ pos += SIZEOF_REGISTER;
}
}
}
#if SAVE_LMF
if (method->save_lmf) {
for (i = MONO_MAX_IREGS-1; i >= 0; --i) {
- mips_sw (code, i, mips_sp, lmf_offset + G_STRUCT_OFFSET(MonoLMF, iregs[i]));
+ MIPS_SW (code, i, mips_sp, lmf_offset + G_STRUCT_OFFSET(MonoLMF, iregs[i]));
}
}
#endif
#endif
#endif
if (cfg->frame_reg != mips_sp) {
- mips_move (code, cfg->frame_reg, mips_sp);
+ MIPS_MOVE (code, cfg->frame_reg, mips_sp);
#if SAVE_LMF
if (method->save_lmf)
- mips_sw (code, cfg->frame_reg, mips_sp,
+ MIPS_SW (code, cfg->frame_reg, mips_sp,
lmf_offset + G_STRUCT_OFFSET(MonoLMF, iregs[cfg->frame_reg]));
#endif
}
/* Do instrumentation before assigning regvars to registers. Because they may be assigned
* to the t* registers, which would be clobbered by the instrumentation calls.
*/
- if (tracing)
+ if (tracing) {
code = mono_arch_instrument_prolog (cfg, mono_trace_enter_method, code, TRUE);
+ }
/* load arguments allocated to register from the stack */
ArgInfo *ainfo = &cinfo->ret;
inst = cfg->vret_addr;
if (inst->opcode == OP_REGVAR)
- mips_move (code, inst->dreg, ainfo->reg);
+ MIPS_MOVE (code, inst->dreg, ainfo->reg);
else if (mips_is_imm16 (inst->inst_offset)) {
mips_sw (code, ainfo->reg, inst->inst_basereg, inst->inst_offset);
} else {
if (inst->opcode == OP_REGVAR) {
/* Argument ends up in a register */
if (ainfo->regtype == RegTypeGeneral)
- mips_move (code, inst->dreg, ainfo->reg);
+ MIPS_MOVE (code, inst->dreg, ainfo->reg);
else if (ainfo->regtype == RegTypeFP) {
g_assert_not_reached();
#if 0
mips_sw (code, ainfo->reg, inst->inst_basereg, inst->inst_offset);
break;
case 8:
+#if (SIZEOF_REGISTER == 4)
mips_sw (code, ainfo->reg, inst->inst_basereg, inst->inst_offset);
mips_sw (code, ainfo->reg + 1, inst->inst_basereg, inst->inst_offset + 4);
+#elif (SIZEOF_REGISTER == 8)
+ mips_sd (code, ainfo->reg, inst->inst_basereg, inst->inst_offset);
+#endif
break;
default:
g_assert_not_reached ();
} else if (ainfo->regtype == RegTypeFP) {
g_assert (mips_is_imm16 (inst->inst_offset));
if (ainfo->size == 8) {
-#if 1
- mips_sdc1 (code, ainfo->reg, inst->inst_basereg, inst->inst_offset);
-#else
+#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);
+#elif _MIPS_SIM == _ABIN32
+ mips_sdc1 (code, ainfo->reg, inst->inst_basereg, inst->inst_offset);
#endif
}
else if (ainfo->size == 4)
g_assert (mips_is_imm16 (inst->inst_offset + ainfo->size * sizeof (gpointer)));
/* Push the argument registers into their stack slots */
for (i = 0; i < ainfo->size; ++i) {
- mips_sw (code, ainfo->reg + i, inst->inst_basereg, doffset);
- doffset += sizeof (gpointer);
+ MIPS_SW (code, ainfo->reg + i, inst->inst_basereg, doffset);
+ doffset += SIZEOF_REGISTER;
}
} else if (ainfo->regtype == RegTypeStructByAddr) {
g_assert (mips_is_imm16 (inst->inst_offset));
/* save method info */
mips_load_const (code, mips_at, method);
mips_sw (code, mips_at, mips_sp, lmf_offset + G_STRUCT_OFFSET(MonoLMF, method));
- mips_sw (code, mips_sp, mips_sp, lmf_offset + G_STRUCT_OFFSET(MonoLMF, ebp));
+ MIPS_SW (code, mips_sp, mips_sp, lmf_offset + G_STRUCT_OFFSET(MonoLMF, ebp));
/* save the current IP */
mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_IP, NULL);
else
save_mode = SAVE_NONE;
break;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- save_mode = SAVE_TWO;
- break;
case MONO_TYPE_R4:
case MONO_TYPE_R8:
save_mode = SAVE_FP;
case MONO_TYPE_VALUETYPE:
save_mode = SAVE_STRUCT;
break;
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+#if SIZEOF_REGISTER == 4
+ save_mode = SAVE_TWO;
+#elif SIZEOF_REGISTER == 8
+ save_mode = SAVE_ONE;
+#endif
+ break;
default:
save_mode = SAVE_ONE;
break;
switch (save_mode) {
case SAVE_TWO:
mips_sw (code, mips_v0, mips_sp, save_offset);
- mips_sw (code, mips_v1, mips_sp, save_offset + 4);
+ mips_sw (code, mips_v1, mips_sp, save_offset + SIZEOF_REGISTER);
if (enable_arguments) {
- mips_move (code, mips_a1, mips_v0);
- mips_move (code, mips_a2, mips_v1);
+ MIPS_MOVE (code, mips_a1, mips_v0);
+ MIPS_MOVE (code, mips_a2, mips_v1);
}
break;
case SAVE_ONE:
- mips_sw (code, mips_v0, mips_sp, save_offset);
+ MIPS_SW (code, mips_v0, mips_sp, save_offset);
if (enable_arguments) {
- mips_move (code, mips_a1, mips_v0);
+ MIPS_MOVE (code, mips_a1, mips_v0);
}
break;
case SAVE_FP:
mips_sdc1 (code, mips_f0, mips_sp, save_offset);
mips_ldc1 (code, mips_f12, mips_sp, save_offset);
mips_lw (code, mips_a0, mips_sp, save_offset);
- mips_lw (code, mips_a1, mips_sp, save_offset+4);
+ mips_lw (code, mips_a1, mips_sp, save_offset + SIZEOF_REGISTER);
break;
case SAVE_STRUCT:
case SAVE_NONE:
switch (save_mode) {
case SAVE_TWO:
mips_lw (code, mips_v0, mips_sp, save_offset);
- mips_lw (code, mips_v1, mips_sp, save_offset + 4);
+ mips_lw (code, mips_v1, mips_sp, save_offset + SIZEOF_REGISTER);
break;
case SAVE_ONE:
- mips_lw (code, mips_v0, mips_sp, save_offset);
+ MIPS_LW (code, mips_v0, mips_sp, save_offset);
break;
case SAVE_FP:
mips_ldc1 (code, mips_f0, mips_sp, save_offset);
mono_arch_emit_epilog_sub (MonoCompile *cfg, guint8 *code)
{
MonoMethod *method = cfg->method;
- int pos, i;
+ int pos = 0, i;
int max_epilog_size = 16 + 20*4;
guint32 iregs_to_restore;
#if SAVE_FP_REGS
}
pos = cfg->arch.iregs_offset;
if (cfg->frame_reg != mips_sp) {
- mips_move (code, mips_sp, cfg->frame_reg);
+ MIPS_MOVE (code, mips_sp, cfg->frame_reg);
}
#if SAVE_ALL_REGS
iregs_to_restore = MONO_ARCH_CALLEE_SAVED_REGS;
if (iregs_to_restore) {
for (i = MONO_MAX_IREGS-1; i >= 0; --i) {
if (iregs_to_restore & (1 << i)) {
- mips_lw (code, i, mips_sp, pos);
- pos += sizeof (gulong);
+ MIPS_LW (code, i, mips_sp, pos);
+ pos += SIZEOF_REGISTER;
}
}
}
if (fregs_to_restore & (1 << i)) {
g_assert (pos < cfg->stack_usage - MIPS_STACK_ALIGNMENT);
mips_lwc1 (code, i, mips_sp, pos);
- pos += sizeof (gulong);
+ pos += FREG_SIZE
}
}
}
}
/* remove once throw_exception_by_name is eliminated */
+#if 0
static int
exception_id_by_name (const char *name)
{
g_error ("Unknown intrinsic exception %s\n", name);
return 0;
}
+#endif
void
mono_arch_emit_exceptions (MonoCompile *cfg)
} else {
/* the initial load of the vtable address */
size += 8;
- code = mono_code_manager_reserve (domain->code_mp, size);
+ code = mono_domain_code_reserve (domain, size);
}
start = code;
if (!fail_tramp)