Implement ICMP shader instruction (#1010)

This commit is contained in:
gdkchan 2020-03-23 13:32:30 -03:00 committed by GitHub
parent 9a208c4fb5
commit 6edc929894
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 16 deletions

View file

@ -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));

View file

@ -200,10 +200,27 @@ namespace Ryujinx.Graphics.Shader.Instructions
// TODO: CC, X, corner cases
}
public static void Icmp(EmitterContext context)
{
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)
{
OpCodeAlu op = (OpCodeAlu)context.CurrOp;
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)
{

View file

@ -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);