diff --git a/ARMeilleure/Instructions/SoftFloat.cs b/ARMeilleure/Instructions/SoftFloat.cs index 3a5ac1ec6c..9a358e062a 100644 --- a/ARMeilleure/Instructions/SoftFloat.cs +++ b/ARMeilleure/Instructions/SoftFloat.cs @@ -624,11 +624,12 @@ namespace ARMeilleure.Instructions public static float FPAdd(float value1, float value2) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context, fpcr); - float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, context.Fpcr); + float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { @@ -639,7 +640,7 @@ namespace ARMeilleure.Instructions { result = FPDefaultNaN(); - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } else if ((inf1 && !sign1) || (inf2 && !sign2)) { @@ -657,7 +658,7 @@ namespace ARMeilleure.Instructions { result = value1 + value2; - if ((context.Fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) + if ((fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) { context.Fpsr |= FPSR.Ufc; @@ -672,9 +673,10 @@ namespace ARMeilleure.Instructions public static int FPCompare(float value1, float value2, bool signalNaNs) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out _, context); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out _, context); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out _, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out _, context, fpcr); int result; @@ -684,7 +686,7 @@ namespace ARMeilleure.Instructions if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs) { - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } } else @@ -819,11 +821,12 @@ namespace ARMeilleure.Instructions public static float FPDiv(float value1, float value2) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context, fpcr); - float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, context.Fpcr); + float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { @@ -834,7 +837,7 @@ namespace ARMeilleure.Instructions { result = FPDefaultNaN(); - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } else if (inf1 || zero2) { @@ -842,7 +845,7 @@ namespace ARMeilleure.Instructions if (!inf1) { - FPProcessException(FPException.DivideByZero, context); + FPProcessException(FPException.DivideByZero, context, fpcr); } } else if (zero1 || inf2) @@ -853,7 +856,7 @@ namespace ARMeilleure.Instructions { result = value1 / value2; - if ((context.Fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) + if ((fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) { context.Fpsr |= FPSR.Ufc; @@ -1168,11 +1171,12 @@ namespace ARMeilleure.Instructions public static float FPMulX(float value1, float value2) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context, fpcr); - float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, context.Fpcr); + float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { @@ -1195,7 +1199,7 @@ namespace ARMeilleure.Instructions { result = value1 * value2; - if ((context.Fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) + if ((fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) { context.Fpsr |= FPSR.Ufc; @@ -1351,13 +1355,14 @@ namespace ARMeilleure.Instructions public static float FPRecipStepFused(float value1, float value2) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; value1 = value1.FPNeg(); - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context, fpcr); - float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, context.Fpcr); + float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { @@ -1376,7 +1381,7 @@ namespace ARMeilleure.Instructions { result = MathF.FusedMultiplyAdd(value1, value2, 2f); - if ((context.Fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) + if ((fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) { context.Fpsr |= FPSR.Ufc; @@ -1391,14 +1396,15 @@ namespace ARMeilleure.Instructions public static float FPRecpX(float value) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; - value.FPUnpack(out FPType type, out bool sign, out uint op, context); + value.FPUnpack(out FPType type, out bool sign, out uint op, context, fpcr); float result; if (type == FPType.SNaN || type == FPType.QNaN) { - result = FPProcessNaN(type, op, context, context.Fpcr); + result = FPProcessNaN(type, op, context, fpcr); } else { @@ -1498,7 +1504,7 @@ namespace ARMeilleure.Instructions { result = FPDefaultNaN(); - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } else if ((inf1 && !sign1) || (inf2 && sign2)) { @@ -1561,13 +1567,14 @@ namespace ARMeilleure.Instructions public static float FPRSqrtStepFused(float value1, float value2) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; value1 = value1.FPNeg(); - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context, fpcr); - float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, context.Fpcr); + float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { @@ -1586,7 +1593,7 @@ namespace ARMeilleure.Instructions { result = MathF.FusedMultiplyAdd(value1, value2, 3f) / 2f; - if ((context.Fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) + if ((fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) { context.Fpsr |= FPSR.Ufc; @@ -1601,14 +1608,15 @@ namespace ARMeilleure.Instructions public static float FPSqrt(float value) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; - value = value.FPUnpack(out FPType type, out bool sign, out uint op, context); + value = value.FPUnpack(out FPType type, out bool sign, out uint op, context, fpcr); float result; if (type == FPType.SNaN || type == FPType.QNaN) { - result = FPProcessNaN(type, op, context, context.Fpcr); + result = FPProcessNaN(type, op, context, fpcr); } else if (type == FPType.Zero) { @@ -1622,13 +1630,13 @@ namespace ARMeilleure.Instructions { result = FPDefaultNaN(); - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } else { result = MathF.Sqrt(value); - if ((context.Fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) + if ((fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) { context.Fpsr |= FPSR.Ufc; @@ -1738,16 +1746,6 @@ namespace ARMeilleure.Instructions return BitConverter.Int32BitsToSingle(ones ? -1 : 0); } - private static float FPUnpack( - this float value, - out FPType type, - out bool sign, - out uint valueBits, - ExecutionContext context) - { - return FPUnpack(value, out type, out sign, out valueBits, context, context.Fpcr); - } - private static float FPUnpack( this float value, out FPType type, @@ -1769,7 +1767,7 @@ namespace ARMeilleure.Instructions if ((valueBits & 0x007FFFFFu) != 0u) { - FPProcessException(FPException.InputDenorm, context); + FPProcessException(FPException.InputDenorm, context, fpcr); } } else @@ -1890,11 +1888,6 @@ namespace ARMeilleure.Instructions return BitConverter.Int32BitsToSingle((int)op); } - private static void FPProcessException(FPException exc, ExecutionContext context) - { - FPProcessException(exc, context, context.Fpcr); - } - private static void FPProcessException(FPException exc, ExecutionContext context, FPCR fpcr) { int enable = (int)exc + 8; @@ -1915,11 +1908,12 @@ namespace ARMeilleure.Instructions public static double FPAdd(double value1, double value2) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context, fpcr); - double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, context.Fpcr); + double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { @@ -1930,7 +1924,7 @@ namespace ARMeilleure.Instructions { result = FPDefaultNaN(); - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } else if ((inf1 && !sign1) || (inf2 && !sign2)) { @@ -1948,7 +1942,7 @@ namespace ARMeilleure.Instructions { result = value1 + value2; - if ((context.Fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) + if ((fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) { context.Fpsr |= FPSR.Ufc; @@ -1963,9 +1957,10 @@ namespace ARMeilleure.Instructions public static int FPCompare(double value1, double value2, bool signalNaNs) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out _, context); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out _, context); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out _, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out _, context, fpcr); int result; @@ -1975,7 +1970,7 @@ namespace ARMeilleure.Instructions if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs) { - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } } else @@ -2110,11 +2105,12 @@ namespace ARMeilleure.Instructions public static double FPDiv(double value1, double value2) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context, fpcr); - double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, context.Fpcr); + double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { @@ -2125,7 +2121,7 @@ namespace ARMeilleure.Instructions { result = FPDefaultNaN(); - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } else if (inf1 || zero2) { @@ -2133,7 +2129,7 @@ namespace ARMeilleure.Instructions if (!inf1) { - FPProcessException(FPException.DivideByZero, context); + FPProcessException(FPException.DivideByZero, context, fpcr); } } else if (zero1 || inf2) @@ -2144,7 +2140,7 @@ namespace ARMeilleure.Instructions { result = value1 / value2; - if ((context.Fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) + if ((fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) { context.Fpsr |= FPSR.Ufc; @@ -2397,7 +2393,7 @@ namespace ARMeilleure.Instructions { result = FPDefaultNaN(); - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } if (!done) @@ -2459,11 +2455,12 @@ namespace ARMeilleure.Instructions public static double FPMulX(double value1, double value2) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context, fpcr); - double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, context.Fpcr); + double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { @@ -2486,7 +2483,7 @@ namespace ARMeilleure.Instructions { result = value1 * value2; - if ((context.Fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) + if ((fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) { context.Fpsr |= FPSR.Ufc; @@ -2642,13 +2639,14 @@ namespace ARMeilleure.Instructions public static double FPRecipStepFused(double value1, double value2) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; value1 = value1.FPNeg(); - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context, fpcr); - double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, context.Fpcr); + double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { @@ -2667,7 +2665,7 @@ namespace ARMeilleure.Instructions { result = Math.FusedMultiplyAdd(value1, value2, 2d); - if ((context.Fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) + if ((fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) { context.Fpsr |= FPSR.Ufc; @@ -2682,14 +2680,15 @@ namespace ARMeilleure.Instructions public static double FPRecpX(double value) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; - value.FPUnpack(out FPType type, out bool sign, out ulong op, context); + value.FPUnpack(out FPType type, out bool sign, out ulong op, context, fpcr); double result; if (type == FPType.SNaN || type == FPType.QNaN) { - result = FPProcessNaN(type, op, context, context.Fpcr); + result = FPProcessNaN(type, op, context, fpcr); } else { @@ -2852,13 +2851,14 @@ namespace ARMeilleure.Instructions public static double FPRSqrtStepFused(double value1, double value2) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; value1 = value1.FPNeg(); - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context, fpcr); - double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, context.Fpcr); + double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { @@ -2877,7 +2877,7 @@ namespace ARMeilleure.Instructions { result = Math.FusedMultiplyAdd(value1, value2, 3d) / 2d; - if ((context.Fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) + if ((fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) { context.Fpsr |= FPSR.Ufc; @@ -2892,14 +2892,15 @@ namespace ARMeilleure.Instructions public static double FPSqrt(double value) { ExecutionContext context = NativeInterface.GetContext(); + FPCR fpcr = context.Fpcr; - value = value.FPUnpack(out FPType type, out bool sign, out ulong op, context); + value = value.FPUnpack(out FPType type, out bool sign, out ulong op, context, fpcr); double result; if (type == FPType.SNaN || type == FPType.QNaN) { - result = FPProcessNaN(type, op, context, context.Fpcr); + result = FPProcessNaN(type, op, context, fpcr); } else if (type == FPType.Zero) { @@ -2913,13 +2914,13 @@ namespace ARMeilleure.Instructions { result = FPDefaultNaN(); - FPProcessException(FPException.InvalidOp, context); + FPProcessException(FPException.InvalidOp, context, fpcr); } else { result = Math.Sqrt(value); - if ((context.Fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) + if ((fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) { context.Fpsr |= FPSR.Ufc; @@ -3029,16 +3030,6 @@ namespace ARMeilleure.Instructions return BitConverter.Int64BitsToDouble(ones ? -1L : 0L); } - private static double FPUnpack( - this double value, - out FPType type, - out bool sign, - out ulong valueBits, - ExecutionContext context) - { - return FPUnpack(value, out type, out sign, out valueBits, context, context.Fpcr); - } - private static double FPUnpack( this double value, out FPType type, @@ -3060,7 +3051,7 @@ namespace ARMeilleure.Instructions if ((valueBits & 0x000FFFFFFFFFFFFFul) != 0ul) { - FPProcessException(FPException.InputDenorm, context); + FPProcessException(FPException.InputDenorm, context, fpcr); } } else @@ -3181,11 +3172,6 @@ namespace ARMeilleure.Instructions return BitConverter.Int64BitsToDouble((long)op); } - private static void FPProcessException(FPException exc, ExecutionContext context) - { - FPProcessException(exc, context, context.Fpcr); - } - private static void FPProcessException(FPException exc, ExecutionContext context, FPCR fpcr) { int enable = (int)exc + 8;