InstEmitIntegerLogical.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 private const int PT = RegisterConsts.PredicateTrueIndex; 13 14 public static void LopR(EmitterContext context) 15 { 16 InstLopR op = context.GetOp<InstLopR>(); 17 18 var srcA = GetSrcReg(context, op.SrcA); 19 var srcB = GetSrcReg(context, op.SrcB); 20 21 EmitLop(context, op.Lop, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC); 22 } 23 24 public static void LopI(EmitterContext context) 25 { 26 InstLopI op = context.GetOp<InstLopI>(); 27 28 var srcA = GetSrcReg(context, op.SrcA); 29 var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20)); 30 31 EmitLop(context, op.LogicOp, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC); 32 } 33 34 public static void LopC(EmitterContext context) 35 { 36 InstLopC op = context.GetOp<InstLopC>(); 37 38 var srcA = GetSrcReg(context, op.SrcA); 39 var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); 40 41 EmitLop(context, op.LogicOp, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC); 42 } 43 44 public static void Lop32i(EmitterContext context) 45 { 46 InstLop32i op = context.GetOp<InstLop32i>(); 47 48 var srcA = GetSrcReg(context, op.SrcA); 49 var srcB = GetSrcImm(context, op.Imm32); 50 51 EmitLop(context, op.LogicOp, PredicateOp.F, srcA, srcB, op.Dest, PT, op.NegA, op.NegB, op.X, op.WriteCC); 52 } 53 54 public static void Lop3R(EmitterContext context) 55 { 56 InstLop3R op = context.GetOp<InstLop3R>(); 57 58 var srcA = GetSrcReg(context, op.SrcA); 59 var srcB = GetSrcReg(context, op.SrcB); 60 var srcC = GetSrcReg(context, op.SrcC); 61 62 EmitLop3(context, op.Imm, op.PredicateOp, srcA, srcB, srcC, op.Dest, op.DestPred, op.X, op.WriteCC); 63 } 64 65 public static void Lop3I(EmitterContext context) 66 { 67 InstLop3I op = context.GetOp<InstLop3I>(); 68 69 var srcA = GetSrcReg(context, op.SrcA); 70 var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20)); 71 var srcC = GetSrcReg(context, op.SrcC); 72 73 EmitLop3(context, op.Imm, PredicateOp.F, srcA, srcB, srcC, op.Dest, PT, false, op.WriteCC); 74 } 75 76 public static void Lop3C(EmitterContext context) 77 { 78 InstLop3C op = context.GetOp<InstLop3C>(); 79 80 var srcA = GetSrcReg(context, op.SrcA); 81 var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); 82 var srcC = GetSrcReg(context, op.SrcC); 83 84 EmitLop3(context, op.Imm, PredicateOp.F, srcA, srcB, srcC, op.Dest, PT, false, op.WriteCC); 85 } 86 87 private static void EmitLop( 88 EmitterContext context, 89 LogicOp logicOp, 90 PredicateOp predOp, 91 Operand srcA, 92 Operand srcB, 93 int rd, 94 int destPred, 95 bool invertA, 96 bool invertB, 97 bool extended, 98 bool writeCC) 99 { 100 srcA = context.BitwiseNot(srcA, invertA); 101 srcB = context.BitwiseNot(srcB, invertB); 102 103 Operand res = logicOp switch 104 { 105 LogicOp.And => context.BitwiseAnd(srcA, srcB), 106 LogicOp.Or => context.BitwiseOr(srcA, srcB), 107 LogicOp.Xor => context.BitwiseExclusiveOr(srcA, srcB), 108 _ => srcB, 109 }; 110 111 EmitLopPredWrite(context, res, predOp, destPred); 112 113 context.Copy(GetDest(rd), res); 114 115 SetZnFlags(context, res, writeCC, extended); 116 } 117 118 private static void EmitLop3( 119 EmitterContext context, 120 int truthTable, 121 PredicateOp predOp, 122 Operand srcA, 123 Operand srcB, 124 Operand srcC, 125 int rd, 126 int destPred, 127 bool extended, 128 bool writeCC) 129 { 130 Operand res = Lop3Expression.GetFromTruthTable(context, srcA, srcB, srcC, truthTable); 131 132 EmitLopPredWrite(context, res, predOp, destPred); 133 134 context.Copy(GetDest(rd), res); 135 136 SetZnFlags(context, res, writeCC, extended); 137 } 138 139 private static void EmitLopPredWrite(EmitterContext context, Operand result, PredicateOp predOp, int pred) 140 { 141 if (pred != RegisterConsts.PredicateTrueIndex) 142 { 143 Operand pRes; 144 145 if (predOp == PredicateOp.F) 146 { 147 pRes = Const(IrConsts.False); 148 } 149 else if (predOp == PredicateOp.T) 150 { 151 pRes = Const(IrConsts.True); 152 } 153 else if (predOp == PredicateOp.Z) 154 { 155 pRes = context.ICompareEqual(result, Const(0)); 156 } 157 else /* if (predOp == Pop.Nz) */ 158 { 159 pRes = context.ICompareNotEqual(result, Const(0)); 160 } 161 162 context.Copy(Register(pred, RegisterType.Predicate), pRes); 163 } 164 } 165 } 166 }