@@ -2119,7 +2119,17 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas
21192119 } else if (!strcmp (tm , "AreSame ")) {
21202120 * op = MINT_CEQ_P ;
21212121 } else if (!strcmp (tm , "ByteOffset ")) {
2122- * op = MINT_INTRINS_UNSAFE_BYTE_OFFSET ;
2122+ #if SIZEOF_VOID_P == 4
2123+ interp_add_ins (td , MINT_SUB_I4 );
2124+ #else
2125+ interp_add_ins (td , MINT_SUB_I8 );
2126+ #endif
2127+ td -> sp -= 2 ;
2128+ interp_ins_set_sregs2 (td -> last_ins , td -> sp [1 ].local , td -> sp [0 ].local );
2129+ push_simple_type (td , STACK_TYPE_I );
2130+ interp_ins_set_dreg (td -> last_ins , td -> sp [-1 ].local );
2131+ td -> ip += 5 ;
2132+ return TRUE;
21232133 } else if (!strcmp (tm , "Unbox ")) {
21242134 MonoGenericContext * ctx = mono_method_get_context (target_method );
21252135 g_assert (ctx );
@@ -9873,6 +9883,39 @@ interp_super_instructions (TransformData *td)
98739883 dump_interp_inst (new_inst );
98749884 }
98759885 }
9886+ } else if (opcode == MINT_DIV_UN_I4 || opcode == MINT_DIV_UN_I8 ) {
9887+ // ldc + div.un -> shr.imm
9888+ int sreg_imm = ins -> sregs [1 ];
9889+ InterpInst * def = td -> locals [sreg_imm ].def ;
9890+ if (def != NULL && td -> local_ref_count [sreg_imm ] == 1 ) {
9891+ int power2 = -1 ;
9892+ if (MINT_IS_LDC_I4 (def -> opcode )) {
9893+ guint32 ct = interp_get_const_from_ldc_i4 (def );
9894+ power2 = mono_is_power_of_two ((guint32 )ct );
9895+ } else if (MINT_IS_LDC_I8 (def -> opcode )) {
9896+ guint64 ct = interp_get_const_from_ldc_i8 (def );
9897+ if (ct < G_MAXUINT32 )
9898+ power2 = mono_is_power_of_two ((guint32 )ct );
9899+ }
9900+ if (power2 > 0 ) {
9901+ InterpInst * new_inst ;
9902+ if (opcode == MINT_DIV_UN_I4 )
9903+ new_inst = interp_insert_ins (td , ins , MINT_SHR_UN_I4_IMM );
9904+ else
9905+ new_inst = interp_insert_ins (td , ins , MINT_SHR_UN_I8_IMM );
9906+ new_inst -> dreg = ins -> dreg ;
9907+ new_inst -> sregs [0 ] = ins -> sregs [0 ];
9908+ new_inst -> data [0 ] = power2 ;
9909+
9910+ interp_clear_ins (def );
9911+ interp_clear_ins (ins );
9912+ local_ref_count [sreg_imm ]-- ;
9913+ if (td -> verbose_level ) {
9914+ g_print ("lower div.un: " );
9915+ dump_interp_inst (new_inst );
9916+ }
9917+ }
9918+ }
98769919 } else if (MINT_IS_LDIND_INT (opcode )) {
98779920 int sreg_base = ins -> sregs [0 ];
98789921 InterpInst * def = td -> locals [sreg_base ].def ;
0 commit comments