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:
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:
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;
{
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 */
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));
* 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)) {
#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)
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;
}
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;
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;
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;
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:
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:
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:
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:
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:
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:
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:
* 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))) &&
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 */