InstEmitPredicate.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 Pset(EmitterContext context) 13 { 14 InstPset op = context.GetOp<InstPset>(); 15 16 Operand srcA = context.BitwiseNot(Register(op.Src2Pred, RegisterType.Predicate), op.Src2PredInv); 17 Operand srcB = context.BitwiseNot(Register(op.Src1Pred, RegisterType.Predicate), op.Src1PredInv); 18 Operand srcC = context.BitwiseNot(Register(op.SrcPred, RegisterType.Predicate), op.SrcPredInv); 19 20 Operand res = GetPredLogicalOp(context, op.BoolOpAB, srcA, srcB); 21 res = GetPredLogicalOp(context, op.BoolOpC, res, srcC); 22 23 Operand dest = GetDest(op.Dest); 24 25 if (op.BVal) 26 { 27 context.Copy(dest, context.ConditionalSelect(res, ConstF(1), ConstF(0))); 28 } 29 else 30 { 31 context.Copy(dest, res); 32 } 33 } 34 35 public static void Psetp(EmitterContext context) 36 { 37 InstPsetp op = context.GetOp<InstPsetp>(); 38 39 Operand srcA = context.BitwiseNot(Register(op.Src2Pred, RegisterType.Predicate), op.Src2PredInv); 40 Operand srcB = context.BitwiseNot(Register(op.Src1Pred, RegisterType.Predicate), op.Src1PredInv); 41 42 Operand p0Res = GetPredLogicalOp(context, op.BoolOpAB, srcA, srcB); 43 Operand p1Res = context.BitwiseNot(p0Res); 44 Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv); 45 46 p0Res = GetPredLogicalOp(context, op.BoolOpC, p0Res, srcPred); 47 p1Res = GetPredLogicalOp(context, op.BoolOpC, p1Res, srcPred); 48 49 context.Copy(Register(op.DestPred, RegisterType.Predicate), p0Res); 50 context.Copy(Register(op.DestPredInv, RegisterType.Predicate), p1Res); 51 } 52 53 public static void P2rC(EmitterContext context) 54 { 55 InstP2rC op = context.GetOp<InstP2rC>(); 56 57 Operand srcA = GetSrcReg(context, op.SrcA); 58 Operand dest = GetSrcReg(context, op.Dest); 59 Operand mask = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); 60 61 EmitP2r(context, srcA, dest, mask, op.ByteSel, op.Ccpr); 62 } 63 64 public static void P2rI(EmitterContext context) 65 { 66 InstP2rI op = context.GetOp<InstP2rI>(); 67 68 Operand srcA = GetSrcReg(context, op.SrcA); 69 Operand dest = GetSrcReg(context, op.Dest); 70 Operand mask = GetSrcImm(context, op.Imm20); 71 72 EmitP2r(context, srcA, dest, mask, op.ByteSel, op.Ccpr); 73 } 74 75 public static void P2rR(EmitterContext context) 76 { 77 InstP2rR op = context.GetOp<InstP2rR>(); 78 79 Operand srcA = GetSrcReg(context, op.SrcA); 80 Operand dest = GetSrcReg(context, op.Dest); 81 Operand mask = GetSrcReg(context, op.SrcB); 82 83 EmitP2r(context, srcA, dest, mask, op.ByteSel, op.Ccpr); 84 } 85 86 private static void EmitP2r( 87 EmitterContext context, 88 Operand srcA, 89 Operand dest, 90 Operand mask, 91 ByteSel byteSel, 92 bool ccpr) 93 { 94 int count = ccpr ? RegisterConsts.FlagsCount : RegisterConsts.PredsCount; 95 int shift = (int)byteSel * 8; 96 mask = context.BitwiseAnd(mask, Const(0xff)); 97 98 Operand insert = Const(0); 99 for (int i = 0; i < count; i++) 100 { 101 Operand condition = ccpr 102 ? Register(i, RegisterType.Flag) 103 : Register(i, RegisterType.Predicate); 104 105 Operand bit = context.ConditionalSelect(condition, Const(1 << (i + shift)), Const(0)); 106 insert = context.BitwiseOr(insert, bit); 107 } 108 109 Operand maskShifted = context.ShiftLeft(mask, Const(shift)); 110 Operand masked = context.BitwiseAnd(srcA, context.BitwiseNot(maskShifted)); 111 Operand res = context.BitwiseOr(masked, context.BitwiseAnd(insert, maskShifted)); 112 113 context.Copy(dest, res); 114 } 115 } 116 }