From 6a8ba6d60080ca15fc25a6812998b19e63171610 Mon Sep 17 00:00:00 2001 From: gdk Date: Tue, 19 Nov 2019 10:45:46 -0300 Subject: [PATCH] Add R2P shader instruction --- .../Decoders/OpCodeTable.cs | 3 ++ .../Instructions/InstEmitMemory.cs | 2 +- .../Instructions/InstEmitMove.cs | 32 +++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs index bc30940d8c..a7a7f64e6f 100644 --- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs +++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs @@ -143,6 +143,9 @@ namespace Ryujinx.Graphics.Shader.Decoders Set("0011100x00001x", InstEmit.Popc, typeof(OpCodeAluImm)); Set("0101110000001x", InstEmit.Popc, typeof(OpCodeAluReg)); Set("0101000010010x", InstEmit.Psetp, typeof(OpCodePsetp)); + Set("0100110011110x", InstEmit.R2p, typeof(OpCodeAluCbuf)); + Set("0011100x11110x", InstEmit.R2p, typeof(OpCodeAluImm)); + Set("0101110011110x", InstEmit.R2p, typeof(OpCodeAluReg)); Set("1110101111111x", InstEmit.Red, typeof(OpCodeRed)); Set("0100110010010x", InstEmit.Rro, typeof(OpCodeFArithCbuf)); Set("0011100x10010x", InstEmit.Rro, typeof(OpCodeFArithImm)); diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs index d76f44cb63..2abbed085f 100644 --- a/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs +++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs @@ -213,7 +213,7 @@ namespace Ryujinx.Graphics.Shader.Instructions Operand mem, Operand value) { - Operand res = null; + Operand res = Const(0); switch (op) { diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs index 5833d87984..17e80f4a4a 100644 --- a/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs +++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs @@ -16,6 +16,38 @@ namespace Ryujinx.Graphics.Shader.Instructions context.Copy(GetDest(context), GetSrcB(context)); } + public static void R2p(EmitterContext context) + { + OpCodeAlu op = (OpCodeAlu)context.CurrOp; + + bool isCC = op.RawOpCode.Extract(40); + int shift = op.RawOpCode.Extract(41, 2) * 8; + + Operand value = GetSrcA(context); + Operand mask = GetSrcB(context); + + Operand Test(Operand value, int bit) + { + return context.ICompareNotEqual(context.BitwiseAnd(value, Const(1 << bit)), Const(0)); + } + + if (isCC) + { + // TODO. + } + else + { + for (int bit = 0; bit < 7; bit++) + { + Operand pred = Register(bit, RegisterType.Predicate); + + Operand res = context.ConditionalSelect(Test(mask, bit), Test(value, bit + shift), pred); + + context.Copy(pred, res); + } + } + } + public static void S2r(EmitterContext context) { // TODO: Better impl.