#include <glib.h>
#include <mono/arch/mips/mips-codegen.h>
+#include <mono/utils/mono-context.h>
#if _MIPS_SIM == _ABIO32
/* o32 fully supported */
gulong magic;
};
-/* we define our own structure and we'll copy the data
- * from sigcontext/ucontext/mach when we need it.
- * This also makes us save stack space and time when copying
- * We might also want to add an additional field to propagate
- * the original context from the signal handler.
- */
-typedef struct {
- gpointer sc_pc;
- mips_ireg sc_regs [MONO_SAVED_GREGS];
- mips_freg sc_fpregs [MONO_SAVED_FREGS];
-} MonoContext;
-
typedef struct MonoCompileArch {
+ gpointer cinfo;
guint iregs_offset;
guint lmf_offset;
guint local_alloc_offset;
guint spillvar_offset;
guint spillvar_offset_float;
guint tracing_offset;
+ guint long_branch;
} MonoCompileArch;
#if SIZEOF_REGISTER == 4
#define MIPS_LAST_FPARG_REG mips_f19
#endif
-//#define MONO_ARCH_HAVE_IMT 1
-//#define MONO_ARCH_IMT_REG mips_v0 /* XXX */
+#define MONO_ARCH_HAVE_IMT 1
+#define MONO_ARCH_IMT_REG mips_t0
-//#define MONO_ARCH_VTABLE_REG mips_v0 /* XXX */
-#define MONO_ARCH_RGCTX_REG mips_v0 /* XXX */
+#define MONO_ARCH_VTABLE_REG mips_t0
+#define MONO_ARCH_RGCTX_REG mips_t0
#define MONO_ARCH_HAVE_DECOMPOSE_OPTS 1
#define MONO_ARCH_HAVE_DECOMPOSE_LONG_OPTS 1
#define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1
+#define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1
+#define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1
+#define MONO_ARCH_HAVE_XP_UNWIND 1
/* XXX - a mystery, but it works */
#define MONO_GET_CONTEXT \
/* set the next to 0 once inssel-mips.brg is updated */
#define MIPS_PASS_STRUCTS_BY_VALUE 1
-#define MIPS_SMALL_RET_STRUCT_IN_REG 0
#define MONO_ARCH_USE_SIGACTION
#define MONO_ARCH_NEED_DIV_CHECK 1
#define MONO_ARCH_NO_IOV_CHECK 1
+#define MONO_ARCH_THIS_AS_FIRST_ARG 1
+
#define MIPS_NUM_REG_ARGS (MIPS_LAST_ARG_REG-MIPS_FIRST_ARG_REG+1)
#define MIPS_NUM_REG_FPARGS (MIPS_LAST_FPARG_REG-MIPS_FIRST_FPARG_REG+1)
-/* we have the stack pointer, not the base pointer in sigcontext */
-#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->sc_pc = (int)(ip); } while (0);
-#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->sc_regs[mips_fp] = (int)(bp); } while (0);
-#define MONO_CONTEXT_SET_SP(ctx,sp) do { (ctx)->sc_regs[mips_sp] = (int)(sp); } while (0);
-
-#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->sc_pc))
-#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->sc_regs[mips_fp]))
-#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sc_regs[mips_sp]))
-
typedef struct {
unsigned long zero;
unsigned long at; /* assembler temp */
MONO_CONTEXT_SET_SP ((ctx), MONO_CONTEXT_GET_BP (ctx)); \
} while (0)
+#define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf) do { (lmf)->ebp = -1; } while (0)
+
/* re-attaches with gdb - sometimes causes executable to hang */
#undef HAVE_BACKTRACE_SYMBOLS
#define MONO_ZERO_REG mips_zero
-#define MONO_EMIT_NEW_BRANCH_UNREG_LABEL(cfg,op,sr1,label) do { \
- MonoInst *inst; \
- inst = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \
- inst->opcode = op; \
- inst->sreg1 = sr1; \
- inst->inst_i0 = label; \
- inst->flags = MONO_INST_BRLABEL; \
- mono_bblock_add_inst ((cfg)->cbb, inst); \
- } while (0)
-
-#define MONO_EMIT_NEW_BRANCH_BIREG_LABEL(cfg,op,sr1,sr2,label) do { \
- MonoInst *inst; \
- inst = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \
- inst->opcode = op; \
- inst->sreg1 = sr1; \
- inst->sreg2 = sr2; \
- inst->inst_i0 = label; \
- inst->flags = MONO_INST_BRLABEL; \
- mono_bblock_add_inst ((cfg)->cbb, inst); \
- } while (0)
-
-#define MONO_EMIT_NEW_BRANCH_NONZERO_LABEL(cfg,op,sr1,targetbb) do { \
- MonoInst *inst; \
- MonoInst *target_label; \
- target_label = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \
- target_label->opcode = OP_LABEL; \
- target_label->next = (targetbb)->code; \
- target_label->inst_c0 = (targetbb)->native_offset; \
- (targetbb)->code = target_label; \
- inst = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \
- inst->opcode = op; \
- (inst)->sreg1 = sr1; \
- (inst)->sreg2 = sr2; \
- inst->inst_i0 = target_label; \
- inst->flags = MONO_INST_BRLABEL; \
- mono_bblock_add_inst ((cfg)->cbb, inst); \
- } while (0)
-
-#define MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK(cfg,op,sr1,sr2,targetbb) do { \
- MonoInst *inst; \
- MonoInst *target_label; \
- target_label = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \
- target_label->opcode = OP_LABEL; \
- target_label->next = (targetbb)->code; \
- target_label->inst_c0 = (targetbb)->native_offset; \
- (targetbb)->code = target_label; \
- inst = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \
- inst->opcode = op; \
- (inst)->sreg1 = sr1; \
- (inst)->sreg2 = sr2; \
- inst->inst_i0 = target_label; \
- inst->flags = MONO_INST_BRLABEL; \
- mono_bblock_add_inst ((cfg)->cbb, inst); \
- } while (0)
-
-#ifndef MONO_EMIT_NEW_COMPARE_BRANCH_LABEL
-#define MONO_EMIT_NEW_COMPARE_BRANCH_LABEL(cfg, cmp_op, sreg1, sreg2, label) \
- do { \
- switch (cmp_op) { \
- case CEE_BEQ: \
- MONO_EMIT_NEW_BRANCH_BIREG_LABEL(cfg, OP_MIPS_BEQ, sreg1, sreg2, label); \
- break; \
- case CEE_BNE_UN: \
- MONO_EMIT_NEW_BRANCH_BIREG_LABEL(cfg, OP_MIPS_BNE, sreg1, sreg2, label); \
- break; \
- case CEE_BGE: \
- MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLT, mips_at, sreg1, sreg2); \
- MONO_EMIT_NEW_BIALU_IMM (s, OP_IXOR, mips_at, mips_at, 1); \
- MONO_EMIT_NEW_BRANCH_BIREG_LABEL(cfg, OP_MIPS_BNE, mips_at, mips_zero, label); \
- break; \
- case CEE_BGE_UN: \
- MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLTU, mips_at, sreg1, sreg2); \
- MONO_EMIT_NEW_BIALU_IMM (s, OP_IXOR, mips_at, mips_at, 1); \
- MONO_EMIT_NEW_BRANCH_BIREG_LABEL(cfg, OP_MIPS_BNE, mips_at, mips_zero, label); \
- break; \
- case CEE_BGT: \
- MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLT, mips_at, sreg2, sreg1); \
- MONO_EMIT_NEW_BRANCH_BIREG_LABEL(cfg, OP_MIPS_BNE, mips_at, mips_zero, label); \
- break; \
- case CEE_BGT_UN: \
- MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLTU, mips_at, sreg2, sreg1); \
- MONO_EMIT_NEW_BRANCH_BIREG_LABEL(cfg, OP_MIPS_BNE, mips_at, mips_zero, label); \
- break; \
- case CEE_BLT: \
- MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLT, mips_at, sreg1, sreg2); \
- MONO_EMIT_NEW_BRANCH_BIREG_LABEL(cfg, OP_MIPS_BNE, mips_at, mips_zero, label); \
- break; \
- case CEE_BLT_UN: \
- MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLTU, mips_at, sreg1, sreg2); \
- MONO_EMIT_NEW_BRANCH_BIREG_LABEL(cfg, OP_MIPS_BNE, mips_at, mips_zero, label); \
- break; \
- default: \
- g_assert_not_reached(); \
- } \
- } while (0)
-#endif
-
-#ifndef MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL
-#define MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL(cfg, cmp_op, sreg1, imm, label) \
- do { \
- guint32 cmp_reg; \
- if (!(imm)) { \
- cmp_reg = mips_zero; \
- } \
- else { \
- cmp_reg = mips_at; \
- MONO_EMIT_NEW_ICONST (cfg, cmp_reg, (imm)); \
- } \
- MONO_EMIT_NEW_COMPARE_BRANCH_LABEL(cfg, cmp_op, sreg1, cmp_reg, label); \
- } while (0)
-#endif
-
-#ifndef MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK
-#define MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK(cfg, cmp_op, sreg1, sreg2, block) \
- do { \
- switch (cmp_op) { \
- case CEE_BEQ: \
- MONO_EMIT_NEW_BRANCH_BIREG_BLOCK (cfg, OP_MIPS_BEQ, sreg1, sreg2, block); \
- break; \
- case CEE_BNE_UN: \
- MONO_EMIT_NEW_BRANCH_BIREG_BLOCK (cfg, OP_MIPS_BNE, sreg1, sreg2, block); \
- break; \
- case CEE_BLT_UN: \
- MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLTU, mips_at, sreg1, sreg2); \
- MONO_EMIT_NEW_BRANCH_BIREG_BLOCK (cfg, OP_MIPS_BNE, mips_at, mips_zero, block); \
- break; \
- default: \
- g_assert_not_reached (); \
- } \
- } while (0)
-#endif
-
-#ifndef MONO_EMIT_NEW_COMPARE_IMM_BRANCH_BLOCK
-#define MONO_EMIT_NEW_COMPARE_IMM_BRANCH_BLOCK(cfg, cmp_op, sreg1, imm, block) \
- do { \
- guint32 cmp_reg; \
- if (!(imm)) { \
- cmp_reg = mips_zero; \
- } \
- else { \
- cmp_reg = mips_at; \
- MONO_EMIT_NEW_ICONST (cfg, cmp_reg, (imm)); \
- } \
- MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK(cfg, cmp_op, sreg1, cmp_reg, block); \
- } while (0)
-#endif
-
#define MONO_EMIT_NEW_MIPS_COND_EXC(cfg,cond,sr1,sr2,name) do { \
MonoInst *inst; \
MONO_INST_NEW ((cfg), (inst), cond); \