aboutsummaryrefslogtreecommitdiff
path: root/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2023-06-14 00:57:02 -0300
committerGitHub <noreply@github.com>2023-06-14 00:57:02 -0300
commit105c9712c1cf8400b3ff34c3a69a8af81ee4431e (patch)
treeb83fa5c26480b4cb37a957fa052b8180f8b8560c /src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
parent4d804ed45e1c00b74714089e26f941e71a1c8c45 (diff)
Fix Arm32 double to int/uint conversion on Arm64 (#5292)1.1.891
* Fix Arm32 double to int/uint conversion on Arm64 * PPTC version bump
Diffstat (limited to 'src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs')
-rw-r--r--src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs74
1 files changed, 55 insertions, 19 deletions
diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
index 33ae83df..bec36e2d 100644
--- a/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
+++ b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
@@ -165,7 +165,7 @@ namespace ARMeilleure.Instructions
{
Operand m = GetVecA32(op.Vm >> 1);
- Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, doubleSize);
+ Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true);
Intrinsic inst = (unsigned ? Intrinsic.Arm64FcvtzuGp : Intrinsic.Arm64FcvtzsGp) | Intrinsic.Arm64VDouble;
@@ -175,7 +175,7 @@ namespace ARMeilleure.Instructions
}
else
{
- InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS);
+ InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS, false);
}
}
else if (!roundWithFpscr && Optimizations.UseSse41)
@@ -260,28 +260,64 @@ namespace ARMeilleure.Instructions
if (Optimizations.UseAdvSimd)
{
- if (unsigned)
+ bool doubleSize = floatSize == OperandType.FP64;
+
+ if (doubleSize)
{
- inst = rm switch {
- 0b00 => Intrinsic.Arm64FcvtauS,
- 0b01 => Intrinsic.Arm64FcvtnuS,
- 0b10 => Intrinsic.Arm64FcvtpuS,
- 0b11 => Intrinsic.Arm64FcvtmuS,
- _ => throw new ArgumentOutOfRangeException(nameof(rm))
- };
+ Operand m = GetVecA32(op.Vm >> 1);
+
+ Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true);
+
+ if (unsigned)
+ {
+ inst = rm switch {
+ 0b00 => Intrinsic.Arm64FcvtauGp,
+ 0b01 => Intrinsic.Arm64FcvtnuGp,
+ 0b10 => Intrinsic.Arm64FcvtpuGp,
+ 0b11 => Intrinsic.Arm64FcvtmuGp,
+ _ => throw new ArgumentOutOfRangeException(nameof(rm))
+ };
+ }
+ else
+ {
+ inst = rm switch {
+ 0b00 => Intrinsic.Arm64FcvtasGp,
+ 0b01 => Intrinsic.Arm64FcvtnsGp,
+ 0b10 => Intrinsic.Arm64FcvtpsGp,
+ 0b11 => Intrinsic.Arm64FcvtmsGp,
+ _ => throw new ArgumentOutOfRangeException(nameof(rm))
+ };
+ }
+
+ Operand asInteger = context.AddIntrinsicInt(inst | Intrinsic.Arm64VDouble, toConvert);
+
+ InsertScalar(context, op.Vd, asInteger);
}
else
{
- inst = rm switch {
- 0b00 => Intrinsic.Arm64FcvtasS,
- 0b01 => Intrinsic.Arm64FcvtnsS,
- 0b10 => Intrinsic.Arm64FcvtpsS,
- 0b11 => Intrinsic.Arm64FcvtmsS,
- _ => throw new ArgumentOutOfRangeException(nameof(rm))
- };
- }
+ if (unsigned)
+ {
+ inst = rm switch {
+ 0b00 => Intrinsic.Arm64FcvtauS,
+ 0b01 => Intrinsic.Arm64FcvtnuS,
+ 0b10 => Intrinsic.Arm64FcvtpuS,
+ 0b11 => Intrinsic.Arm64FcvtmuS,
+ _ => throw new ArgumentOutOfRangeException(nameof(rm))
+ };
+ }
+ else
+ {
+ inst = rm switch {
+ 0b00 => Intrinsic.Arm64FcvtasS,
+ 0b01 => Intrinsic.Arm64FcvtnsS,
+ 0b10 => Intrinsic.Arm64FcvtpsS,
+ 0b11 => Intrinsic.Arm64FcvtmsS,
+ _ => throw new ArgumentOutOfRangeException(nameof(rm))
+ };
+ }
- InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst);
+ InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst);
+ }
}
else if (Optimizations.UseSse41)
{