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);
}
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);

View file

@ -52,6 +52,8 @@ namespace Ryujinx.Graphics.Gal.Shader
public static void Ld_C(ShaderIrBlock Block, long OpCode)
{
int CbufPos = (int)(OpCode >> 22) & 0x3fff;
int CbufIndex = (int)(OpCode >> 36) & 0x1f;
int Type = (int)(OpCode >> 48) & 7;
if (Type > 5)
@ -59,16 +61,26 @@ namespace Ryujinx.Graphics.Gal.Shader
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)

View file

@ -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);
}
}
}