Merge pull request #1857 from slluis/fix-assembly-resolver
[mono.git] / mono / mini / mini-codegen.c
index cc603b8a9530467d8f9eb39dd46f2efbafd9cc9b..4fde10b791fabbd369962c611d37f097cb6000d4 100644 (file)
@@ -580,6 +580,7 @@ mono_print_ins_index (int i, MonoInst *ins)
        case OP_IOR_IMM:
        case OP_IXOR_IMM:
        case OP_SUB_IMM:
+       case OP_STORE_MEMBASE_IMM:
                printf (" [%d]", (int)ins->inst_imm);
                break;
        case OP_ADD_IMM:
@@ -649,6 +650,19 @@ mono_print_ins_index (int i, MonoInst *ins)
 
                        list = g_slist_next (list);
                }
+               list = call->out_freg_args;
+               while (list) {
+                       guint32 regpair;
+                       int reg, hreg;
+
+                       regpair = (guint32)(gssize)(list->data);
+                       hreg = regpair >> 24;
+                       reg = regpair & 0xffffff;
+
+                       printf (" [%s <- R%d]", mono_arch_fregname (hreg), reg);
+
+                       list = g_slist_next (list);
+               }
                break;
        }
        case OP_BR:
@@ -688,7 +702,7 @@ mono_print_ins_index (int i, MonoInst *ins)
                break;
        case OP_IL_SEQ_POINT:
        case OP_SEQ_POINT:
-               printf (" il: %x", (int)ins->inst_imm);
+               printf (" il: 0x%x%s", (int)ins->inst_imm, ins->flags & MONO_INST_NONEMPTY_STACK ? ", nonempty-stack" : "");
                break;
        default:
                break;
@@ -778,10 +792,8 @@ spill_vreg (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **last, MonoInst *ins
 {
        MonoInst *load;
        int i, sel, spill;
-       int *symbolic;
        MonoRegState *rs = cfg->rs;
 
-       symbolic = rs->symbolic [bank];
        sel = rs->vassign [reg];
 
        /* the vreg we need to spill lives in another logical reg bank */
@@ -826,11 +838,8 @@ get_register_spilling (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **last, Mo
        MonoInst *load;
        int i, sel, spill, num_sregs;
        int sregs [MONO_MAX_SRC_REGS];
-       int *symbolic;
        MonoRegState *rs = cfg->rs;
 
-       symbolic = rs->symbolic [bank];
-
        g_assert (bank < MONO_NUM_REGBANKS);
 
        DEBUG (printf ("\tstart regmask to assign R%d: 0x%08llu (R%d <- R%d R%d R%d)\n", reg, (unsigned long long)regmask, ins->dreg, ins->sreg1, ins->sreg2, ins->sreg3));
@@ -1301,44 +1310,6 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                        ins->dreg = -1;
                }
 
-               if (spec [MONO_INST_CLOB] == 'c' && MONO_IS_CALL (ins)) {
-                       /* A call instruction implicitly uses all registers in call->out_ireg_args */
-
-                       MonoCallInst *call = (MonoCallInst*)ins;
-                       GSList *list;
-
-                       list = call->out_ireg_args;
-                       if (list) {
-                               while (list) {
-                                       guint32 regpair;
-                                       int reg, hreg;
-
-                                       regpair = (guint32)(gssize)(list->data);
-                                       hreg = regpair >> 24;
-                                       reg = regpair & 0xffffff;
-
-                                       //reginfo [reg].prev_use = reginfo [reg].last_use;
-                                       //reginfo [reg].last_use = i;
-
-                                       list = g_slist_next (list);
-                               }
-                       }
-
-                       list = call->out_freg_args;
-                       if (list) {
-                               while (list) {
-                                       guint32 regpair;
-                                       int reg, hreg;
-
-                                       regpair = (guint32)(gssize)(list->data);
-                                       hreg = regpair >> 24;
-                                       reg = regpair & 0xffffff;
-
-                                       list = g_slist_next (list);
-                               }
-                       }
-               }
-
                ++i;
        }
 
@@ -1346,7 +1317,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
 
        DEBUG (print_regtrack (reginfo, rs->next_vreg));
        MONO_BB_FOR_EACH_INS_REVERSE_SAFE (bb, prev, ins) {
-               int prev_dreg, clob_dreg;
+               int prev_dreg;
                int dest_dreg, clob_reg;
                int dest_sregs [MONO_MAX_SRC_REGS], prev_sregs [MONO_MAX_SRC_REGS];
                int dreg_high, sreg1_high;
@@ -1359,7 +1330,6 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                spec_src1 = spec [MONO_INST_SRC1];
                spec_dest = spec [MONO_INST_DEST];
                prev_dreg = -1;
-               clob_dreg = -1;
                clob_reg = -1;
                dest_dreg = -1;
                dreg_high = -1;
@@ -1517,7 +1487,6 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
 
                                        prev_dreg = ins->dreg;
                                        assign_reg (cfg, rs, ins->dreg, new_dest, 0);
-                                       clob_dreg = ins->dreg;
                                        create_copy_ins (cfg, bb, tmp, dest_sreg, new_dest, ins, ip, 0);
                                        mono_regstate_free_int (rs, dest_sreg);
                                        need_spill = FALSE;
@@ -2355,6 +2324,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:
@@ -2393,6 +2364,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:
@@ -2405,6 +2378,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:
@@ -2435,6 +2410,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:
@@ -2447,6 +2424,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:
@@ -2526,12 +2505,8 @@ mono_opcode_to_type (int opcode, int cmp_opcode)
 gboolean
 mono_is_regsize_var (MonoType *t)
 {
-       if (t->byref)
-               return TRUE;
-       t = mono_type_get_underlying_type (t);
+       t = mini_type_get_underlying_type (NULL, t);
        switch (t->type) {
-       case MONO_TYPE_BOOLEAN:
-       case MONO_TYPE_CHAR:
        case MONO_TYPE_I1:
        case MONO_TYPE_U1:
        case MONO_TYPE_I2:
@@ -2574,7 +2549,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: 
@@ -2598,7 +2574,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))) &&
@@ -2748,4 +2724,72 @@ mini_exception_id_by_name (const char *name)
        return -1;
 }
 
+gboolean
+mini_type_is_hfa (MonoType *t, int *out_nfields, int *out_esize)
+{
+       MonoClass *klass;
+       gpointer iter;
+       MonoClassField *field;
+       MonoType *ftype, *prev_ftype = NULL;
+       int nfields = 0;
+
+       klass = mono_class_from_mono_type (t);
+       iter = NULL;
+       while ((field = mono_class_get_fields (klass, &iter))) {
+               if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
+                       continue;
+               ftype = mono_field_get_type (field);
+               ftype = mini_native_type_replace_type (ftype);
+
+               if (MONO_TYPE_ISSTRUCT (ftype)) {
+                       int nested_nfields, nested_esize;
+
+                       if (!mini_type_is_hfa (ftype, &nested_nfields, &nested_esize))
+                               return FALSE;
+                       if (nested_esize == 4)
+                               ftype = &mono_defaults.single_class->byval_arg;
+                       else
+                               ftype = &mono_defaults.double_class->byval_arg;
+                       if (prev_ftype && prev_ftype->type != ftype->type)
+                               return FALSE;
+                       prev_ftype = ftype;
+                       nfields += nested_nfields;
+                       // FIXME: Nested float structs are aligned to 8 bytes
+                       if (ftype->type == MONO_TYPE_R4)
+                               return FALSE;
+               } else {
+                       if (!(!ftype->byref && (ftype->type == MONO_TYPE_R4 || ftype->type == MONO_TYPE_R8)))
+                               return FALSE;
+                       if (prev_ftype && prev_ftype->type != ftype->type)
+                               return FALSE;
+                       prev_ftype = ftype;
+                       nfields ++;
+               }
+       }
+       if (nfields == 0 || nfields > 4)
+               return FALSE;
+       *out_nfields = nfields;
+       *out_esize = prev_ftype->type == MONO_TYPE_R4 ? 4 : 8;
+       return TRUE;
+}
+
+MonoRegState*
+mono_regstate_new (void)
+{
+       MonoRegState* rs = g_new0 (MonoRegState, 1);
+
+       rs->next_vreg = MAX (MONO_MAX_IREGS, MONO_MAX_FREGS);
+#ifdef MONO_ARCH_NEED_SIMD_BANK
+       rs->next_vreg = MAX (rs->next_vreg, MONO_MAX_XREGS);
+#endif
+
+       return rs;
+}
+
+void
+mono_regstate_free (MonoRegState *rs) {
+       g_free (rs->vassign);
+       g_free (rs);
+}
+
 #endif /* DISABLE_JIT */