aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Instructions/InstEmitSimdHelper.cs
diff options
context:
space:
mode:
authorLDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>2022-09-19 19:49:10 +0200
committerGitHub <noreply@github.com>2022-09-19 14:49:10 -0300
commitb9f1ff3c7748c6a2665e76d17e86c3b7228f44fe (patch)
tree318f3a5c124f6a980c643b027bb73f3891953c46 /ARMeilleure/Instructions/InstEmitSimdHelper.cs
parenta77af4c5e9e74ada62bfdb7ef5672eeebb00c3ab (diff)
Implemented in IR the managed methods of the ShlReg region of the SoftFallback class. (#3700)1.1.273
* Implemented in IR the managed methods of the Saturating region ... ... of the SoftFallback class (the SatQ ones). The need to natively manage the Fpcr and Fpsr system registers is still a fact. Contributes to https://github.com/Ryujinx/Ryujinx/issues/2917 ; I will open another PR to implement in Intrinsics-branchless the methods of the Saturation region as well (the SatXXXToXXX ones). All instructions involved have been tested locally in both release and debug modes, in both lowcq and highcq. * Ptc.InternalVersion = 3665 * Addressed PR feedback. * Implemented in IR the managed methods of the ShlReg region of the SoftFallback class. It also includes the last two SatQ ones (following up on https://github.com/Ryujinx/Ryujinx/pull/3665). All instructions involved have been tested locally in both release and debug modes, in both lowcq and highcq. * Update InstEmitSimdHelper.cs
Diffstat (limited to 'ARMeilleure/Instructions/InstEmitSimdHelper.cs')
-rw-r--r--ARMeilleure/Instructions/InstEmitSimdHelper.cs148
1 files changed, 107 insertions, 41 deletions
diff --git a/ARMeilleure/Instructions/InstEmitSimdHelper.cs b/ARMeilleure/Instructions/InstEmitSimdHelper.cs
index 27b5c130..80dfc688 100644
--- a/ARMeilleure/Instructions/InstEmitSimdHelper.cs
+++ b/ARMeilleure/Instructions/InstEmitSimdHelper.cs
@@ -1533,29 +1533,88 @@ namespace ARMeilleure.Instructions
context.Copy(d, res);
}
+ // long SignedSignSatQ(long op, int size);
+ public static Operand EmitSignedSignSatQ(ArmEmitterContext context, Operand op, int size)
+ {
+ int eSize = 8 << size;
+
+ Debug.Assert(op.Type == OperandType.I64);
+ Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
+
+ Operand lbl1 = Label();
+ Operand lblEnd = Label();
+
+ Operand zeroL = Const(0L);
+ Operand maxT = Const((1L << (eSize - 1)) - 1L);
+ Operand minT = Const(-(1L << (eSize - 1)));
+
+ Operand res = context.Copy(context.AllocateLocal(OperandType.I64), zeroL);
+
+ context.BranchIf(lbl1, op, zeroL, Comparison.LessOrEqual);
+ context.Copy(res, maxT);
+ context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
+ context.Branch(lblEnd);
+
+ context.MarkLabel(lbl1);
+ context.BranchIf(lblEnd, op, zeroL, Comparison.GreaterOrEqual);
+ context.Copy(res, minT);
+ context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
+ context.Branch(lblEnd);
+
+ context.MarkLabel(lblEnd);
+
+ return res;
+ }
+
+ // private static ulong UnsignedSignSatQ(ulong op, int size);
+ public static Operand EmitUnsignedSignSatQ(ArmEmitterContext context, Operand op, int size)
+ {
+ int eSize = 8 << size;
+
+ Debug.Assert(op.Type == OperandType.I64);
+ Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
+
+ Operand lblEnd = Label();
+
+ Operand zeroUL = Const(0UL);
+ Operand maxT = Const(ulong.MaxValue >> (64 - eSize));
+
+ Operand res = context.Copy(context.AllocateLocal(OperandType.I64), zeroUL);
+
+ context.BranchIf(lblEnd, op, zeroUL, Comparison.LessOrEqualUI);
+ context.Copy(res, maxT);
+ context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
+ context.Branch(lblEnd);
+
+ context.MarkLabel(lblEnd);
+
+ return res;
+ }
+
// TSrc (16bit, 32bit, 64bit; signed) > TDst (8bit, 16bit, 32bit; signed, unsigned).
// long SignedSrcSignedDstSatQ(long op, int size); ulong SignedSrcUnsignedDstSatQ(long op, int size);
public static Operand EmitSignedSrcSatQ(ArmEmitterContext context, Operand op, int sizeDst, bool signedDst)
{
- Debug.Assert(op.Type == OperandType.I64 && (uint)sizeDst <= 2u);
+ int eSizeDst = 8 << sizeDst;
+
+ Debug.Assert(op.Type == OperandType.I64);
+ Debug.Assert(eSizeDst == 8 || eSizeDst == 16 || eSizeDst == 32);
Operand lbl1 = Label();
Operand lblEnd = Label();
- int eSize = 8 << sizeDst;
-
- Operand maxT = signedDst ? Const((1L << (eSize - 1)) - 1L) : Const((1UL << eSize) - 1UL);
- Operand minT = signedDst ? Const(-(1L << (eSize - 1))) : Const(0UL);
+ Operand maxT = signedDst ? Const((1L << (eSizeDst - 1)) - 1L) : Const((1UL << eSizeDst) - 1UL);
+ Operand minT = signedDst ? Const(-(1L << (eSizeDst - 1))) : Const(0UL);
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
- context.BranchIf(lbl1, res, maxT, Comparison.LessOrEqual);
+ context.BranchIf(lbl1, op, maxT, Comparison.LessOrEqual);
context.Copy(res, maxT);
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
context.Branch(lblEnd);
context.MarkLabel(lbl1);
- context.BranchIf(lblEnd, res, minT, Comparison.GreaterOrEqual);
+ context.BranchIf(lblEnd, op, minT, Comparison.GreaterOrEqual);
context.Copy(res, minT);
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
context.Branch(lblEnd);
@@ -1569,18 +1628,19 @@ namespace ARMeilleure.Instructions
// long UnsignedSrcSignedDstSatQ(ulong op, int size); ulong UnsignedSrcUnsignedDstSatQ(ulong op, int size);
public static Operand EmitUnsignedSrcSatQ(ArmEmitterContext context, Operand op, int sizeDst, bool signedDst)
{
- Debug.Assert(op.Type == OperandType.I64 && (uint)sizeDst <= 2u);
+ int eSizeDst = 8 << sizeDst;
- Operand lblEnd = Label();
+ Debug.Assert(op.Type == OperandType.I64);
+ Debug.Assert(eSizeDst == 8 || eSizeDst == 16 || eSizeDst == 32);
- int eSize = 8 << sizeDst;
+ Operand lblEnd = Label();
- Operand maxL = signedDst ? Const((1L << (eSize - 1)) - 1L) : Const((1UL << eSize) - 1UL);
+ Operand maxT = signedDst ? Const((1L << (eSizeDst - 1)) - 1L) : Const((1UL << eSizeDst) - 1UL);
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
- context.BranchIf(lblEnd, res, maxL, Comparison.LessOrEqualUI);
- context.Copy(res, maxL);
+ context.BranchIf(lblEnd, op, maxT, Comparison.LessOrEqualUI);
+ context.Copy(res, maxT);
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
context.Branch(lblEnd);
@@ -1601,7 +1661,7 @@ namespace ARMeilleure.Instructions
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
- context.BranchIf(lblEnd, res, minL, Comparison.NotEqual);
+ context.BranchIf(lblEnd, op, minL, Comparison.NotEqual);
context.Copy(res, maxL);
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
context.Branch(lblEnd);
@@ -1620,15 +1680,16 @@ namespace ARMeilleure.Instructions
Operand minL = Const(long.MinValue);
Operand maxL = Const(long.MaxValue);
- Operand zero = Const(0L);
+ Operand zeroL = Const(0L);
- Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
+ Operand add = context.Add(op1, op2);
+ Operand res = context.Copy(context.AllocateLocal(OperandType.I64), add);
Operand left = context.BitwiseNot(context.BitwiseExclusiveOr(op1, op2));
- Operand right = context.BitwiseExclusiveOr(op1, res);
- context.BranchIf(lblEnd, context.BitwiseAnd(left, right), zero, Comparison.GreaterOrEqual);
+ Operand right = context.BitwiseExclusiveOr(op1, add);
+ context.BranchIf(lblEnd, context.BitwiseAnd(left, right), zeroL, Comparison.GreaterOrEqual);
- Operand isPositive = context.ICompareGreaterOrEqual(op1, zero);
+ Operand isPositive = context.ICompareGreaterOrEqual(op1, zeroL);
context.Copy(res, context.ConditionalSelect(isPositive, maxL, minL));
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
context.Branch(lblEnd);
@@ -1647,9 +1708,10 @@ namespace ARMeilleure.Instructions
Operand maxUL = Const(ulong.MaxValue);
- Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
+ Operand add = context.Add(op1, op2);
+ Operand res = context.Copy(context.AllocateLocal(OperandType.I64), add);
- context.BranchIf(lblEnd, res, op1, Comparison.GreaterOrEqualUI);
+ context.BranchIf(lblEnd, add, op1, Comparison.GreaterOrEqualUI);
context.Copy(res, maxUL);
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
context.Branch(lblEnd);
@@ -1668,15 +1730,16 @@ namespace ARMeilleure.Instructions
Operand minL = Const(long.MinValue);
Operand maxL = Const(long.MaxValue);
- Operand zero = Const(0L);
+ Operand zeroL = Const(0L);
- Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Subtract(op1, op2));
+ Operand sub = context.Subtract(op1, op2);
+ Operand res = context.Copy(context.AllocateLocal(OperandType.I64), sub);
Operand left = context.BitwiseExclusiveOr(op1, op2);
- Operand right = context.BitwiseExclusiveOr(op1, res);
- context.BranchIf(lblEnd, context.BitwiseAnd(left, right), zero, Comparison.GreaterOrEqual);
+ Operand right = context.BitwiseExclusiveOr(op1, sub);
+ context.BranchIf(lblEnd, context.BitwiseAnd(left, right), zeroL, Comparison.GreaterOrEqual);
- Operand isPositive = context.ICompareGreaterOrEqual(op1, zero);
+ Operand isPositive = context.ICompareGreaterOrEqual(op1, zeroL);
context.Copy(res, context.ConditionalSelect(isPositive, maxL, minL));
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
context.Branch(lblEnd);
@@ -1693,12 +1756,13 @@ namespace ARMeilleure.Instructions
Operand lblEnd = Label();
- Operand zero = Const(0L);
+ Operand zeroL = Const(0L);
- Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Subtract(op1, op2));
+ Operand sub = context.Subtract(op1, op2);
+ Operand res = context.Copy(context.AllocateLocal(OperandType.I64), sub);
context.BranchIf(lblEnd, op1, op2, Comparison.GreaterOrEqualUI);
- context.Copy(res, zero);
+ context.Copy(res, zeroL);
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
context.Branch(lblEnd);
@@ -1717,25 +1781,26 @@ namespace ARMeilleure.Instructions
Operand lblEnd = Label();
Operand maxL = Const(long.MaxValue);
- Operand zero = Const(0L);
+ Operand zeroL = Const(0L);
- Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
+ Operand add = context.Add(op1, op2);
+ Operand res = context.Copy(context.AllocateLocal(OperandType.I64), add);
context.BranchIf(lbl1, op1, maxL, Comparison.GreaterUI);
- Operand notOp2AndRes = context.BitwiseAnd(context.BitwiseNot(op2), res);
- context.BranchIf(lblEnd, notOp2AndRes, zero, Comparison.GreaterOrEqual);
+ Operand notOp2AndRes = context.BitwiseAnd(context.BitwiseNot(op2), add);
+ context.BranchIf(lblEnd, notOp2AndRes, zeroL, Comparison.GreaterOrEqual);
context.Copy(res, maxL);
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
context.Branch(lblEnd);
context.MarkLabel(lbl1);
- context.BranchIf(lbl2, op2, zero, Comparison.Less);
+ context.BranchIf(lbl2, op2, zeroL, Comparison.Less);
context.Copy(res, maxL);
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
context.Branch(lblEnd);
context.MarkLabel(lbl2);
- context.BranchIf(lblEnd, res, maxL, Comparison.LessOrEqualUI);
+ context.BranchIf(lblEnd, add, maxL, Comparison.LessOrEqualUI);
context.Copy(res, maxL);
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
context.Branch(lblEnd);
@@ -1755,20 +1820,21 @@ namespace ARMeilleure.Instructions
Operand maxUL = Const(ulong.MaxValue);
Operand maxL = Const(long.MaxValue);
- Operand zero = Const(0L);
+ Operand zeroL = Const(0L);
- Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
+ Operand add = context.Add(op1, op2);
+ Operand res = context.Copy(context.AllocateLocal(OperandType.I64), add);
- context.BranchIf(lbl1, op1, zero, Comparison.Less);
- context.BranchIf(lblEnd, res, op1, Comparison.GreaterOrEqualUI);
+ context.BranchIf(lbl1, op1, zeroL, Comparison.Less);
+ context.BranchIf(lblEnd, add, op1, Comparison.GreaterOrEqualUI);
context.Copy(res, maxUL);
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
context.Branch(lblEnd);
context.MarkLabel(lbl1);
context.BranchIf(lblEnd, op2, maxL, Comparison.GreaterUI);
- context.BranchIf(lblEnd, res, zero, Comparison.GreaterOrEqual);
- context.Copy(res, zero);
+ context.BranchIf(lblEnd, add, zeroL, Comparison.GreaterOrEqual);
+ context.Copy(res, zeroL);
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
context.Branch(lblEnd);