X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mono%2Fmini%2Finssel.brg;h=3ec201ed3a810f095cdda9d6ae0981327afa3090;hb=884f608c3fbe8b0178dd1c7d01ce4d92d3797a15;hp=3d08d41087b02eca6dca5fe7ea39eb92f3122bb8;hpb=f292c18aea85007083bacc8762a93b922e56acf6;p=mono.git diff --git a/mono/mini/inssel.brg b/mono/mini/inssel.brg index 3d08d41087b..3ec201ed3a8 100644 --- a/mono/mini/inssel.brg +++ b/mono/mini/inssel.brg @@ -319,6 +319,13 @@ } while (0) #endif +#ifndef MONO_EMIT_NEW_COMPARE_BRANCH_LABEL_CHAINED +#define MONO_EMIT_NEW_COMPARE_BRANCH_LABEL_CHAINED(cfg, cmp_op, sreg1, sreg2, label) \ + do { \ + MONO_EMIT_NEW_BRANCH_LABEL (s, (cmp_op), (label)); \ +} while (0) +#endif + #ifndef MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL #define MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL(cfg, cmp_op, sreg1, imm, label) \ do { \ @@ -327,6 +334,13 @@ } while (0) #endif +#ifndef MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL_CHAINED +#define MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL_CHAINED(cfg, cmp_op, sreg1, imm, label) \ + do { \ + MONO_EMIT_NEW_BRANCH_LABEL (s, (cmp_op), (label)); \ +} while (0) +#endif + #ifndef MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK #define MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK(cfg, cmp_op, sreg1, sreg2, block) \ do { \ @@ -335,6 +349,13 @@ } while (0) #endif +#ifndef MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK_CHAINED +#define MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK_CHAINED(cfg, cmp_op, sreg1, sreg2, block) \ + do { \ + MONO_EMIT_NEW_BRANCH_BLOCK (s, (cmp_op), (block)); \ +} while (0) +#endif + #ifndef MONO_EMIT_NEW_COMPARE_IMM_BRANCH_BLOCK #define MONO_EMIT_NEW_COMPARE_IMM_BRANCH_BLOCK(cfg, cmp_op, sreg1, imm, block) \ do { \ @@ -343,6 +364,13 @@ } while (0) #endif +#ifndef MONO_EMIT_NEW_COMPARE_IMM_BRANCH_BLOCK_CHAINED +#define MONO_EMIT_NEW_COMPARE_IMM_BRANCH_BLOCK_CHAINED(cfg, cmp_op, sreg1, imm, block) \ + do { \ + MONO_EMIT_NEW_BRANCH_BLOCK (s, (cmp_op), (block)); \ +} while (0) +#endif + %% %termprefix OP_ CEE_ @@ -752,7 +780,7 @@ reg: OP_CEQ (cflags), reg: OP_CLT (cflags), reg: OP_CLT_UN (cflags), reg: OP_CGT (cflags), -reg: OP_CGT_UN (cflags) { +reg: OP_CGT_UN (cflags) "2" { tree->dreg = state->reg1; mono_bblock_add_inst (s->cbb, tree); } @@ -765,10 +793,10 @@ stmt: OP_LABEL { mono_bblock_add_inst (s->cbb, tree); } -stmt: CEE_NOP "0" { +stmt: OP_NOP "0" { } -stmt: CEE_BREAK "0" { +stmt: OP_BREAK "0" { mono_bblock_add_inst (s->cbb, tree); } @@ -785,12 +813,17 @@ stmt: CEE_SWITCH (reg) "2" { MONO_NEW_LABEL (s, label); - MONO_EMIT_NEW_BIALU_IMM (s, OP_ICOMPARE_IMM, -1, state->left->reg1, n); - MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_IBGE_UN, tree->inst_many_bb [n]); - if (sizeof (gpointer) == 8) + if (sizeof (gpointer) == 8) { + MONO_EMIT_NEW_BIALU_IMM (s, OP_ICOMPARE_IMM, -1, state->left->reg1, n); + MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_IBGE_UN, tree->inst_many_bb [n]); MONO_EMIT_NEW_BIALU_IMM (s, OP_SHL_IMM, offset_reg, state->left->reg1, 3); - else + /* The upper word might not be zero, and we add it to a 64 bit address later */ + MONO_EMIT_NEW_UNALU (s, CEE_CONV_U8, offset_reg, offset_reg); + } else { + MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, n); + MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_many_bb [n]); MONO_EMIT_NEW_BIALU_IMM (s, OP_SHL_IMM, offset_reg, state->left->reg1, 2); + } mono_bblock_add_inst (s->cbb, label); if (s->compile_aot) { int table_reg = mono_regstate_next_int (s->rs); @@ -818,7 +851,7 @@ stmt: CEE_SWITCH (reg) "2" { MONO_EMIT_UNALU (s, tree, OP_BR_REG, -1, target_reg); } -stmt: CEE_BR "0" { +stmt: OP_BR "0" { mono_bblock_add_inst (s->cbb, tree); } @@ -943,14 +976,14 @@ stmt: CEE_POP (CEE_LDIND_U4 (OP_REGVAR)) stmt: CEE_POP (CEE_LDIND_I (OP_REGVAR)) stmt: CEE_POP (CEE_LDIND_REF (OP_REGVAR)) -stmt: CEE_JMP "0" { +stmt: OP_JMP "0" { mono_bblock_add_inst (s->cbb, tree); } # exception handling -stmt: CEE_THROW (reg) { - MONO_EMIT_UNALU (s, tree, CEE_THROW, -1, state->left->reg1); +stmt: OP_THROW (reg) { + MONO_EMIT_UNALU (s, tree, OP_THROW, -1, state->left->reg1); } stmt: OP_RETHROW (reg) { @@ -968,12 +1001,12 @@ stmt: OP_THROW_OR_NULL (reg, reg) { * the abort exception is more important than getting the sematics right. */ MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL (s, CEE_BEQ, state->left->reg1, 0, dont_throw); - MONO_EMIT_UNALU (s, tree, CEE_THROW, -1, state->left->reg1); + MONO_EMIT_UNALU (s, tree, OP_THROW, -1, state->left->reg1); mono_bblock_add_inst (s->cbb, dont_throw); } -stmt: CEE_THROW (CEE_LDIND_REF (OP_REGVAR)) { - MONO_EMIT_UNALU (s, tree, CEE_THROW, -1, state->left->left->tree->dreg); +stmt: OP_THROW (CEE_LDIND_REF (OP_REGVAR)) { + MONO_EMIT_UNALU (s, tree, OP_THROW, -1, state->left->left->tree->dreg); } stmt: OP_CALL_HANDLER { @@ -984,7 +1017,7 @@ stmt: OP_START_HANDLER "2" { mono_bblock_add_inst (s->cbb, tree); } -stmt: CEE_ENDFINALLY "2" { +stmt: OP_ENDFINALLY "2" { mono_bblock_add_inst (s->cbb, tree); } @@ -1049,7 +1082,7 @@ reg: CEE_ISINST (reg) { MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL (s, CEE_BEQ, eclass_reg, mono_defaults.enum_class, object_is_null); } - MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, false_label); + MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, false_label); } else if (klass->cast_class == mono_defaults.enum_class->parent) { int const_reg = -1; @@ -1068,7 +1101,7 @@ reg: CEE_ISINST (reg) { MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL (s, CEE_BEQ, eclass_reg, mono_defaults.enum_class, object_is_null); } - MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, false_label); + MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, false_label); } else if (klass->cast_class == mono_defaults.enum_class) { if (s->compile_aot) { int const_reg = mono_regstate_next_int (s->rs); @@ -1078,7 +1111,7 @@ reg: CEE_ISINST (reg) { MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL (s, CEE_BEQ, eclass_reg, mono_defaults.enum_class, object_is_null); } - MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, false_label); + MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, false_label); } else if (klass->cast_class->flags & TYPE_ATTRIBUTE_INTERFACE) { mini_emit_isninst_iface_class_cast (s, eclass_reg, klass->cast_class, false_label, object_is_null); } else { @@ -1106,7 +1139,7 @@ reg: CEE_ISINST (reg) { MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL (s, CEE_BNE_UN, klass_reg, klass, false_label); } - MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, object_is_null); + MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, object_is_null); } else { MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass)); /* the object_is_null target simply copies the input register to the output */ @@ -1117,7 +1150,7 @@ reg: CEE_ISINST (reg) { mono_bblock_add_inst (s->cbb, false_label); MONO_EMIT_NEW_ICONST (s, state->reg1, 0); - MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label); + MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, end_label); mono_bblock_add_inst (s->cbb, object_is_null); MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, obj_reg); mono_bblock_add_inst (s->cbb, end_label); @@ -1184,7 +1217,7 @@ reg: OP_CISINST (reg) { MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL (s, CEE_BEQ, tmp_reg, 0, no_proxy_label); mini_emit_isninst_cast (s, klass_reg, klass, false2_label, true_label); - MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, false2_label); + MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, false2_label); mono_bblock_add_inst (s->cbb, no_proxy_label); mini_emit_isninst_cast (s, klass_reg, klass, false_label, true_label); @@ -1192,10 +1225,10 @@ reg: OP_CISINST (reg) { mono_bblock_add_inst (s->cbb, false_label); MONO_EMIT_NEW_ICONST (s, state->reg1, 1); - MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label); + MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, end_label); mono_bblock_add_inst (s->cbb, false2_label); MONO_EMIT_NEW_ICONST (s, state->reg1, 2); - MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label); + MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, end_label); mono_bblock_add_inst (s->cbb, true_label); MONO_EMIT_NEW_ICONST (s, state->reg1, 0); mono_bblock_add_inst (s->cbb, end_label); @@ -1313,7 +1346,7 @@ reg: OP_CCASTCLASS (reg) { MONO_EMIT_NEW_COMPARE_IMM_EXC (s, EQ, tmp_reg, 0, "InvalidCastException"); MONO_EMIT_NEW_ICONST (s, state->reg1, 1); - MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label); + MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, end_label); } else { @@ -1341,7 +1374,7 @@ reg: OP_CCASTCLASS (reg) { mini_emit_isninst_cast (s, klass_reg, klass, fail_label, ok_result_label); mono_bblock_add_inst (s->cbb, fail_label); MONO_EMIT_NEW_ICONST (s, state->reg1, 1); - MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label); + MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, end_label); mono_bblock_add_inst (s->cbb, no_proxy_label); /* Again, use ok_result_label as "object_is_null" */ @@ -1529,6 +1562,28 @@ stmt: CEE_MKREFANY (OP_GROUP (reg, OP_I8CONST), reg) { MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREP_MEMBASE_REG, state->right->reg1, G_STRUCT_OFFSET (MonoTypedRef, value), state->left->left->reg1); } +reg: OP_MIN (reg, reg) "2" { + /* min (x,y) = y + (((x-y)>>31)&(x-y)); */ + int diff = mono_regstate_next_int (s->rs); + int shifted = mono_regstate_next_int (s->rs); + int anded = mono_regstate_next_int (s->rs); + MONO_EMIT_NEW_BIALU (s, CEE_SUB, diff, state->left->reg1, state->right->reg1); + MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, shifted, diff, (sizeof(void*)*8-1)); + MONO_EMIT_NEW_BIALU (s, CEE_AND, anded, shifted, diff); + MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, anded, state->right->reg1); +} + +reg: OP_MAX (reg, reg) "2" { + /* max (x,y) = x - (((x-y)>>31)&(x-y)); */ + int diff = mono_regstate_next_int (s->rs); + int shifted = mono_regstate_next_int (s->rs); + int anded = mono_regstate_next_int (s->rs); + MONO_EMIT_NEW_BIALU (s, CEE_SUB, diff, state->left->reg1, state->right->reg1); + MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, shifted, diff, (sizeof(void*)*8-1)); + MONO_EMIT_NEW_BIALU (s, CEE_AND, anded, shifted, diff); + MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, anded); +} + %% #ifdef MONO_ARCH_NEED_GOT_VAR @@ -1599,25 +1654,87 @@ mini_emit_load_intf_reg_vtable (MonoCompile *s, int intf_reg, int vtable_reg, Mo } } -/* Emit code which loads ->interface_offsets [klass->interface_id] */ +/* + * Emit code which loads into "intf_bit_reg" a nonzero value if the MonoClass + * stored in "klass_reg" implements the interface "klass". + */ static void -mini_emit_load_intf_reg_class (MonoCompile *s, int intf_reg, int klass_reg, MonoClass *klass) +mini_emit_load_intf_bit_reg_class (MonoCompile *s, int intf_bit_reg, int klass_reg, MonoClass *klass) { - int ioffset_reg = mono_regstate_next_int (s->rs); + 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, ioffset_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, interface_offsets)); + MONO_EMIT_NEW_LOAD_MEMBASE (s, ibitmap_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, 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_SHL_IMM, shifted_iid_reg, iid_reg, 2); - MONO_EMIT_NEW_BIALU (s, CEE_ADD, ioffset_reg, ioffset_reg, shifted_iid_reg); - MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, intf_reg, ioffset_reg, 0); + 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_LOADI4_MEMBASE, intf_reg, ioffset_reg, klass->interface_id * sizeof (int)); + 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)); } } +/* + * 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 static void mini_emit_virtual_call (MonoCompile *cfg, void *st, MonoInst *tree, int novirtop, int virtop) @@ -1649,15 +1766,50 @@ mini_emit_virtual_call (MonoCompile *cfg, void *st, MonoInst *tree, int novirtop return; } +#ifdef MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE + if ((method->klass->parent == mono_defaults.multicastdelegate_class) && (!strcmp (method->name, "Invoke"))) { + /* Make a call to delegate->invoke_impl */ + tree->dreg = state->reg1; + tree->opcode = virtop; + tree->inst_basereg = this_reg; + tree->inst_offset = G_STRUCT_OFFSET (MonoDelegate, invoke_impl); + mono_bblock_add_inst (cfg->cbb, tree); + return; + } +#endif + + if ((method->flags & METHOD_ATTRIBUTE_VIRTUAL) && + ((method->flags & METHOD_ATTRIBUTE_FINAL) || + (method->klass && method->klass->flags & TYPE_ATTRIBUTE_SEALED))) { + /* + * the method is virtual, but we can statically dispatch since either + * it's class or the method itself are sealed. + * But first we need to ensure it's not a null reference. + */ + MONO_EMIT_NEW_UNALU (cfg, OP_CHECK_THIS, -1, this_reg); + + tree->dreg = state->reg1; + tree->opcode = novirtop; + mono_bblock_add_inst (cfg->cbb, tree); + return; + } + /* Initialize method->slot */ mono_class_setup_vtable (method->klass); vtable_reg = mono_regstate_next_int (cfg->rs); MONO_EMIT_NEW_LOAD_MEMBASE (cfg, vtable_reg, this_reg, G_STRUCT_OFFSET (MonoObject, vtable)); if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) { +#ifdef MONO_ARCH_HAVE_IMT + guint32 imt_slot = mono_method_get_imt_slot (method); + emit_imt_argument (cfg, (MonoCallInst*)tree); + slot_reg = vtable_reg; + tree->inst_offset = (imt_slot - MONO_IMT_SIZE) * SIZEOF_VOID_P; +#else slot_reg = mono_regstate_next_int (cfg->rs); mini_emit_load_intf_reg_vtable (cfg, slot_reg, vtable_reg, method->klass); tree->inst_offset = method->slot * SIZEOF_VOID_P; +#endif } else { slot_reg = vtable_reg; tree->inst_offset = G_STRUCT_OFFSET (MonoVTable, vtable) + (method->slot * SIZEOF_VOID_P); @@ -1698,24 +1850,23 @@ mini_emit_isninst_iface_cast (MonoCompile *s, int vtable_reg, MonoClass *klass, int intf_reg = mono_regstate_next_int (s->rs); mini_emit_max_iid_check_vtable (s, vtable_reg, klass, false_target); - mini_emit_load_intf_reg_vtable (s, intf_reg, vtable_reg, klass); + mini_emit_load_intf_bit_reg_vtable (s, intf_reg, vtable_reg, klass); /* the object_is_null target simply copies the input register to the output */ MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL (s, CEE_BNE_UN, intf_reg, 0, true_target); } /* * Variant of the above that takes a register to the class, not the vtable. - * Note that inside interfaces_offsets the empty value is -1, not NULL, in this case. */ static void mini_emit_isninst_iface_class_cast (MonoCompile *s, int klass_reg, MonoClass *klass, MonoInst *false_target, MonoInst *true_target) { - int intf_reg = mono_regstate_next_int (s->rs); + int intf_bit_reg = mono_regstate_next_int (s->rs); mini_emit_max_iid_check_class (s, klass_reg, klass, false_target); - mini_emit_load_intf_reg_class (s, intf_reg, klass_reg, klass); + mini_emit_load_intf_bit_reg_class (s, intf_bit_reg, klass_reg, klass); /* the object_is_null target simply copies the input register to the output */ - MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL (s, CEE_BGE, intf_reg, -1, true_target); + MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL (s, CEE_BNE_UN, intf_bit_reg, 0, true_target); } static void @@ -1724,22 +1875,21 @@ mini_emit_castclass_iface (MonoCompile *s, int vtable_reg, MonoClass *klass) int intf_reg = mono_regstate_next_int (s->rs); mini_emit_max_iid_check_vtable (s, vtable_reg, klass, NULL); - mini_emit_load_intf_reg_vtable (s, intf_reg, vtable_reg, klass); + mini_emit_load_intf_bit_reg_vtable (s, intf_reg, vtable_reg, klass); MONO_EMIT_NEW_COMPARE_IMM_EXC (s, EQ, intf_reg, 0, "InvalidCastException"); } /* * Variant of the aboce that takes a register to the class, not the vtable. - * Note that inside interfaces_offsets the empty value is -1, not NULL, in this case. */ static void mini_emit_castclass_iface_class (MonoCompile *s, int klass_reg, MonoClass *klass) { - int intf_reg = mono_regstate_next_int (s->rs); + int intf_bit_reg = mono_regstate_next_int (s->rs); mini_emit_max_iid_check_class (s, klass_reg, klass, NULL); - mini_emit_load_intf_reg_class (s, intf_reg, klass_reg, klass); - MONO_EMIT_NEW_COMPARE_IMM_EXC (s, EQ, intf_reg, -1, "InvalidCastException"); + mini_emit_load_intf_bit_reg_class (s, intf_bit_reg, klass_reg, klass); + MONO_EMIT_NEW_COMPARE_IMM_EXC (s, EQ, intf_bit_reg, 0, "InvalidCastException"); } static void