aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/Instructions/InstEmitSimdCvt32.cs')
-rw-r--r--ARMeilleure/Instructions/InstEmitSimdCvt32.cs49
1 files changed, 41 insertions, 8 deletions
diff --git a/ARMeilleure/Instructions/InstEmitSimdCvt32.cs b/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
index 69ba4274..c76634eb 100644
--- a/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
+++ b/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
@@ -203,6 +203,9 @@ namespace ARMeilleure.Instructions
FPRoundingMode roundMode;
switch (rm)
{
+ case 0b00:
+ roundMode = FPRoundingMode.ToNearestAway;
+ break;
case 0b01:
roundMode = FPRoundingMode.ToNearest;
break;
@@ -228,7 +231,7 @@ namespace ARMeilleure.Instructions
bool unsigned = op.Opc == 0;
int rm = op.Opc2 & 3;
- if (Optimizations.UseSse41 && rm != 0b00)
+ if (Optimizations.UseSse41)
{
EmitSse41ConvertInt32(context, RMToRoundMode(rm), !unsigned);
}
@@ -267,15 +270,21 @@ namespace ARMeilleure.Instructions
int rm = op.Opc2 & 3;
- if (Optimizations.UseSse2 && rm != 0b00)
+ if (Optimizations.UseSse41)
{
EmitScalarUnaryOpSimd32(context, (m) =>
{
- Intrinsic inst = (op.Size & 1) == 0 ? Intrinsic.X86Roundss : Intrinsic.X86Roundsd;
-
FPRoundingMode roundMode = RMToRoundMode(rm);
- return context.AddIntrinsic(inst, m, Const(X86GetRoundControl(roundMode)));
+ if (roundMode != FPRoundingMode.ToNearestAway)
+ {
+ Intrinsic inst = (op.Size & 1) == 0 ? Intrinsic.X86Roundss : Intrinsic.X86Roundsd;
+ return context.AddIntrinsic(inst, m, Const(X86GetRoundControl(roundMode)));
+ }
+ else
+ {
+ return EmitSse41RoundToNearestWithTiesToAwayOpF(context, m, scalar: true);
+ }
});
}
else
@@ -305,7 +314,17 @@ namespace ARMeilleure.Instructions
// VRINTA (vector).
public static void Vrinta_V(ArmEmitterContext context)
{
- EmitVectorUnaryOpF32(context, (m) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, m));
+ if (Optimizations.UseSse41)
+ {
+ EmitVectorUnaryOpSimd32(context, (m) =>
+ {
+ return EmitSse41RoundToNearestWithTiesToAwayOpF(context, m, scalar: false);
+ });
+ }
+ else
+ {
+ EmitVectorUnaryOpF32(context, (m) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, m));
+ }
}
// VRINTM (vector).
@@ -413,7 +432,14 @@ namespace ARMeilleure.Instructions
Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmpss, n, n, Const((int)CmpCondition.OrderedQ));
nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n);
- nRes = context.AddIntrinsic(Intrinsic.X86Roundss, nRes, Const(X86GetRoundControl(roundMode)));
+ if (roundMode != FPRoundingMode.ToNearestAway)
+ {
+ nRes = context.AddIntrinsic(Intrinsic.X86Roundss, nRes, Const(X86GetRoundControl(roundMode)));
+ }
+ else
+ {
+ nRes = EmitSse41RoundToNearestWithTiesToAwayOpF(context, nRes, scalar: true);
+ }
Operand zero = context.VectorZero();
@@ -464,7 +490,14 @@ namespace ARMeilleure.Instructions
Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmpsd, n, n, Const((int)CmpCondition.OrderedQ));
nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n);
- nRes = context.AddIntrinsic(Intrinsic.X86Roundsd, nRes, Const(X86GetRoundControl(roundMode)));
+ if (roundMode != FPRoundingMode.ToNearestAway)
+ {
+ nRes = context.AddIntrinsic(Intrinsic.X86Roundsd, nRes, Const(X86GetRoundControl(roundMode)));
+ }
+ else
+ {
+ nRes = EmitSse41RoundToNearestWithTiesToAwayOpF(context, nRes, scalar: true);
+ }
Operand zero = context.VectorZero();