MINT_IN_BREAK;
}
-#define LDFLD_VT(datamem, fieldtype) do { \
+#define LDFLD_VT_UNALIGNED(datamem, fieldtype, unaligned) do { \
gpointer p = sp [-1].data.p; \
vt_sp -= ip [2]; \
- sp [-1].data.datamem = * (fieldtype *)((char *)p + ip [1]); \
+ if (unaligned) \
+ memcpy (&sp[-1].data.datamem, (char *)p + ip [1], sizeof (fieldtype)); \
+ else \
+ sp [-1].data.datamem = * (fieldtype *)((char *)p + ip [1]); \
ip += 3; \
} while (0)
+#define LDFLD_VT(datamem, fieldtype) LDFLD_VT_UNALIGNED(datamem, fieldtype, FALSE)
+
MINT_IN_CASE(MINT_LDFLD_VT_I1) LDFLD_VT(i, gint8); MINT_IN_BREAK;
MINT_IN_CASE(MINT_LDFLD_VT_U1) LDFLD_VT(i, guint8); MINT_IN_BREAK;
MINT_IN_CASE(MINT_LDFLD_VT_I2) LDFLD_VT(i, gint16); MINT_IN_BREAK;
MINT_IN_CASE(MINT_LDFLD_VT_R4) LDFLD_VT(f_r4, float); MINT_IN_BREAK;
MINT_IN_CASE(MINT_LDFLD_VT_R8) LDFLD_VT(f, double); MINT_IN_BREAK;
MINT_IN_CASE(MINT_LDFLD_VT_O) LDFLD_VT(p, gpointer); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDFLD_VT_I8_UNALIGNED) LDFLD_VT_UNALIGNED(l, gint64, TRUE); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDFLD_VT_R8_UNALIGNED) LDFLD_VT_UNALIGNED(f, double, TRUE); MINT_IN_BREAK;
MINT_IN_CASE(MINT_LDFLD_VT_VT) {
gpointer p = sp [-1].data.p;
OPDEF(MINT_LDFLD_VT_R8, "ldfld.vt.r8", 3, Pop1, Push1, MintOpTwoShorts)
OPDEF(MINT_LDFLD_VT_O, "ldfld.vt.o", 3, Pop1, Push1, MintOpTwoShorts)
OPDEF(MINT_LDFLD_VT_VT, "ldfld.vt.vt", 4, Pop1, Push1, MintOpTwoShorts)
+OPDEF(MINT_LDFLD_VT_I8_UNALIGNED, "ldfld.vt.i8.unaligned", 3, Pop1, Push1, MintOpTwoShorts)
+OPDEF(MINT_LDFLD_VT_R8_UNALIGNED, "ldfld.vt.r8.unaligned", 3, Pop1, Push1, MintOpTwoShorts)
OPDEF(MINT_LDFLD_I1, "ldfld.i1", 2, Pop1, Push1, MintOpUShortInt)
OPDEF(MINT_LDFLD_U1, "ldfld.u1", 2, Pop1, Push1, MintOpUShortInt)
goto_if_nok (error, exit);
} else if (td->sp [-1].type == STACK_TYPE_VT) {
/* First we pop the vt object from the stack. Then we push the field */
- /* FIXME unaligned field load ? */
int opcode = MINT_LDFLD_VT_I1 + mt - MINT_TYPE_I1;
+#ifdef NO_UNALIGNED_ACCESS
+ if (field->offset % SIZEOF_VOID_P != 0) {
+ if (mt == MINT_TYPE_I8)
+ opcode = MINT_LDFLD_VT_I8_UNALIGNED;
+ else if (mt == MINT_TYPE_R8)
+ opcode = MINT_LDFLD_VT_R8_UNALIGNED;
+ }
+#endif
interp_add_ins (td, opcode);
g_assert (m_class_is_valuetype (klass));
td->last_ins->data [0] = field->offset - MONO_ABI_SIZEOF (MonoObject);