Update SoftFallback.cs

This commit is contained in:
LDj3SNuD 2018-11-27 02:52:49 +01:00 committed by GitHub
parent 0a2456628f
commit 586fced2a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -16,6 +16,283 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(SoftFallback), mthdName);
}
#region "ShlReg"
public static long SignedShlReg(long value, long shift, bool round, int size)
{
int eSize = 8 << size;
int shiftLsB = (sbyte)shift;
if (shiftLsB < 0)
{
return SignedShrReg(value, -shiftLsB, round, eSize);
}
else if (shiftLsB > 0)
{
if (shiftLsB >= eSize)
{
return 0L;
}
return value << shiftLsB;
}
else /* if (shiftLsB == 0) */
{
return value;
}
}
public static ulong UnsignedShlReg(ulong value, ulong shift, bool round, int size)
{
int eSize = 8 << size;
int shiftLsB = (sbyte)shift;
if (shiftLsB < 0)
{
return UnsignedShrReg(value, -shiftLsB, round, eSize);
}
else if (shiftLsB > 0)
{
if (shiftLsB >= eSize)
{
return 0UL;
}
return value << shiftLsB;
}
else /* if (shiftLsB == 0) */
{
return value;
}
}
public static long SignedShlRegSatQ(long value, long shift, bool round, int size, CpuThreadState state)
{
int eSize = 8 << size;
int shiftLsB = (sbyte)shift;
if (shiftLsB < 0)
{
return SignedShrReg(value, -shiftLsB, round, eSize);
}
else if (shiftLsB > 0)
{
if (shiftLsB >= eSize)
{
return SignedSignSatQ(value, eSize, state);
}
if (eSize == 64)
{
long shl = value << shiftLsB;
long shr = shl >> shiftLsB;
if (shr != value)
{
return SignedSignSatQ(value, eSize, state);
}
else /* if (shr == value) */
{
return shl;
}
}
else /* if (eSize != 64) */
{
return SignedSrcSignedDstSatQ(value << shiftLsB, size, state);
}
}
else /* if (shiftLsB == 0) */
{
return value;
}
}
public static ulong UnsignedShlRegSatQ(ulong value, ulong shift, bool round, int size, CpuThreadState state)
{
int eSize = 8 << size;
int shiftLsB = (sbyte)shift;
if (shiftLsB < 0)
{
return UnsignedShrReg(value, -shiftLsB, round, eSize);
}
else if (shiftLsB > 0)
{
if (shiftLsB >= eSize)
{
return UnsignedSignSatQ(value, eSize, state);
}
if (eSize == 64)
{
ulong shl = value << shiftLsB;
ulong shr = shl >> shiftLsB;
if (shr != value)
{
return UnsignedSignSatQ(value, eSize, state);
}
else /* if (shr == value) */
{
return shl;
}
}
else /* if (eSize != 64) */
{
return UnsignedSrcUnsignedDstSatQ(value << shiftLsB, size, state);
}
}
else /* if (shiftLsB == 0) */
{
return value;
}
}
private static long SignedShrReg(long value, int shift, bool round, int eSize) // shift := [1, 128]; eSize := {8, 16, 32, 64}.
{
if (round)
{
if (shift >= eSize)
{
return 0L;
}
long roundConst = 1L << (shift - 1);
long add = value + roundConst;
if (eSize == 64)
{
if ((~value & (value ^ add)) < 0L)
{
return (long)((ulong)add >> shift);
}
else
{
return add >> shift;
}
}
else /* if (eSize != 64) */
{
return add >> shift;
}
}
else /* if (!round) */
{
if (shift >= eSize)
{
if (value < 0L)
{
return -1L;
}
else /* if (value >= 0L) */
{
return 0L;
}
}
return value >> shift;
}
}
private static ulong UnsignedShrReg(ulong value, int shift, bool round, int eSize) // shift := [1, 128]; eSize := {8, 16, 32, 64}.
{
if (round)
{
if (shift > 64)
{
return 0UL;
}
long roundConst = 1L << (shift - 1);
ulong add = value + (ulong)roundConst;
if (eSize == 64)
{
if ((add < value) && (add < (ulong)roundConst))
{
if (shift == 64)
{
return 1UL;
}
return (add >> shift) | (0x8000000000000000UL >> (shift - 1));
}
else
{
if (shift == 64)
{
return 0UL;
}
return add >> shift;
}
}
else /* if (eSize != 64) */
{
if (shift == 64)
{
return 0UL;
}
return add >> shift;
}
}
else /* if (!round) */
{
if (shift >= eSize)
{
return 0UL;
}
return value >> shift;
}
}
private static long SignedSignSatQ(long op, int eSize, CpuThreadState state) // eSize := {8, 16, 32, 64}.
{
long tMaxValue = (1L << (eSize - 1)) - 1L;
long tMinValue = -(1L << (eSize - 1));
if (op > 0L)
{
state.SetFpsrFlag(Fpsr.Qc);
return tMaxValue;
}
else if (op < 0L)
{
state.SetFpsrFlag(Fpsr.Qc);
return tMinValue;
}
else
{
return 0L;
}
}
private static ulong UnsignedSignSatQ(ulong op, int eSize, CpuThreadState state) // eSize := {8, 16, 32, 64}.
{
ulong tMaxValue = ulong.MaxValue >> (64 - eSize);
if (op > 0UL)
{
state.SetFpsrFlag(Fpsr.Qc);
return tMaxValue;
}
else
{
return 0UL;
}
}
#endregion
#region "ShrImm64"
public static long SignedShrImm64(long value, long roundConst, int shift)
{
@ -31,7 +308,7 @@ namespace ChocolArm64.Instructions
{
return -1L;
}
else
else /* if (value >= 0L) */
{
return 0L;
}