Skip to content

Commit 0f4764d

Browse files
committed
Updating Mono mini-amd64 to handle MONO_TYPE_I and MONO_TYPE_U for SIMD operations
1 parent 3b6f168 commit 0f4764d

File tree

1 file changed

+93
-4
lines changed

1 file changed

+93
-4
lines changed

src/mono/mono/mini/mini-amd64.c

Lines changed: 93 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3391,6 +3391,13 @@ simd_type_to_comp_op (int t)
33913391
case MONO_TYPE_I8:
33923392
case MONO_TYPE_U8:
33933393
return OP_PCMPEQQ; // SSE 4.1
3394+
case MONO_TYPE_I:
3395+
case MONO_TYPE_U:
3396+
#if TARGET_SIZEOF_VOID_P == 8
3397+
return OP_PCMPEQQ; // SSE 4.1
3398+
#else
3399+
return OP_PCMPEQD;
3400+
#endif
33943401
default:
33953402
g_assert_not_reached ();
33963403
return -1;
@@ -3413,6 +3420,13 @@ simd_type_to_sub_op (int t)
34133420
case MONO_TYPE_I8:
34143421
case MONO_TYPE_U8:
34153422
return OP_PSUBQ;
3423+
case MONO_TYPE_I:
3424+
case MONO_TYPE_U:
3425+
#if TARGET_SIZEOF_VOID_P == 8
3426+
return OP_PSUBQ;
3427+
#else
3428+
return OP_PSUBD;
3429+
#endif
34163430
default:
34173431
g_assert_not_reached ();
34183432
return -1;
@@ -3432,6 +3446,13 @@ simd_type_to_shl_op (int t)
34323446
case MONO_TYPE_I8:
34333447
case MONO_TYPE_U8:
34343448
return OP_PSHLQ;
3449+
case MONO_TYPE_I:
3450+
case MONO_TYPE_U:
3451+
#if TARGET_SIZEOF_VOID_P == 8
3452+
return OP_PSHLD;
3453+
#else
3454+
return OP_PSHLQ;
3455+
#endif
34353456
default:
34363457
g_assert_not_reached ();
34373458
return -1;
@@ -3454,6 +3475,13 @@ simd_type_to_gt_op (int t)
34543475
case MONO_TYPE_I8:
34553476
case MONO_TYPE_U8:
34563477
return OP_PCMPGTQ; // SSE 4.2
3478+
case MONO_TYPE_I:
3479+
case MONO_TYPE_U:
3480+
#if TARGET_SIZEOF_VOID_P == 8
3481+
return OP_PCMPGTQ; // SSE 4.2
3482+
#else
3483+
return OP_PCMPGTD;
3484+
#endif
34573485
default:
34583486
g_assert_not_reached ();
34593487
return -1;
@@ -3472,6 +3500,13 @@ simd_type_to_max_un_op (int t)
34723500
return OP_PMAXD_UN; // SSE 4.1
34733501
//case MONO_TYPE_U8:
34743502
// return OP_PMAXQ_UN; // AVX
3503+
#if TARGET_SIZEOF_VOID_P == 8
3504+
//case MONO_TYPE_U:
3505+
// return OP_PMAXQ_UN; // AVX
3506+
#else
3507+
case MONO_TYPE_U:
3508+
return OP_PMAXD_UN; // SSE 4.1
3509+
#endif
34753510
default:
34763511
g_assert_not_reached ();
34773512
return -1;
@@ -3494,6 +3529,13 @@ simd_type_to_add_op (int t)
34943529
case MONO_TYPE_I8:
34953530
case MONO_TYPE_U8:
34963531
return OP_PADDQ;
3532+
case MONO_TYPE_I:
3533+
case MONO_TYPE_U:
3534+
#if TARGET_SIZEOF_VOID_P == 8
3535+
return OP_PADDQ;
3536+
#else
3537+
return OP_PADDD;
3538+
#endif
34973539
default:
34983540
g_assert_not_reached ();
34993541
return -1;
@@ -3518,6 +3560,15 @@ simd_type_to_min_op (int t)
35183560
return OP_PMIND_UN; // SSE 4.1
35193561
// case MONO_TYPE_I8: // AVX
35203562
// case MONO_TYPE_U8:
3563+
#if TARGET_SIZEOF_VOID_P == 8
3564+
//case MONO_TYPE_I: // AVX
3565+
//case MONO_TYPE_U:
3566+
#else
3567+
case MONO_TYPE_I:
3568+
return OP_PMIND; // SSE 4.1
3569+
case MONO_TYPE_U:
3570+
return OP_PMIND_UN; // SSE 4.1
3571+
#endif
35213572
default:
35223573
g_assert_not_reached ();
35233574
return -1;
@@ -3542,6 +3593,15 @@ simd_type_to_max_op (int t)
35423593
return OP_PMAXD_UN; // SSE 4.1
35433594
// case MONO_TYPE_I8: // AVX
35443595
// case MONO_TYPE_U8:
3596+
#if TARGET_SIZEOF_VOID_P == 8
3597+
//case MONO_TYPE_I: // AVX
3598+
//case MONO_TYPE_U:
3599+
#else
3600+
case MONO_TYPE_I:
3601+
return OP_PMAXD; // SSE 4.1
3602+
case MONO_TYPE_U:
3603+
return OP_PMAXD_UN; // SSE 4.1
3604+
#endif
35453605
default:
35463606
g_assert_not_reached ();
35473607
return -1;
@@ -3552,8 +3612,13 @@ static void
35523612
emit_simd_comp_op (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, int type, int dreg, int sreg1, int sreg2)
35533613
{
35543614
MonoInst *temp;
3615+
gboolean is64BitNativeInt = FALSE;
35553616

3556-
if (!mono_hwcap_x86_has_sse42 && (ins->inst_c1 == MONO_TYPE_I8 || ins->inst_c1 == MONO_TYPE_U8)) {
3617+
#if TARGET_SIZEOF_VOID_P == 8
3618+
is64BitNativeInt = ins->inst_c1 == MONO_TYPE_I || ins->inst_c1 == MONO_TYPE_U;
3619+
#endif
3620+
3621+
if (!mono_hwcap_x86_has_sse42 && (ins->inst_c1 == MONO_TYPE_I8 || ins->inst_c1 == MONO_TYPE_U8 || is64BitNativeInt)) {
35573622
int temp_reg1 = mono_alloc_ireg (cfg);
35583623
int temp_reg2 = mono_alloc_ireg (cfg);
35593624

@@ -3613,6 +3678,15 @@ emit_simd_gt_un_op (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, int typ
36133678
NEW_SIMD_INS (cfg, ins, temp, simd_type_to_sub_op (type), temp_s2, sreg2, temp_c80);
36143679
emit_simd_gt_op (cfg, bb, ins, type, dreg, temp_s1, temp_s2);
36153680
break;
3681+
3682+
case MONO_TYPE_U:
3683+
#if TARGET_SIZEOF_VOID_P == 8
3684+
goto USE_SIGNED_GT;
3685+
#else
3686+
if (mono_hwcap_x86_has_sse41)
3687+
goto USE_MAX;
3688+
goto USE_SIGNED_GT;
3689+
#endif
36163690
}
36173691
}
36183692
}
@@ -3621,8 +3695,13 @@ static void
36213695
emit_simd_gt_op (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, int type, int dreg, int sreg1, int sreg2)
36223696
{
36233697
MonoInst *temp;
3698+
gboolean is64BitNativeInt = FALSE;
3699+
3700+
#if TARGET_SIZEOF_VOID_P == 8
3701+
is64BitNativeInt = ins->inst_c1 == MONO_TYPE_I || ins->inst_c1 == MONO_TYPE_U;
3702+
#endif
36243703

3625-
if (!mono_hwcap_x86_has_sse42 && (type == MONO_TYPE_I8 || type == MONO_TYPE_U8)) {
3704+
if (!mono_hwcap_x86_has_sse42 && (type == MONO_TYPE_I8 || type == MONO_TYPE_U8 || is64BitNativeInt)) {
36263705
// Decompose 64-bit greater than to 32-bit
36273706
//
36283707
// t = (v1 > v2)
@@ -3663,11 +3742,16 @@ static void
36633742
emit_simd_min_op (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, int type, int dreg, int sreg1, int sreg2)
36643743
{
36653744
MonoInst *temp;
3745+
gboolean is64BitNativeInt = FALSE;
3746+
3747+
#if TARGET_SIZEOF_VOID_P == 8
3748+
is64BitNativeInt = ins->inst_c1 == MONO_TYPE_I || ins->inst_c1 == MONO_TYPE_U;
3749+
#endif
36663750

36673751
if (type == MONO_TYPE_I2 || type == MONO_TYPE_U2) {
36683752
// SSE2, so always available
36693753
NEW_SIMD_INS (cfg, ins, temp, simd_type_to_min_op (type), dreg, sreg1, sreg2);
3670-
} else if (!mono_hwcap_x86_has_sse41 || type == MONO_TYPE_I8 || type == MONO_TYPE_U8) {
3754+
} else if (!mono_hwcap_x86_has_sse41 || type == MONO_TYPE_I8 || type == MONO_TYPE_U8 || is64BitNativeInt) {
36713755
// Decompose to t = (s1 > s2), d = (s1 & !t) | (s2 & t)
36723756
int temp_t = mono_alloc_ireg (cfg);
36733757
int temp_d1 = mono_alloc_ireg (cfg);
@@ -3689,11 +3773,16 @@ static void
36893773
emit_simd_max_op (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, int type, int dreg, int sreg1, int sreg2)
36903774
{
36913775
MonoInst *temp;
3776+
gboolean is64BitNativeInt = FALSE;
3777+
3778+
#if TARGET_SIZEOF_VOID_P == 8
3779+
is64BitNativeInt = ins->inst_c1 == MONO_TYPE_I || ins->inst_c1 == MONO_TYPE_U;
3780+
#endif
36923781

36933782
if (type == MONO_TYPE_I2 || type == MONO_TYPE_U2) {
36943783
// SSE2, so always available
36953784
NEW_SIMD_INS (cfg, ins, temp, simd_type_to_max_op (type), dreg, sreg1, sreg2);
3696-
} else if (!mono_hwcap_x86_has_sse41 || type == MONO_TYPE_I8 || type == MONO_TYPE_U8) {
3785+
} else if (!mono_hwcap_x86_has_sse41 || type == MONO_TYPE_I8 || type == MONO_TYPE_U8 || is64BitNativeInt) {
36973786
// Decompose to t = (s1 > s2), d = (s1 & t) | (s2 & !t)
36983787
int temp_t = mono_alloc_ireg (cfg);
36993788
int temp_d1 = mono_alloc_ireg (cfg);

0 commit comments

Comments
 (0)