From 3d67259c9e7bfe5c2b3a77b53658f282b60dc72c Mon Sep 17 00:00:00 2001 From: riperiperi Date: Sat, 18 Jan 2020 17:37:21 +0000 Subject: [PATCH] Add StandardFPSCRValue behaviour to compare instructions. --- ARMeilleure/Instructions/InstEmitSimdCmp32.cs | 51 +++------ ARMeilleure/Instructions/SoftFloat.cs | 104 ++++++++++++++---- 2 files changed, 95 insertions(+), 60 deletions(-) diff --git a/ARMeilleure/Instructions/InstEmitSimdCmp32.cs b/ARMeilleure/Instructions/InstEmitSimdCmp32.cs index 0007030e2e..bb119d9f47 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCmp32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCmp32.cs @@ -16,7 +16,7 @@ namespace ARMeilleure.Instructions { public static void Vceq_V(ArmEmitterContext context) { - EmitCmpOpF32(context, SoftFloat32.FPCompareEQ, SoftFloat64.FPCompareEQ, false); + EmitCmpOpF32(context, SoftFloat32.FPCompareEQFpscr, SoftFloat64.FPCompareEQFpscr, false); } public static void Vceq_I(ArmEmitterContext context) @@ -30,7 +30,7 @@ namespace ARMeilleure.Instructions OpCode32Simd op = (OpCode32Simd)context.CurrOp; if (op.F) { - EmitCmpOpF32(context, SoftFloat32.FPCompareEQ, SoftFloat64.FPCompareEQ, true); + EmitCmpOpF32(context, SoftFloat32.FPCompareEQFpscr, SoftFloat64.FPCompareEQFpscr, true); } else { @@ -40,7 +40,7 @@ namespace ARMeilleure.Instructions public static void Vcge_V(ArmEmitterContext context) { - EmitCmpOpF32(context, SoftFloat32.FPCompareGE, SoftFloat64.FPCompareGE, false); + EmitCmpOpF32(context, SoftFloat32.FPCompareGEFpscr, SoftFloat64.FPCompareGEFpscr, false); } public static void Vcge_I(ArmEmitterContext context) @@ -54,7 +54,7 @@ namespace ARMeilleure.Instructions OpCode32Simd op = (OpCode32Simd)context.CurrOp; if (op.F) { - EmitCmpOpF32(context, SoftFloat32.FPCompareGE, SoftFloat64.FPCompareGE, true); + EmitCmpOpF32(context, SoftFloat32.FPCompareGEFpscr, SoftFloat64.FPCompareGEFpscr, true); } else { @@ -64,7 +64,7 @@ namespace ARMeilleure.Instructions public static void Vcgt_V(ArmEmitterContext context) { - EmitCmpOpF32(context, SoftFloat32.FPCompareGT, SoftFloat64.FPCompareGT, false); + EmitCmpOpF32(context, SoftFloat32.FPCompareGTFpscr, SoftFloat64.FPCompareGTFpscr, false); } public static void Vcgt_I(ArmEmitterContext context) @@ -78,7 +78,7 @@ namespace ARMeilleure.Instructions OpCode32Simd op = (OpCode32Simd)context.CurrOp; if (op.F) { - EmitCmpOpF32(context, SoftFloat32.FPCompareGT, SoftFloat64.FPCompareGT, true); + EmitCmpOpF32(context, SoftFloat32.FPCompareGTFpscr, SoftFloat64.FPCompareGTFpscr, true); } else { @@ -86,23 +86,12 @@ namespace ARMeilleure.Instructions } } - public static void Vcle_V(ArmEmitterContext context) - { - EmitCmpOpF32(context, SoftFloat32.FPCompareLE, SoftFloat64.FPCompareLE, false); - } - - public static void Vcle_I(ArmEmitterContext context) - { - OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp; - EmitCmpOpI32(context, context.ICompareLessOrEqual, context.ICompareLessOrEqualUI, false, !op.U); - } - public static void Vcle_Z(ArmEmitterContext context) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; if (op.F) { - EmitCmpOpF32(context, SoftFloat32.FPCompareLE, SoftFloat64.FPCompareLE, true); + EmitCmpOpF32(context, SoftFloat32.FPCompareLEFpscr, SoftFloat64.FPCompareLEFpscr, true); } else { @@ -110,23 +99,12 @@ namespace ARMeilleure.Instructions } } - public static void Vclt_V(ArmEmitterContext context) - { - EmitCmpOpF32(context, SoftFloat32.FPCompareLT, SoftFloat64.FPCompareLT, false); - } - - public static void Vclt_I(ArmEmitterContext context) - { - OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp; - EmitCmpOpI32(context, context.ICompareLess, context.ICompareLessUI, false, !op.U); - } - public static void Vclt_Z(ArmEmitterContext context) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; if (op.F) { - EmitCmpOpF32(context, SoftFloat32.FPCompareLT, SoftFloat64.FPCompareLT, true); + EmitCmpOpF32(context, SoftFloat32.FPCompareLTFpscr, SoftFloat64.FPCompareLTFpscr, true); } else { @@ -136,18 +114,19 @@ namespace ARMeilleure.Instructions private static void EmitCmpOpF32( ArmEmitterContext context, - _F32_F32_F32 f32, - _F64_F64_F64 f64, + _F32_F32_F32_Bool f32, + _F64_F64_F64_Bool f64, bool zero) { + Operand one = Const(1); if (zero) { EmitVectorUnaryOpF32(context, (m) => { OperandType type = m.Type; - if (type == OperandType.FP64) return context.Call(f64, m, new Operand(0.0)); - else return context.Call(f32, m, new Operand(0.0)); + if (type == OperandType.FP64) return context.Call(f64, m, new Operand(0.0), one); + else return context.Call(f32, m, new Operand(0.0), one); }); } else @@ -156,8 +135,8 @@ namespace ARMeilleure.Instructions { OperandType type = n.Type; - if (type == OperandType.FP64) return context.Call(f64, n, m); - else return context.Call(f32, n, m); + if (type == OperandType.FP64) return context.Call(f64, n, m, one); + else return context.Call(f32, n, m, one); }); } } diff --git a/ARMeilleure/Instructions/SoftFloat.cs b/ARMeilleure/Instructions/SoftFloat.cs index 1963ece2a7..3a5ac1ec6c 100644 --- a/ARMeilleure/Instructions/SoftFloat.cs +++ b/ARMeilleure/Instructions/SoftFloat.cs @@ -708,10 +708,16 @@ namespace ARMeilleure.Instructions public static float FPCompareEQ(float value1, float value2) { - ExecutionContext context = NativeInterface.GetContext(); + return FPCompareEQFpscr(value1, value2, false); + } - value1 = value1.FPUnpack(out FPType type1, out _, out _, context); - value2 = value2.FPUnpack(out FPType type2, out _, out _, context); + public static float FPCompareEQFpscr(float value1, float value2, bool standardFpscr) + { + ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; + + value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr); float result; @@ -721,7 +727,7 @@ namespace ARMeilleure.Instructions if (type1 == FPType.SNaN || type2 == FPType.SNaN) { - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } } else @@ -734,10 +740,16 @@ namespace ARMeilleure.Instructions public static float FPCompareGE(float value1, float value2) { - ExecutionContext context = NativeInterface.GetContext(); + return FPCompareGEFpscr(value1, value2, false); + } - value1 = value1.FPUnpack(out FPType type1, out _, out _, context); - value2 = value2.FPUnpack(out FPType type2, out _, out _, context); + public static float FPCompareGEFpscr(float value1, float value2, bool standardFpscr) + { + ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; + + value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr); float result; @@ -745,7 +757,7 @@ namespace ARMeilleure.Instructions { result = ZerosOrOnes(false); - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } else { @@ -757,10 +769,16 @@ namespace ARMeilleure.Instructions public static float FPCompareGT(float value1, float value2) { - ExecutionContext context = NativeInterface.GetContext(); + return FPCompareGTFpscr(value1, value2, false); + } - value1 = value1.FPUnpack(out FPType type1, out _, out _, context); - value2 = value2.FPUnpack(out FPType type2, out _, out _, context); + public static float FPCompareGTFpscr(float value1, float value2, bool standardFpscr) + { + ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; + + value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr); float result; @@ -768,7 +786,7 @@ namespace ARMeilleure.Instructions { result = ZerosOrOnes(false); - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } else { @@ -788,6 +806,16 @@ namespace ARMeilleure.Instructions return FPCompareGT(value2, value1); } + public static float FPCompareLEFpscr(float value1, float value2, bool standardFpscr) + { + return FPCompareGEFpscr(value2, value1, standardFpscr); + } + + public static float FPCompareLTFpscr(float value1, float value2, bool standardFpscr) + { + return FPCompareGTFpscr(value2, value1, standardFpscr); + } + public static float FPDiv(float value1, float value2) { ExecutionContext context = NativeInterface.GetContext(); @@ -1971,10 +1999,16 @@ namespace ARMeilleure.Instructions public static double FPCompareEQ(double value1, double value2) { - ExecutionContext context = NativeInterface.GetContext(); + return FPCompareEQFpscr(value1, value2, false); + } - value1 = value1.FPUnpack(out FPType type1, out _, out _, context); - value2 = value2.FPUnpack(out FPType type2, out _, out _, context); + public static double FPCompareEQFpscr(double value1, double value2, bool standardFpscr) + { + ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; + + value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr); double result; @@ -1984,7 +2018,7 @@ namespace ARMeilleure.Instructions if (type1 == FPType.SNaN || type2 == FPType.SNaN) { - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } } else @@ -1997,10 +2031,16 @@ namespace ARMeilleure.Instructions public static double FPCompareGE(double value1, double value2) { - ExecutionContext context = NativeInterface.GetContext(); + return FPCompareGEFpscr(value1, value2, false); + } - value1 = value1.FPUnpack(out FPType type1, out _, out _, context); - value2 = value2.FPUnpack(out FPType type2, out _, out _, context); + public static double FPCompareGEFpscr(double value1, double value2, bool standardFpscr) + { + ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; + + value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr); double result; @@ -2008,7 +2048,7 @@ namespace ARMeilleure.Instructions { result = ZerosOrOnes(false); - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } else { @@ -2020,10 +2060,16 @@ namespace ARMeilleure.Instructions public static double FPCompareGT(double value1, double value2) { - ExecutionContext context = NativeInterface.GetContext(); + return FPCompareGTFpscr(value1, value2, false); + } - value1 = value1.FPUnpack(out FPType type1, out _, out _, context); - value2 = value2.FPUnpack(out FPType type2, out _, out _, context); + public static double FPCompareGTFpscr(double value1, double value2, bool standardFpscr) + { + ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; + + value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr); double result; @@ -2031,7 +2077,7 @@ namespace ARMeilleure.Instructions { result = ZerosOrOnes(false); - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } else { @@ -2051,6 +2097,16 @@ namespace ARMeilleure.Instructions return FPCompareGT(value2, value1); } + public static double FPCompareLEFpscr(double value1, double value2, bool standardFpscr) + { + return FPCompareGEFpscr(value2, value1, standardFpscr); + } + + public static double FPCompareLTFpscr(double value1, double value2, bool standardFpscr) + { + return FPCompareGTFpscr(value2, value1, standardFpscr); + } + public static double FPDiv(double value1, double value2) { ExecutionContext context = NativeInterface.GetContext();