aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-03-23 13:32:30 -0300
committerGitHub <noreply@github.com>2020-03-23 17:32:30 +0100
commit6edc9298944d16c29e7423da5b1f3ce3e1025ac7 (patch)
tree4b71cc317f26d2c81d6e41df698f2d31e2bc4298
parent9a208c4fb5a374eaf691b9ef83f918b209c82438 (diff)
Implement ICMP shader instruction (#1010)
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs4
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs42
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs2
3 files changed, 32 insertions, 16 deletions
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
index 72f66f4a..3878dd87 100644
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
@@ -120,6 +120,10 @@ namespace Ryujinx.Graphics.Shader.Decoders
Set("010011001100xx", InstEmit.Iadd3, typeof(OpCodeAluCbuf));
Set("0011100x1100xx", InstEmit.Iadd3, typeof(OpCodeAluImm));
Set("010111001100xx", InstEmit.Iadd3, typeof(OpCodeAluReg));
+ Set("010010110100xx", InstEmit.Icmp, typeof(OpCodeAluCbuf));
+ Set("0011011x0100xx", InstEmit.Icmp, typeof(OpCodeAluImm));
+ Set("010110110100xx", InstEmit.Icmp, typeof(OpCodeAluReg));
+ Set("010100110100xx", InstEmit.Icmp, typeof(OpCodeAluRegCbuf));
Set("010010100xxxxx", InstEmit.Imad, typeof(OpCodeAluCbuf));
Set("0011010x0xxxxx", InstEmit.Imad, typeof(OpCodeAluImm));
Set("010110100xxxxx", InstEmit.Imad, typeof(OpCodeAluReg));
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs
index 92354cec..5a919c77 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs
@@ -200,10 +200,27 @@ namespace Ryujinx.Graphics.Shader.Instructions
// TODO: CC, X, corner cases
}
- public static void Imad(EmitterContext context)
+ public static void Icmp(EmitterContext context)
{
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
+ OpCode op = context.CurrOp;
+
+ bool isSigned = op.RawOpCode.Extract(48);
+
+ IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3);
+
+ Operand srcA = GetSrcA(context);
+ Operand srcB = GetSrcB(context);
+ Operand srcC = GetSrcC(context);
+ Operand cmpRes = GetIntComparison(context, cmpOp, srcC, Const(0), isSigned);
+
+ Operand res = context.ConditionalSelect(cmpRes, srcA, srcB);
+
+ context.Copy(GetDest(context), res);
+ }
+
+ public static void Imad(EmitterContext context)
+ {
bool signedA = context.CurrOp.RawOpCode.Extract(48);
bool signedB = context.CurrOp.RawOpCode.Extract(53);
bool high = context.CurrOp.RawOpCode.Extract(54);
@@ -731,19 +748,16 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
else
{
- Instruction inst;
-
- switch (cond)
+ var inst = cond switch
{
- case IntegerCondition.Less: inst = Instruction.CompareLessU32; break;
- case IntegerCondition.Equal: inst = Instruction.CompareEqual; break;
- case IntegerCondition.LessOrEqual: inst = Instruction.CompareLessOrEqualU32; break;
- case IntegerCondition.Greater: inst = Instruction.CompareGreaterU32; break;
- case IntegerCondition.NotEqual: inst = Instruction.CompareNotEqual; break;
- case IntegerCondition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqualU32; break;
-
- default: throw new InvalidOperationException($"Unexpected condition \"{cond}\".");
- }
+ IntegerCondition.Less => Instruction.CompareLessU32,
+ IntegerCondition.Equal => Instruction.CompareEqual,
+ IntegerCondition.LessOrEqual => Instruction.CompareLessOrEqualU32,
+ IntegerCondition.Greater => Instruction.CompareGreaterU32,
+ IntegerCondition.NotEqual => Instruction.CompareNotEqual,
+ IntegerCondition.GreaterOrEqual => Instruction.CompareGreaterOrEqualU32,
+ _ => throw new InvalidOperationException($"Unexpected condition \"{cond}\".")
+ };
if (isSigned)
{
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs
index ffc4c430..efc80b0c 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs
@@ -97,8 +97,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
public static void Sel(EmitterContext context)
{
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
Operand pred = GetPredicate39(context);
Operand srcA = GetSrcA(context);