sp -= 2;
MINT_IN_BREAK;
+#define STARGFLD(datamem, fieldtype) do { \
+ MonoObject *o = frame->stack_args [ip [1]].data.o; \
+ NULL_CHECK (o); \
+ sp--; \
+ * (fieldtype *)((char *)o + ip [2]) = sp [0].data.datamem; \
+ ip += 3; \
+} while (0)
+ MINT_IN_CASE(MINT_STARGFLD_I1) STARGFLD(i, gint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STARGFLD_U1) STARGFLD(i, guint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STARGFLD_I2) STARGFLD(i, gint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STARGFLD_U2) STARGFLD(i, guint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STARGFLD_I4) STARGFLD(i, gint32); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STARGFLD_I8) STARGFLD(l, gint64); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STARGFLD_R4) STARGFLD(f_r4, float); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STARGFLD_R8) STARGFLD(f, double); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STARGFLD_P) STARGFLD(p, gpointer); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STARGFLD_O) {
+ MonoObject *o = frame->stack_args [ip [1]].data.o;
+ NULL_CHECK (o);
+ sp--;
+ mono_gc_wbarrier_set_field_internal (o, (char *) o + ip [2], sp [0].data.o);
+ ip += 3;
+ MINT_IN_BREAK;
+ }
+
+#define STLOCFLD(datamem, fieldtype) do { \
+ MonoObject *o = *(MonoObject**)(locals + ip [1]); \
+ NULL_CHECK (o); \
+ sp--; \
+ * (fieldtype *)((char *)o + ip [2]) = sp [0].data.datamem; \
+ ip += 3; \
+} while (0)
+ MINT_IN_CASE(MINT_STLOCFLD_I1) STLOCFLD(i, gint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STLOCFLD_U1) STLOCFLD(i, guint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STLOCFLD_I2) STLOCFLD(i, gint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STLOCFLD_U2) STLOCFLD(i, guint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STLOCFLD_I4) STLOCFLD(i, gint32); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STLOCFLD_I8) STLOCFLD(l, gint64); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STLOCFLD_R4) STLOCFLD(f_r4, float); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STLOCFLD_R8) STLOCFLD(f, double); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STLOCFLD_P) STLOCFLD(p, gpointer); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STLOCFLD_O) {
+ MonoObject *o = *(MonoObject**)(locals + ip [1]);
+ NULL_CHECK (o);
+ sp--;
+ mono_gc_wbarrier_set_field_internal (o, (char *) o + ip [2], sp [0].data.o);
+ ip += 3;
+ MINT_IN_BREAK;
+ }
+
MINT_IN_CASE(MINT_LDSFLDA) {
MonoVTable *vtable = (MonoVTable*) frame->imethod->data_items [ip [1]];
INIT_VTABLE (vtable);
MINT_IN_CASE(MINT_STLOC_NP_I4) STLOC_NP(i, gint32); MINT_IN_BREAK;
MINT_IN_CASE(MINT_STLOC_NP_I8) STLOC_NP(l, gint64); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STLOC_NP_R4) STLOC_NP(f_r4, float); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STLOC_NP_R8) STLOC_NP(f, double); MINT_IN_BREAK;
MINT_IN_CASE(MINT_STLOC_NP_O) STLOC_NP(p, gpointer); MINT_IN_BREAK;
MINT_IN_CASE(MINT_STLOC_VT) {
OPDEF(MINT_STRMFLD, "strmfld", 2, Pop2, Push0, MintOpFieldToken)
OPDEF(MINT_STRMFLD_VT, "strmfld.vt", 2, Pop2, Push0, MintOpUShortInt)
+OPDEF(MINT_STARGFLD_I1, "stargfld.i1", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STARGFLD_U1, "stargfld.u1", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STARGFLD_I2, "stargfld.i2", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STARGFLD_U2, "stargfld.u2", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STARGFLD_I4, "stargfld.i4", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STARGFLD_I8, "stargfld.i8", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STARGFLD_R4, "stargfld.r4", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STARGFLD_R8, "stargfld.r8", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STARGFLD_O, "stargfld.o", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STARGFLD_P, "stargfld.p", 3, Pop1, Push0, MintOpTwoShorts)
+
+OPDEF(MINT_STLOCFLD_I1, "stlocfld.i1", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STLOCFLD_U1, "stlocfld.u1", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STLOCFLD_I2, "stlocfld.i2", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STLOCFLD_U2, "stlocfld.u2", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STLOCFLD_I4, "stlocfld.i4", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STLOCFLD_I8, "stlocfld.i8", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STLOCFLD_R4, "stlocfld.r4", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STLOCFLD_R8, "stlocfld.r8", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STLOCFLD_O, "stlocfld.o", 3, Pop1, Push0, MintOpTwoShorts)
+OPDEF(MINT_STLOCFLD_P, "stlocfld.p", 3, Pop1, Push0, MintOpTwoShorts)
+
OPDEF(MINT_LDTSFLD_I1, "ldtsfld.i1", 3, Pop0, Push1, MintOpInt)
OPDEF(MINT_LDTSFLD_U1, "ldtsfld.u1", 3, Pop0, Push1, MintOpInt)
OPDEF(MINT_LDTSFLD_I2, "ldtsfld.i2", 3, Pop0, Push1, MintOpInt)
OPDEF(MINT_STLOC_NP_I4, "stloc.np.i4", 2, Pop0, Push0, MintOpUShortInt)
OPDEF(MINT_STLOC_NP_I8, "stloc.np.i8", 2, Pop0, Push0, MintOpUShortInt)
+OPDEF(MINT_STLOC_NP_R4, "stloc.np.R4", 2, Pop0, Push0, MintOpUShortInt)
+OPDEF(MINT_STLOC_NP_R8, "stloc.np.R8", 2, Pop0, Push0, MintOpUShortInt)
OPDEF(MINT_STLOC_NP_O, "stloc.np.o", 2, Pop0, Push0, MintOpUShortInt)
OPDEF(MINT_MOVLOC_1, "movloc.1", 3, Pop0, Push0, MintOpTwoShorts)
#define MINT_IS_UNOP(op) ((op) >= MINT_ADD1_I4 && (op) <= MINT_CEQ0_I4)
#define MINT_IS_BINOP(op) ((op) >= MINT_ADD_I4 && (op) <= MINT_CLT_UN_R8)
#define MINT_IS_LDLOCFLD(op) ((op) >= MINT_LDLOCFLD_I1 && (op) <= MINT_LDLOCFLD_P)
+#define MINT_IS_STLOCFLD(op) ((op) >= MINT_STLOCFLD_I1 && (op) <= MINT_STLOCFLD_P)
#define MINT_IS_LOCUNOP(op) ((op) >= MINT_LOCADD1_I4 && (op) <= MINT_LOCSUB1_I8)
g_assert_not_reached ();
break;
}
- SET_SIMPLE_TYPE(td->sp - 1, STACK_TYPE_I8);
+ SET_SIMPLE_TYPE(td->sp - 1, STACK_TYPE_I);
++td->ip;
break;
case CEE_CONV_OVF_I8_UN:
cbb->last_seq_point = seqp;
} else {
if (MINT_IS_LDLOC (opcode) || MINT_IS_STLOC (opcode) || MINT_IS_STLOC_NP (opcode) || opcode == MINT_LDLOCA_S ||
- MINT_IS_LDLOCFLD (opcode) || MINT_IS_LOCUNOP (opcode)) {
+ MINT_IS_LDLOCFLD (opcode) || MINT_IS_LOCUNOP (opcode) || MINT_IS_STLOCFLD (opcode)) {
ins->data [0] = get_interp_local_offset (td, ins->data [0]);
} else if (MINT_IS_MOVLOC (opcode)) {
ins->data [0] = get_interp_local_offset (td, ins->data [0]);
static void
interp_cprop (TransformData *td)
{
- if (!td->max_stack_height || !td->locals_size)
+ if (!td->max_stack_height)
return;
StackContentInfo *stack = (StackContentInfo*) g_malloc (td->max_stack_height * sizeof (StackContentInfo));
StackContentInfo *stack_end = stack + td->max_stack_height;
replace_op = MINT_STLOC_NP_I4;
else if (mt == MINT_TYPE_I8)
replace_op = MINT_STLOC_NP_I8;
+ else if (mt == MINT_TYPE_R4)
+ replace_op = MINT_STLOC_NP_R4;
+ else if (mt == MINT_TYPE_R8)
+ replace_op = MINT_STLOC_NP_R8;
else if (mt == MINT_TYPE_O || mt == MINT_TYPE_P)
replace_op = MINT_STLOC_NP_O;
if (replace_op) {
} else if (MINT_IS_BINOP (ins->opcode)) {
ins = interp_fold_binop (td, sp, ins);
sp--;
+ } else if (ins->opcode >= MINT_STFLD_I1 && ins->opcode <= MINT_STFLD_P && (mono_interp_opt & INTERP_OPT_SUPER_INSTRUCTIONS)) {
+ if (sp [-2].ins) {
+ InterpInst *obj_ins = sp [-2].ins;
+ if (obj_ins->opcode == MINT_LDLOC_O) {
+ int loc_index = obj_ins->data [0];
+ int fld_offset = ins->data [0];
+ int mt = ins->opcode - MINT_STFLD_I1;
+ ins = interp_insert_ins (td, ins, MINT_STLOCFLD_I1 + mt);
+ ins->data [0] = loc_index;
+ ins->data [1] = fld_offset;
+ interp_clear_ins (td, ins->prev);
+ interp_clear_ins (td, obj_ins);
+ mono_interp_stats.super_instructions++;
+ mono_interp_stats.killed_instructions++;
+ } else if (obj_ins->opcode == MINT_LDARG_O || obj_ins->opcode == MINT_LDARG_P0) {
+ int arg_index = 0;
+ int fld_offset = ins->data [0];
+ int mt = ins->opcode - MINT_STFLD_I1;
+ if (obj_ins->opcode == MINT_LDARG_O)
+ arg_index = obj_ins->data [0];
+ ins = interp_insert_ins (td, ins, MINT_STARGFLD_I1 + mt);
+ ins->data [0] = arg_index;
+ ins->data [1] = fld_offset;
+ interp_clear_ins (td, ins->prev);
+ interp_clear_ins (td, obj_ins);
+ mono_interp_stats.super_instructions++;
+ mono_interp_stats.killed_instructions++;
+ }
+ }
+ sp -= 2;
+ } else if (MINT_IS_STLOCFLD (ins->opcode)) {
+ local_ref_count [ins->data [0]]++;
+ sp--;
} else {
if (pop == MINT_POP_ALL)
pop = sp - stack;