When running in a linked environment, this file might not exist
[mono.git] / mono / mini / mini-mips.h
index 5b45f29a6b5a178e8b51ebaf59338dac225c9903..ce8600ed62908db03a80037a802cf48e943b17cc 100644 (file)
@@ -1,8 +1,8 @@
 #ifndef __MONO_MINI_MIPS_H__
 #define __MONO_MINI_MIPS_H__
 
-#include <mono/arch/mips/mips-codegen.h>
 #include <glib.h>
+#include <mono/arch/mips/mips-codegen.h>
 
 #if _MIPS_SIM == _ABIO32
 /* o32 fully supported */
 #define MONO_SAVED_FREGS 32
 
 
-#if _MIPS_SIM == _ABIO32
+#if SIZEOF_REGISTER == 4
 #define IREG_SIZE      4
 typedef guint32                mips_ireg;
 #define FREG_SIZE      4
 typedef gfloat         mips_freg;
-#elif _MIPS_SIM == _ABIN32
+
+#elif SIZEOF_REGISTER == 8
+
 #define IREG_SIZE      8
 typedef guint64                mips_ireg;
 #define FREG_SIZE      8
 typedef gdouble                mips_freg;
+
+#else
+#error Unknown REGISTER_SIZE
 #endif
 
 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
@@ -54,6 +59,7 @@ typedef gdouble               mips_freg;
 
 #define MIPS_V_REGS    ((1 << mips_v0) | \
                         (1 << mips_v1))
+#if _MIPS_SIM == _ABIO32
 #define MIPS_T_REGS    ((1 << mips_t0) | \
                         (1 << mips_t1) | \
                         (1 << mips_t2) | \
@@ -62,6 +68,14 @@ typedef gdouble              mips_freg;
                         (1 << mips_t5) | \
                         (1 << mips_t6) | \
                         (1 << mips_t7))
+#elif _MIPS_SIM == _ABIN32
+#define MIPS_T_REGS    ((1 << mips_t0) | \
+                        (1 << mips_t1) | \
+                        (1 << mips_t2) | \
+                        (1 << mips_t3))
+#endif
+
+
 #define MIPS_S_REGS    ((1 << mips_s0) | \
                         (1 << mips_s1) | \
                         (1 << mips_s2) | \
@@ -71,10 +85,21 @@ typedef gdouble             mips_freg;
                         (1 << mips_s6) | \
                         (1 << mips_s7) | \
                         (1 << mips_fp))
+#if _MIPS_SIM == _ABIO32
 #define MIPS_A_REGS    ((1 << mips_a0) | \
                         (1 << mips_a1) | \
                         (1 << mips_a2) | \
                         (1 << mips_a3))
+#elif _MIPS_SIM == _ABIN32
+#define MIPS_A_REGS    ((1 << mips_a0) | \
+                        (1 << mips_a1) | \
+                        (1 << mips_a2) | \
+                        (1 << mips_a3) | \
+                        (1 << mips_a4) | \
+                        (1 << mips_a5) | \
+                        (1 << mips_a6) | \
+                        (1 << mips_a7))
+#endif
 
 #define mips_temp mips_t8
 
@@ -212,14 +237,22 @@ typedef struct MonoCompileArch {
        guint           local_alloc_offset;
        guint           spillvar_offset;
        guint           spillvar_offset_float;
+       guint           tracing_offset;
+       guint           long_branch;
 } MonoCompileArch;
 
+#if SIZEOF_REGISTER == 4
 #define MONO_ARCH_EMULATE_FCONV_TO_I8 1
 #define MONO_ARCH_EMULATE_LCONV_TO_R8 1
 #define MONO_ARCH_EMULATE_LCONV_TO_R4 1
 #define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
 #define MONO_ARCH_EMULATE_FREM 1
 #define MONO_ARCH_BIGMUL_INTRINS 1
+#endif
+
+#if SIZEOF_REGISTER == 8
+#define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS
+#endif
 
 #define MIPS_RET_ADDR_OFFSET   (-sizeof(gpointer))
 #define MIPS_FP_ADDR_OFFSET    (-8)
@@ -240,12 +273,11 @@ typedef struct MonoCompileArch {
 #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_COMMON_VTABLE_TRAMPOLINE 1
+#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
@@ -264,6 +296,8 @@ typedef struct MonoCompileArch {
 #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)
 
@@ -327,6 +361,8 @@ typedef struct {
                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
 
@@ -334,153 +370,6 @@ typedef struct {
 
 #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); \
@@ -557,4 +446,6 @@ typedef struct {
        int offset;
 } MonoMIPSArgInfo;
 
+extern guint8 *mips_emit_load_const(guint8 *code, int dreg, mgreg_t v);
+
 #endif /* __MONO_MINI_MIPS_H__ */