X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-codegen.c;h=4fde10b791fabbd369962c611d37f097cb6000d4;hb=f03a1b538bfb0d9be810688e8713731e122320b5;hp=66eb8fcdcf2f0c78f58f12ca2fd5bfeae4091fd7;hpb=8da27c63c37365e4467b2e780e3febcf59c8e0c7;p=mono.git diff --git a/mono/mini/mini-codegen.c b/mono/mini/mini-codegen.c index 66eb8fcdcf2..4fde10b791f 100644 --- a/mono/mini/mini-codegen.c +++ b/mono/mini/mini-codegen.c @@ -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: @@ -686,8 +700,9 @@ 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); + printf (" il: 0x%x%s", (int)ins->inst_imm, ins->flags & MONO_INST_NONEMPTY_STACK ? ", nonempty-stack" : ""); break; default: break; @@ -777,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 */ @@ -825,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)); @@ -1173,6 +1183,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)) { @@ -1198,12 +1210,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 (®info [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) @@ -1296,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; } @@ -1341,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; @@ -1354,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; @@ -1512,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; @@ -2350,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: @@ -2388,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: @@ -2400,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: @@ -2430,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: @@ -2442,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: @@ -2521,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: @@ -2569,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: @@ -2593,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))) && @@ -2743,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 */