InstEmitConditionCode.cs
1 using Ryujinx.Graphics.Shader.Decoders; 2 using Ryujinx.Graphics.Shader.IntermediateRepresentation; 3 using Ryujinx.Graphics.Shader.Translation; 4 using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper; 5 using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; 6 using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; 7 8 namespace Ryujinx.Graphics.Shader.Instructions 9 { 10 static partial class InstEmit 11 { 12 public static void Cset(EmitterContext context) 13 { 14 InstCset op = context.GetOp<InstCset>(); 15 16 Operand res = GetCondition(context, op.Ccc); 17 Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv); 18 19 res = GetPredLogicalOp(context, op.Bop, res, srcPred); 20 21 Operand dest = GetDest(op.Dest); 22 23 if (op.BVal) 24 { 25 context.Copy(dest, context.ConditionalSelect(res, ConstF(1), Const(0))); 26 } 27 else 28 { 29 context.Copy(dest, res); 30 } 31 32 // TODO: CC. 33 } 34 35 public static void Csetp(EmitterContext context) 36 { 37 InstCsetp op = context.GetOp<InstCsetp>(); 38 39 Operand p0Res = GetCondition(context, op.Ccc); 40 Operand p1Res = context.BitwiseNot(p0Res); 41 Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv); 42 43 p0Res = GetPredLogicalOp(context, op.Bop, p0Res, srcPred); 44 p1Res = GetPredLogicalOp(context, op.Bop, p1Res, srcPred); 45 46 context.Copy(Register(op.DestPred, RegisterType.Predicate), p0Res); 47 context.Copy(Register(op.DestPredInv, RegisterType.Predicate), p1Res); 48 49 // TODO: CC. 50 } 51 52 private static Operand GetCondition(EmitterContext context, Ccc cond, int defaultCond = IrConsts.True) 53 { 54 return cond switch 55 { 56 Ccc.F => Const(IrConsts.False), 57 Ccc.Lt => context.BitwiseExclusiveOr(context.BitwiseAnd(GetNF(), context.BitwiseNot(GetZF())), GetVF()), 58 Ccc.Eq => context.BitwiseAnd(context.BitwiseNot(GetNF()), GetZF()), 59 Ccc.Le => context.BitwiseExclusiveOr(GetNF(), context.BitwiseOr(GetZF(), GetVF())), 60 Ccc.Gt => context.BitwiseNot(context.BitwiseOr(context.BitwiseExclusiveOr(GetNF(), GetVF()), GetZF())), 61 Ccc.Ne => context.BitwiseNot(GetZF()), 62 Ccc.Ge => context.BitwiseNot(context.BitwiseExclusiveOr(GetNF(), GetVF())), 63 Ccc.Num => context.BitwiseNot(context.BitwiseAnd(GetNF(), GetZF())), 64 Ccc.Nan => context.BitwiseAnd(GetNF(), GetZF()), 65 Ccc.Ltu => context.BitwiseExclusiveOr(GetNF(), GetVF()), 66 Ccc.Equ => GetZF(), 67 Ccc.Leu => context.BitwiseOr(context.BitwiseExclusiveOr(GetNF(), GetVF()), GetZF()), 68 Ccc.Gtu => context.BitwiseExclusiveOr(context.BitwiseNot(GetNF()), context.BitwiseOr(GetVF(), GetZF())), 69 Ccc.Neu => context.BitwiseOr(GetNF(), context.BitwiseNot(GetZF())), 70 Ccc.Geu => context.BitwiseExclusiveOr(context.BitwiseOr(context.BitwiseNot(GetNF()), GetZF()), GetVF()), 71 Ccc.T => Const(IrConsts.True), 72 Ccc.Off => context.BitwiseNot(GetVF()), 73 Ccc.Lo => context.BitwiseNot(GetCF()), 74 Ccc.Sff => context.BitwiseNot(GetNF()), 75 Ccc.Ls => context.BitwiseOr(GetZF(), context.BitwiseNot(GetCF())), 76 Ccc.Hi => context.BitwiseAnd(GetCF(), context.BitwiseNot(GetZF())), 77 Ccc.Sft => GetNF(), 78 Ccc.Hs => GetCF(), 79 Ccc.Oft => GetVF(), 80 Ccc.Rle => context.BitwiseOr(GetNF(), GetZF()), 81 Ccc.Rgt => context.BitwiseNot(context.BitwiseOr(GetNF(), GetZF())), 82 _ => Const(defaultCond), 83 }; 84 } 85 } 86 }