Skip to content

Commit d05d6c2

Browse files
Have mono handle ConvertToIntegerNative for Double and Single (#112206)
* Have mono handle ConvertToIntegerNative for Double and Single * Ensure indirect calls on Mono produce the expected result for ConvertToInteger native * Ensure the mono interpreter also handles ConvertToIntegerNative for double and single * Ensure mono uses OP_RCONV_TO_* for Single.ConvertIntegerToNative * Ensure we decompose the opcode to support ones that are emulated
1 parent 4dfe657 commit d05d6c2

File tree

4 files changed

+106
-7
lines changed

4 files changed

+106
-7
lines changed

src/libraries/System.Private.CoreLib/src/System/Double.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -665,15 +665,12 @@ public static TInteger ConvertToInteger<TInteger>(double value)
665665
public static TInteger ConvertToIntegerNative<TInteger>(double value)
666666
where TInteger : IBinaryInteger<TInteger>
667667
{
668-
#if !MONO
669668
if (typeof(TInteger).IsPrimitive)
670669
{
671670
// We need this to be recursive so indirect calls (delegates
672671
// for example) produce the same result as direct invocation
673672
return ConvertToIntegerNative<TInteger>(value);
674673
}
675-
#endif
676-
677674
return TInteger.CreateSaturating(value);
678675
}
679676

src/libraries/System.Private.CoreLib/src/System/Single.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -660,15 +660,12 @@ public static TInteger ConvertToInteger<TInteger>(float value)
660660
public static TInteger ConvertToIntegerNative<TInteger>(float value)
661661
where TInteger : IBinaryInteger<TInteger>
662662
{
663-
#if !MONO
664663
if (typeof(TInteger).IsPrimitive)
665664
{
666665
// We need this to be recursive so indirect calls (delegates
667666
// for example) produce the same result as direct invocation
668667
return ConvertToIntegerNative<TInteger>(value);
669668
}
670-
#endif
671-
672669
return TInteger.CreateSaturating(value);
673670
}
674671

src/mono/mono/mini/interp/transform.c

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2676,7 +2676,54 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas
26762676
!strncmp ("Vector", klass_name, 6) &&
26772677
!strcmp (tm, "get_IsHardwareAccelerated"))) {
26782678
*op = MINT_LDC_I4_0;
2679-
}
2679+
} else if ((target_method->klass == mono_defaults.double_class) || (target_method->klass == mono_defaults.single_class)) {
2680+
MonoGenericContext *method_context = mono_method_get_context (target_method);
2681+
bool isDouble = target_method->klass == mono_defaults.double_class;
2682+
if (!strcmp (tm, "ConvertToIntegerNative") &&
2683+
method_context != NULL &&
2684+
method_context->method_inst->type_argc == 1) {
2685+
MonoTypeEnum tto_type = method_context->method_inst->type_argv [0]->type;
2686+
switch (tto_type) {
2687+
case MONO_TYPE_I1:
2688+
*op = isDouble ? MINT_CONV_I1_R8 : MINT_CONV_I1_R4;
2689+
break;
2690+
case MONO_TYPE_I2:
2691+
*op = isDouble ? MINT_CONV_I2_R8 : MINT_CONV_I2_R4;
2692+
break;
2693+
#if TARGET_SIZEOF_VOID_P == 4
2694+
case MONO_TYPE_I:
2695+
#endif
2696+
case MONO_TYPE_I4:
2697+
*op = isDouble ? MINT_CONV_I4_R8 : MINT_CONV_I4_R4;
2698+
break;
2699+
#if TARGET_SIZEOF_VOID_P == 8
2700+
case MONO_TYPE_I:
2701+
#endif
2702+
case MONO_TYPE_I8:
2703+
*op = isDouble ? MINT_CONV_I8_R8 : MINT_CONV_I8_R4;
2704+
break;
2705+
case MONO_TYPE_U1:
2706+
*op = isDouble ? MINT_CONV_U1_R8 : MINT_CONV_U1_R4;
2707+
break;
2708+
case MONO_TYPE_U2:
2709+
*op = isDouble ? MINT_CONV_U2_R8 : MINT_CONV_U2_R4;
2710+
break;
2711+
#if TARGET_SIZEOF_VOID_P == 4
2712+
case MONO_TYPE_U:
2713+
#endif
2714+
case MONO_TYPE_U4:
2715+
*op = isDouble ? MINT_CONV_U4_R8 : MINT_CONV_U4_R4;
2716+
break;
2717+
#if TARGET_SIZEOF_VOID_P == 8
2718+
case MONO_TYPE_U:
2719+
#endif
2720+
case MONO_TYPE_U8:
2721+
*op = isDouble ? MINT_CONV_U8_R8 : MINT_CONV_U8_R4;
2722+
break;
2723+
default: return FALSE;
2724+
}
2725+
}
2726+
}
26802727

26812728
return FALSE;
26822729
}

src/mono/mono/mini/intrinsics.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2322,6 +2322,64 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
23222322
return ins;
23232323
}
23242324
}
2325+
} else if ((cmethod->klass == mono_defaults.double_class) || (cmethod->klass == mono_defaults.single_class)) {
2326+
MonoGenericContext *method_context = mono_method_get_context (cmethod);
2327+
bool isDouble = cmethod->klass == mono_defaults.double_class;
2328+
if (!strcmp (cmethod->name, "ConvertToIntegerNative") &&
2329+
method_context != NULL &&
2330+
method_context->method_inst->type_argc == 1) {
2331+
int opcode = 0;
2332+
MonoTypeEnum tto_type = method_context->method_inst->type_argv [0]->type;
2333+
MonoStackType tto_stack = STACK_I4;
2334+
switch (tto_type) {
2335+
case MONO_TYPE_I1:
2336+
opcode = isDouble ? OP_FCONV_TO_I1 : OP_RCONV_TO_I1;
2337+
break;
2338+
case MONO_TYPE_I2:
2339+
opcode = isDouble ? OP_FCONV_TO_I2 : OP_RCONV_TO_I2;
2340+
break;
2341+
#if TARGET_SIZEOF_VOID_P == 4
2342+
case MONO_TYPE_I:
2343+
#endif
2344+
case MONO_TYPE_I4:
2345+
opcode = isDouble ? OP_FCONV_TO_I4 : OP_RCONV_TO_I4;
2346+
break;
2347+
#if TARGET_SIZEOF_VOID_P == 8
2348+
case MONO_TYPE_I:
2349+
#endif
2350+
case MONO_TYPE_I8:
2351+
opcode = isDouble ? OP_FCONV_TO_I8 : OP_RCONV_TO_I8;
2352+
tto_stack = STACK_I8;
2353+
break;
2354+
case MONO_TYPE_U1:
2355+
opcode = isDouble ? OP_FCONV_TO_U1 : OP_RCONV_TO_U1;
2356+
break;
2357+
case MONO_TYPE_U2:
2358+
opcode = isDouble ? OP_FCONV_TO_U2 : OP_RCONV_TO_U2;
2359+
break;
2360+
#if TARGET_SIZEOF_VOID_P == 4
2361+
case MONO_TYPE_U:
2362+
#endif
2363+
case MONO_TYPE_U4:
2364+
opcode = isDouble ? OP_FCONV_TO_U4 : OP_RCONV_TO_U4;
2365+
break;
2366+
#if TARGET_SIZEOF_VOID_P == 8
2367+
case MONO_TYPE_U:
2368+
#endif
2369+
case MONO_TYPE_U8:
2370+
opcode = isDouble ? OP_FCONV_TO_U8 : OP_RCONV_TO_U8;
2371+
tto_stack = STACK_I8;
2372+
break;
2373+
default: return NULL;
2374+
}
2375+
2376+
if (opcode != 0) {
2377+
int ireg = mono_alloc_ireg (cfg);
2378+
EMIT_NEW_UNALU (cfg, ins, opcode, ireg, args [0]->dreg);
2379+
ins->type = tto_stack;
2380+
return mono_decompose_opcode(cfg, ins);
2381+
}
2382+
}
23252383
}
23262384

23272385
ins = mono_emit_simd_intrinsics (cfg, cmethod, fsig, args);

0 commit comments

Comments
 (0)