From 8ae609dbf10f9c62f56c98945d1962752d3950a3 Mon Sep 17 00:00:00 2001 From: LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> Date: Sat, 4 Aug 2018 14:06:26 +0200 Subject: [PATCH] Update ASoftFallback.cs --- ChocolArm64/Instruction/ASoftFallback.cs | 104 +++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/ChocolArm64/Instruction/ASoftFallback.cs b/ChocolArm64/Instruction/ASoftFallback.cs index 0b1da76588..a4d12dd613 100644 --- a/ChocolArm64/Instruction/ASoftFallback.cs +++ b/ChocolArm64/Instruction/ASoftFallback.cs @@ -93,6 +93,9 @@ namespace ChocolArm64.Instruction { if (op1 <= (ulong)long.MaxValue) { + // op1 from ulong.MinValue to (ulong)long.MaxValue + // op2 from long.MinValue to long.MaxValue + long Add = (long)op1 + op2; if ((~op2 & Add) < 0L) @@ -108,12 +111,18 @@ namespace ChocolArm64.Instruction } else if (op2 >= 0L) { + // op1 from (ulong)long.MaxValue + 1UL to ulong.MaxValue + // op2 from (long)ulong.MinValue to long.MaxValue + SetFpsrQCFlag(State); return long.MaxValue; } else { + // op1 from (ulong)long.MaxValue + 1UL to ulong.MaxValue + // op2 from long.MinValue to (long)ulong.MinValue - 1L + ulong Add = op1 + (ulong)op2; if (Add > (ulong)long.MaxValue) @@ -133,6 +142,9 @@ namespace ChocolArm64.Instruction { if (op1 >= 0L) { + // op1 from (long)ulong.MinValue to long.MaxValue + // op2 from ulong.MinValue to ulong.MaxValue + ulong Add = (ulong)op1 + op2; if ((Add < (ulong)op1) && (Add < op2)) @@ -148,10 +160,16 @@ namespace ChocolArm64.Instruction } else if (op2 > (ulong)long.MaxValue) { + // op1 from long.MinValue to (long)ulong.MinValue - 1L + // op2 from (ulong)long.MaxValue + 1UL to ulong.MaxValue + return (ulong)op1 + op2; } else { + // op1 from long.MinValue to (long)ulong.MinValue - 1L + // op2 from ulong.MinValue to (ulong)long.MaxValue + long Add = op1 + (long)op2; if (Add < (long)ulong.MinValue) @@ -167,6 +185,92 @@ namespace ChocolArm64.Instruction } } + public static long SignedSrcSignedDstSatQ(long op, int Size, AThreadState State) + { + int ESize = 8 << Size; + + long TMaxValue = (1L << (ESize - 1)) - 1L; + long TMinValue = -(1L << (ESize - 1)); + + if (op > TMaxValue) + { + SetFpsrQCFlag(State); + + return TMaxValue; + } + else if (op < TMinValue) + { + SetFpsrQCFlag(State); + + return TMinValue; + } + else + { + return op; + } + } + + public static ulong SignedSrcUnsignedDstSatQ(long op, int Size, AThreadState State) + { + int ESize = 8 << Size; + + ulong TMaxValue = (1UL << ESize) - 1UL; + ulong TMinValue = 0UL; + + if (op > (long)TMaxValue) + { + SetFpsrQCFlag(State); + + return TMaxValue; + } + else if (op < (long)TMinValue) + { + SetFpsrQCFlag(State); + + return TMinValue; + } + else + { + return (ulong)op; + } + } + + public static long UnsignedSrcSignedDstSatQ(ulong op, int Size, AThreadState State) + { + int ESize = 8 << Size; + + long TMaxValue = (1L << (ESize - 1)) - 1L; + + if (op > (ulong)TMaxValue) + { + SetFpsrQCFlag(State); + + return TMaxValue; + } + else + { + return (long)op; + } + } + + public static ulong UnsignedSrcUnsignedDstSatQ(ulong op, int Size, AThreadState State) + { + int ESize = 8 << Size; + + ulong TMaxValue = (1UL << ESize) - 1UL; + + if (op > TMaxValue) + { + SetFpsrQCFlag(State); + + return TMaxValue; + } + else + { + return op; + } + } + private static void SetFpsrQCFlag(AThreadState State) { const int QCFlagBit = 27;