[jit] Fix some issues with constrained gsharedvt calls to be able to handle some...
[mono.git] / mono / mini / mini-codegen.c
index 8214be4db75717fc6a8ddd34a2fed3cdd4d6debd..ab064a1c6ff01117cc00f4b9b9af754a86c197d7 100644 (file)
@@ -101,6 +101,7 @@ static const int regbank_move_ops [] = {
 
 #define regmask(reg) (((regmask_t)1) << (reg))
 
+#ifdef MONO_ARCH_USE_SHARED_FP_SIMD_BANK
 static const regmask_t regbank_callee_saved_regs [] = {
        MONO_ARCH_CALLEE_SAVED_REGS,
        MONO_ARCH_CALLEE_SAVED_FREGS,
@@ -108,6 +109,7 @@ static const regmask_t regbank_callee_saved_regs [] = {
        MONO_ARCH_CALLEE_SAVED_REGS,
        MONO_ARCH_CALLEE_SAVED_XREGS,
 };
+#endif
 
 static const regmask_t regbank_callee_regs [] = {
        MONO_ARCH_CALLEE_REGS,
@@ -684,6 +686,7 @@ mono_print_ins_index (int i, MonoInst *ins)
        case OP_GC_LIVENESS_USE:
                printf (" R%d", (int)ins->inst_c1);
                break;
+       case OP_IL_SEQ_POINT:
        case OP_SEQ_POINT:
                printf (" il: %x", (int)ins->inst_imm);
                break;
@@ -1063,8 +1066,9 @@ assign_reg (MonoCompile *cfg, MonoRegState *rs, int reg, int hreg, int bank)
        else {
                g_assert (reg >= MONO_MAX_IREGS);
                g_assert (hreg < MONO_MAX_IREGS);
-#ifndef TARGET_ARM
+#if !defined(TARGET_ARM) && !defined(TARGET_ARM64)
                /* this seems to trigger a gcc compilation bug sometime (hreg is 0) */
+               /* On arm64, rgctx_reg is a global hreg, and it is used to pass an argument */
                g_assert (! is_global_ireg (hreg));
 #endif
 
@@ -1122,7 +1126,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                desc_to_fixed_reg_inited = TRUE;
 
                /* Validate the cpu description against the info in mini-ops.h */
-#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_ARM)
+#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_ARM) || defined(TARGET_ARM64)
                for (i = OP_LOAD; i < OP_LAST; ++i) {
                        const char *ispec;
 
@@ -1170,6 +1174,8 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
         * bblock.
         */
        for (ins = bb->code; ins; ins = ins->next) {
+               gboolean modify = FALSE;
+
                spec = ins_get_spec (ins->opcode);
 
                if ((ins->dreg != -1) && (ins->dreg < max)) {
@@ -1195,12 +1201,14 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
 #if SIZEOF_REGISTER == 4
                                if (MONO_ARCH_INST_IS_REGPAIR (spec [MONO_INST_SRC1 + j])) {
                                        sregs [j]++;
+                                       modify = TRUE;
                                        memset (&reginfo [sregs [j] + 1], 0, sizeof (RegTrack));
                                }
 #endif
                        }
                }
-               mono_inst_set_src_registers (ins, sregs);
+               if (modify)
+                       mono_inst_set_src_registers (ins, sregs);
        }
 
        /*if (cfg->opt & MONO_OPT_COPYPROP)
@@ -1449,6 +1457,8 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                                                if (k != j)
                                                        sreg_masks [k] &= ~ (regmask (dest_sreg));
                                        }
+                                       /* See below */
+                                       dreg_mask &= ~ (regmask (dest_sreg));
                                } else {
                                        val = rs->vassign [sreg];
                                        if (val == -1) {
@@ -1468,7 +1478,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                                                                sreg_masks [k] &= ~ (regmask (dest_sreg));
                                                }
                                                /* 
-                                                * Prevent the dreg from being allocate to dest_sreg 
+                                                * Prevent the dreg from being allocated to dest_sreg
                                                 * too, since it could force sreg1 to be allocated to 
                                                 * the same reg on x86.
                                                 */
@@ -2345,6 +2355,8 @@ mono_opcode_to_cond (int opcode)
        case OP_LCEQ:
        case OP_FBEQ:
        case OP_FCEQ:
+       case OP_RBEQ:
+       case OP_RCEQ:
        case OP_COND_EXC_EQ:
        case OP_COND_EXC_IEQ:
        case OP_CMOV_IEQ:
@@ -2383,6 +2395,8 @@ mono_opcode_to_cond (int opcode)
        case OP_LCLT:
        case OP_FBLT:
        case OP_FCLT:
+       case OP_RBLT:
+       case OP_RCLT:
        case OP_COND_EXC_LT:
        case OP_COND_EXC_ILT:
        case OP_CMOV_ILT:
@@ -2395,6 +2409,8 @@ mono_opcode_to_cond (int opcode)
        case OP_LCGT:
        case OP_FBGT:
        case OP_FCGT:
+       case OP_RBGT:
+       case OP_RCGT:
        case OP_COND_EXC_GT:
        case OP_COND_EXC_IGT:
        case OP_CMOV_IGT:
@@ -2425,6 +2441,8 @@ mono_opcode_to_cond (int opcode)
        case OP_LCLT_UN:
        case OP_FBLT_UN:
        case OP_FCLT_UN:
+       case OP_RBLT_UN:
+       case OP_RCLT_UN:
        case OP_COND_EXC_LT_UN:
        case OP_COND_EXC_ILT_UN:
        case OP_CMOV_ILT_UN:
@@ -2437,6 +2455,8 @@ mono_opcode_to_cond (int opcode)
        case OP_LCGT_UN:
        case OP_FCGT_UN:
        case OP_FBGT_UN:
+       case OP_RCGT_UN:
+       case OP_RBGT_UN:
        case OP_COND_EXC_GT_UN:
        case OP_COND_EXC_IGT_UN:
        case OP_CMOV_IGT_UN:
@@ -2564,7 +2584,8 @@ mono_is_regsize_var (MonoType *t)
 void
 mono_peephole_ins (MonoBasicBlock *bb, MonoInst *ins)
 {
-       MonoInst *last_ins = ins->prev;
+       int filter = FILTER_IL_SEQ_POINT;
+       MonoInst *last_ins = mono_inst_prev (ins, filter);
 
        switch (ins->opcode) {
        case OP_MUL_IMM: 
@@ -2588,7 +2609,7 @@ mono_peephole_ins (MonoBasicBlock *bb, MonoInst *ins)
                 * OP_MOVE reg1, reg2
                 */
                if (last_ins && last_ins->opcode == OP_GC_LIVENESS_DEF)
-                       last_ins = last_ins->prev;
+                       last_ins = mono_inst_prev (ins, filter);
                if (last_ins &&
                        (((ins->opcode == OP_LOADI4_MEMBASE) && (last_ins->opcode == OP_STOREI4_MEMBASE_REG)) ||
                         ((ins->opcode == OP_LOAD_MEMBASE) && (last_ins->opcode == OP_STORE_MEMBASE_REG))) &&