Add IADDI32, IADD and SEL shader instructions
This commit is contained in:
parent
514218ab98
commit
5eed749649
3 changed files with 98 additions and 0 deletions
|
@ -144,6 +144,35 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
EmitFsetp(Block, OpCode, ShaderOper.RR);
|
||||
}
|
||||
|
||||
public static void Iadd_I32_1c0(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
ShaderIrNode OperA = GetOperGpr0 (OpCode);
|
||||
ShaderIrNode OperB = GetOperImm32_20(OpCode);
|
||||
|
||||
bool NegA = ((OpCode >> 56) & 1) != 0;
|
||||
|
||||
OperA = GetAluIneg(OperA, NegA);
|
||||
|
||||
ShaderIrOp Op = new ShaderIrOp(ShaderIrInst.Add, OperA, OperB);
|
||||
|
||||
Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
|
||||
}
|
||||
|
||||
public static void Iadd_C(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitIadd(Block, OpCode, ShaderOper.CR);
|
||||
}
|
||||
|
||||
public static void Iadd_I(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitIadd(Block, OpCode, ShaderOper.Imm);
|
||||
}
|
||||
|
||||
public static void Iadd_R(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitIadd(Block, OpCode, ShaderOper.RR);
|
||||
}
|
||||
|
||||
public static void Imnmx_C(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitImnmx(Block, OpCode, ShaderOper.CR);
|
||||
|
@ -533,6 +562,31 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
|
||||
}
|
||||
|
||||
private static void EmitIadd(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
|
||||
{
|
||||
ShaderIrNode OperA = GetOperGpr8(OpCode);
|
||||
ShaderIrNode OperB;
|
||||
|
||||
switch (Oper)
|
||||
{
|
||||
case ShaderOper.CR: OperB = GetOperCbuf34 (OpCode); break;
|
||||
case ShaderOper.Imm: OperB = GetOperImm19_20(OpCode); break;
|
||||
case ShaderOper.RR: OperB = GetOperGpr20 (OpCode); break;
|
||||
|
||||
default: throw new ArgumentException(nameof(Oper));
|
||||
}
|
||||
|
||||
bool NegA = ((OpCode >> 49) & 1) != 0;
|
||||
bool NegB = ((OpCode >> 48) & 1) != 0;
|
||||
|
||||
OperA = GetAluIneg(OperA, NegA);
|
||||
OperB = GetAluIneg(OperB, NegB);
|
||||
|
||||
ShaderIrOp Op = new ShaderIrOp(ShaderIrInst.Add, OperA, OperB);
|
||||
|
||||
Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
|
||||
}
|
||||
|
||||
private static void EmitIscadd(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
|
||||
{
|
||||
bool NegB = ((OpCode >> 48) & 1) != 0;
|
||||
|
|
|
@ -113,6 +113,21 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Gpr), OpCode));
|
||||
}
|
||||
|
||||
public static void Sel_C(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitSel(Block, OpCode, ShaderOper.CR);
|
||||
}
|
||||
|
||||
public static void Sel_I(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitSel(Block, OpCode, ShaderOper.Imm);
|
||||
}
|
||||
|
||||
public static void Sel_R(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitSel(Block, OpCode, ShaderOper.RR);
|
||||
}
|
||||
|
||||
private static void EmitF2f(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
|
||||
{
|
||||
bool NegA = ((OpCode >> 45) & 1) != 0;
|
||||
|
@ -340,6 +355,28 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), OperA), OpCode));
|
||||
}
|
||||
|
||||
private static void EmitSel(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
|
||||
{
|
||||
ShaderIrOperGpr Dst = GetOperGpr0 (OpCode);
|
||||
ShaderIrNode Pred = GetOperPred39N(OpCode);
|
||||
|
||||
ShaderIrNode ResultA = GetOperGpr8(OpCode);
|
||||
ShaderIrNode ResultB;
|
||||
|
||||
switch (Oper)
|
||||
{
|
||||
case ShaderOper.CR: ResultB = GetOperCbuf34 (OpCode); break;
|
||||
case ShaderOper.Imm: ResultB = GetOperImm19_20(OpCode); break;
|
||||
case ShaderOper.RR: ResultB = GetOperGpr20 (OpCode); break;
|
||||
|
||||
default: throw new ArgumentException(nameof(Oper));
|
||||
}
|
||||
|
||||
Block.AddNode(GetPredNode(new ShaderIrCond(Pred, new ShaderIrAsg(Dst, ResultA), false), OpCode));
|
||||
|
||||
Block.AddNode(GetPredNode(new ShaderIrCond(Pred, new ShaderIrAsg(Dst, ResultB), true), OpCode));
|
||||
}
|
||||
|
||||
private static IntType GetIntType(long OpCode)
|
||||
{
|
||||
bool Signed = ((OpCode >> 13) & 1) != 0;
|
||||
|
|
|
@ -64,6 +64,10 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
Set("0100110011100x", ShaderDecode.I2i_C);
|
||||
Set("0011100x11100x", ShaderDecode.I2i_I);
|
||||
Set("0101110011100x", ShaderDecode.I2i_R);
|
||||
Set("0001110xxxxxxx", ShaderDecode.Iadd_I32_1c0);
|
||||
Set("0100110000010x", ShaderDecode.Iadd_C);
|
||||
Set("0011100000010x", ShaderDecode.Iadd_I);
|
||||
Set("0101110000010x", ShaderDecode.Iadd_R);
|
||||
Set("0100110000100x", ShaderDecode.Imnmx_C);
|
||||
Set("0011100x00100x", ShaderDecode.Imnmx_I);
|
||||
Set("0101110000100x", ShaderDecode.Imnmx_R);
|
||||
|
@ -87,6 +91,9 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
Set("0100110010010x", ShaderDecode.Rro_C);
|
||||
Set("0011100x10010x", ShaderDecode.Rro_I);
|
||||
Set("0101110010010x", ShaderDecode.Rro_R);
|
||||
Set("0100110010100x", ShaderDecode.Sel_C);
|
||||
Set("0011100010100x", ShaderDecode.Sel_I);
|
||||
Set("0101110010100x", ShaderDecode.Sel_R);
|
||||
Set("0100110001001x", ShaderDecode.Shl_C);
|
||||
Set("0011100x01001x", ShaderDecode.Shl_I);
|
||||
Set("0101110001001x", ShaderDecode.Shl_R);
|
||||
|
|
Loading…
Add table
Reference in a new issue