OPDEF(MINT_INTRINS_TRY_GET_HASHCODE, "intrins_try_get_hashcode", 3, 1, 1, MintOpNoArgs)
OPDEF(MINT_INTRINS_GET_TYPE, "intrins_get_type", 3, 1, 1, MintOpNoArgs)
OPDEF(MINT_INTRINS_SPAN_CTOR, "intrins_span_ctor", 4, 1, 2, MintOpNoArgs)
-OPDEF(MINT_INTRINS_UNSAFE_BYTE_OFFSET, "intrins_unsafe_byte_offset", 4, 1, 2, MintOpNoArgs)
OPDEF(MINT_INTRINS_RUNTIMEHELPERS_OBJECT_HAS_COMPONENT_SIZE, "intrins_runtimehelpers_object_has_component_size", 3, 1, 1, MintOpNoArgs)
OPDEF(MINT_INTRINS_CLEAR_WITH_REFERENCES, "intrin_clear_with_references", 3, 0, 2, MintOpNoArgs)
OPDEF(MINT_INTRINS_MARVIN_BLOCK, "intrins_marvin_block", 3, 0, 2, MintOpNoArgs)
} else if (!strcmp (tm, "AreSame")) {
*op = MINT_CEQ_P;
} else if (!strcmp (tm, "ByteOffset")) {
- *op = MINT_INTRINS_UNSAFE_BYTE_OFFSET;
+#if SIZEOF_VOID_P == 4
+ interp_add_ins (td, MINT_SUB_I4);
+#else
+ interp_add_ins (td, MINT_SUB_I8);
+#endif
+ td->sp -= 2;
+ interp_ins_set_sregs2 (td->last_ins, td->sp [1].local, td->sp [0].local);
+ push_simple_type (td, STACK_TYPE_I);
+ interp_ins_set_dreg (td->last_ins, td->sp [-1].local);
+ td->ip += 5;
+ return TRUE;
} else if (!strcmp (tm, "Unbox")) {
MonoGenericContext *ctx = mono_method_get_context (target_method);
g_assert (ctx);
dump_interp_inst (new_inst);
}
}
+ } else if (opcode == MINT_DIV_UN_I4 || opcode == MINT_DIV_UN_I8) {
+ // ldc + div.un -> shr.imm
+ int sreg_imm = ins->sregs [1];
+ InterpInst *def = td->locals [sreg_imm].def;
+ if (def != NULL && td->local_ref_count [sreg_imm] == 1) {
+ int power2 = -1;
+ if (MINT_IS_LDC_I4 (def->opcode)) {
+ guint32 ct = interp_get_const_from_ldc_i4 (def);
+ power2 = mono_is_power_of_two ((guint32)ct);
+ } else if (MINT_IS_LDC_I8 (def->opcode)) {
+ guint64 ct = interp_get_const_from_ldc_i8 (def);
+ if (ct < G_MAXUINT32)
+ power2 = mono_is_power_of_two ((guint32)ct);
+ }
+ if (power2 > 0) {
+ InterpInst *new_inst;
+ if (opcode == MINT_DIV_UN_I4)
+ new_inst = interp_insert_ins (td, ins, MINT_SHR_UN_I4_IMM);
+ else
+ new_inst = interp_insert_ins (td, ins, MINT_SHR_UN_I8_IMM);
+ new_inst->dreg = ins->dreg;
+ new_inst->sregs [0] = ins->sregs [0];
+ new_inst->data [0] = power2;
+
+ interp_clear_ins (def);
+ interp_clear_ins (ins);
+ local_ref_count [sreg_imm]--;
+ if (td->verbose_level) {
+ g_print ("lower div.un: ");
+ dump_interp_inst (new_inst);
+ }
+ }
+ }
} else if (MINT_IS_LDIND_INT (opcode)) {
int sreg_base = ins->sregs [0];
InterpInst *def = td->locals [sreg_base].def;
builder.callImport("ldtsflda");
break;
}
- case MintOpcode.MINT_INTRINS_UNSAFE_BYTE_OFFSET:
- builder.local("pLocals");
- append_ldloc(builder, getArgU16(ip, 3), WasmOpcode.i32_load);
- append_ldloc(builder, getArgU16(ip, 2), WasmOpcode.i32_load);
- builder.appendU8(WasmOpcode.i32_sub);
- append_stloc_tail(builder, getArgU16(ip, 1), WasmOpcode.i32_store);
- break;
case MintOpcode.MINT_INTRINS_GET_TYPE:
builder.block();
// dest, src