Avoid gpr overwritting on Ld_C instruction (#371)

* Avoid gpr overwritting on LD_C instruction

* Address feedback

* Ignore invalid registers
This commit is contained in:
ReinUsesLisp 2018-08-20 23:31:10 -03:00 committed by gdkchan
parent afdeee2b86
commit afc44850be
3 changed files with 22 additions and 10 deletions

View file

@ -35,13 +35,6 @@ namespace Ryujinx.Graphics.Gal.Shader
(int)(OpCode >> 20) & 0x3fff); (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) public static ShaderIrOperGpr GetOperGpr8(long OpCode)
{ {
return new ShaderIrOperGpr((int)(OpCode >> 8) & 0xff); return new ShaderIrOperGpr((int)(OpCode >> 8) & 0xff);

View file

@ -52,23 +52,35 @@ namespace Ryujinx.Graphics.Gal.Shader
public static void Ld_C(ShaderIrBlock Block, long OpCode) 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) if (Type > 5)
{ {
throw new InvalidOperationException(); throw new InvalidOperationException();
} }
ShaderIrOperGpr Temp = ShaderIrOperGpr.MakeTemporary();
Block.AddNode(new ShaderIrAsg(Temp, GetOperGpr8(OpCode)));
int Count = Type == 5 ? 2 : 1; int Count = Type == 5 ? 2 : 1;
for (int Index = 0; Index < Count; Index++) for (int Index = 0; Index < Count; Index++)
{ {
ShaderIrOperCbuf OperA = GetOperCbuf36(OpCode); ShaderIrOperCbuf OperA = new ShaderIrOperCbuf(CbufIndex, CbufPos, Temp);
ShaderIrOperGpr OperD = GetOperGpr0 (OpCode);
ShaderIrOperGpr OperD = GetOperGpr0(OpCode);
OperA.Pos += Index; OperA.Pos += Index;
OperD.Index += Index; OperD.Index += Index;
if (!OperD.IsValidRegister)
{
break;
}
ShaderIrNode Node = OperA; ShaderIrNode Node = OperA;
if (Type < 4) if (Type < 4)

View file

@ -6,11 +6,18 @@ namespace Ryujinx.Graphics.Gal.Shader
public bool IsConst => Index == ZRIndex; public bool IsConst => Index == ZRIndex;
public bool IsValidRegister => (Index <= ZRIndex);
public int Index { get; set; } public int Index { get; set; }
public ShaderIrOperGpr(int Index) public ShaderIrOperGpr(int Index)
{ {
this.Index = Index; this.Index = Index;
} }
public static ShaderIrOperGpr MakeTemporary(int Index = 0)
{
return new ShaderIrOperGpr(0x100 + Index);
}
} }
} }