+/*
+ * Emit code which loads into "intf_bit_reg" a nonzero value if the MonoVTable
+ * stored in "vtable_reg" implements the interface "klass".
+ */
+static void
+mini_emit_load_intf_bit_reg_vtable (MonoCompile *s, int intf_bit_reg, int vtable_reg, MonoClass *klass)
+{
+ int ibitmap_reg = mono_regstate_next_int (s->rs);
+ int ibitmap_byte_reg = mono_regstate_next_int (s->rs);
+
+ MONO_EMIT_NEW_LOAD_MEMBASE (s, ibitmap_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, interface_bitmap));
+
+ if (s->compile_aot) {
+ int iid_reg = mono_regstate_next_int (s->rs);
+ int shifted_iid_reg = mono_regstate_next_int (s->rs);
+ int ibitmap_byte_address_reg = mono_regstate_next_int (s->rs);
+ int masked_iid_reg = mono_regstate_next_int (s->rs);
+ int iid_one_bit_reg = mono_regstate_next_int (s->rs);
+ int iid_bit_reg = mono_regstate_next_int (s->rs);
+ MONO_EMIT_NEW_AOTCONST (s, iid_reg, klass, MONO_PATCH_INFO_IID);
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, shifted_iid_reg, iid_reg, 3);
+ MONO_EMIT_NEW_BIALU (s, CEE_ADD, ibitmap_byte_address_reg, ibitmap_reg, shifted_iid_reg);
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADU1_MEMBASE, ibitmap_byte_reg, ibitmap_byte_address_reg, 0);
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_AND_IMM, masked_iid_reg, iid_reg, 7);
+ MONO_EMIT_NEW_ICONST (s, iid_one_bit_reg, 1);
+ MONO_EMIT_NEW_BIALU (s, CEE_SHL, iid_bit_reg, iid_one_bit_reg, masked_iid_reg);
+ MONO_EMIT_NEW_BIALU (s, CEE_AND, intf_bit_reg, ibitmap_byte_reg, iid_bit_reg);
+ } else {
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI1_MEMBASE, ibitmap_byte_reg, ibitmap_reg, klass->interface_id >> 3);
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_AND_IMM, intf_bit_reg, ibitmap_byte_reg, 1 << (klass->interface_id & 7));
+ }
+}
+
+#ifdef MONO_ARCH_HAVE_IMT
+static void
+emit_imt_argument (MonoCompile *cfg, MonoCallInst *call) {
+#ifdef MONO_ARCH_IMT_REG
+ MonoInst *inst;
+ MONO_INST_NEW (cfg, inst, OP_PCONST);
+ inst->inst_p0 = call->method;
+ inst->dreg = mono_regstate_next_int (cfg->rs);
+ mono_bblock_add_inst (cfg->cbb, inst);
+
+ mono_call_inst_add_outarg_reg (cfg, call, inst->dreg, MONO_ARCH_IMT_REG, FALSE);
+#else
+ mono_arch_emit_imt_argument (cfg, call);
+#endif
+}
+#endif