aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2018-08-20 23:31:10 -0300
committergdkchan <gab.dark.100@gmail.com>2018-08-20 23:31:10 -0300
commitafc44850be37f57d96e981925229964771a3e9e0 (patch)
tree3536a255668499945942c6347e91b7dc8517a05d
parentafdeee2b866bd5e41dd629553939d9b5d8bc1d50 (diff)
Avoid gpr overwritting on Ld_C instruction (#371)
* Avoid gpr overwritting on LD_C instruction * Address feedback * Ignore invalid registers
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs7
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs18
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs7
3 files changed, 22 insertions, 10 deletions
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs
index 7d7b2f6c..2093f070 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs
@@ -35,13 +35,6 @@ namespace Ryujinx.Graphics.Gal.Shader
(int)(OpCode >> 20) & 0x3fff);
}
- public static ShaderIrOperCbuf GetOperCbuf36(long OpCode)
- {
- return new ShaderIrOperCbuf(
- (int)(OpCode >> 36) & 0x1f,
- (int)(OpCode >> 22) & 0x3fff, GetOperGpr8(OpCode));
- }
-
public static ShaderIrOperGpr GetOperGpr8(long OpCode)
{
return new ShaderIrOperGpr((int)(OpCode >> 8) & 0xff);
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs
index e794e1f8..a183b0c6 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs
@@ -52,23 +52,35 @@ namespace Ryujinx.Graphics.Gal.Shader
public static void Ld_C(ShaderIrBlock Block, long OpCode)
{
- int Type = (int)(OpCode >> 48) & 7;
+ int CbufPos = (int)(OpCode >> 22) & 0x3fff;
+ int CbufIndex = (int)(OpCode >> 36) & 0x1f;
+ int Type = (int)(OpCode >> 48) & 7;
if (Type > 5)
{
throw new InvalidOperationException();
}
+ ShaderIrOperGpr Temp = ShaderIrOperGpr.MakeTemporary();
+
+ Block.AddNode(new ShaderIrAsg(Temp, GetOperGpr8(OpCode)));
+
int Count = Type == 5 ? 2 : 1;
for (int Index = 0; Index < Count; Index++)
{
- ShaderIrOperCbuf OperA = GetOperCbuf36(OpCode);
- ShaderIrOperGpr OperD = GetOperGpr0 (OpCode);
+ ShaderIrOperCbuf OperA = new ShaderIrOperCbuf(CbufIndex, CbufPos, Temp);
+
+ ShaderIrOperGpr OperD = GetOperGpr0(OpCode);
OperA.Pos += Index;
OperD.Index += Index;
+ if (!OperD.IsValidRegister)
+ {
+ break;
+ }
+
ShaderIrNode Node = OperA;
if (Type < 4)
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs
index 5c69d6a6..9dd196e6 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs
@@ -6,11 +6,18 @@ namespace Ryujinx.Graphics.Gal.Shader
public bool IsConst => Index == ZRIndex;
+ public bool IsValidRegister => (Index <= ZRIndex);
+
public int Index { get; set; }
public ShaderIrOperGpr(int Index)
{
this.Index = Index;
}
+
+ public static ShaderIrOperGpr MakeTemporary(int Index = 0)
+ {
+ return new ShaderIrOperGpr(0x100 + Index);
+ }
}
} \ No newline at end of file