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);
|
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)
|
public static void Imnmx_C(ShaderIrBlock Block, long OpCode)
|
||||||
{
|
{
|
||||||
EmitImnmx(Block, OpCode, ShaderOper.CR);
|
EmitImnmx(Block, OpCode, ShaderOper.CR);
|
||||||
|
@ -533,6 +562,31 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
|
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)
|
private static void EmitIscadd(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
|
||||||
{
|
{
|
||||||
bool NegB = ((OpCode >> 48) & 1) != 0;
|
bool NegB = ((OpCode >> 48) & 1) != 0;
|
||||||
|
|
|
@ -113,6 +113,21 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Gpr), OpCode));
|
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)
|
private static void EmitF2f(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
|
||||||
{
|
{
|
||||||
bool NegA = ((OpCode >> 45) & 1) != 0;
|
bool NegA = ((OpCode >> 45) & 1) != 0;
|
||||||
|
@ -340,6 +355,28 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), OperA), OpCode));
|
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)
|
private static IntType GetIntType(long OpCode)
|
||||||
{
|
{
|
||||||
bool Signed = ((OpCode >> 13) & 1) != 0;
|
bool Signed = ((OpCode >> 13) & 1) != 0;
|
||||||
|
|
|
@ -64,6 +64,10 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
Set("0100110011100x", ShaderDecode.I2i_C);
|
Set("0100110011100x", ShaderDecode.I2i_C);
|
||||||
Set("0011100x11100x", ShaderDecode.I2i_I);
|
Set("0011100x11100x", ShaderDecode.I2i_I);
|
||||||
Set("0101110011100x", ShaderDecode.I2i_R);
|
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("0100110000100x", ShaderDecode.Imnmx_C);
|
||||||
Set("0011100x00100x", ShaderDecode.Imnmx_I);
|
Set("0011100x00100x", ShaderDecode.Imnmx_I);
|
||||||
Set("0101110000100x", ShaderDecode.Imnmx_R);
|
Set("0101110000100x", ShaderDecode.Imnmx_R);
|
||||||
|
@ -87,6 +91,9 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
Set("0100110010010x", ShaderDecode.Rro_C);
|
Set("0100110010010x", ShaderDecode.Rro_C);
|
||||||
Set("0011100x10010x", ShaderDecode.Rro_I);
|
Set("0011100x10010x", ShaderDecode.Rro_I);
|
||||||
Set("0101110010010x", ShaderDecode.Rro_R);
|
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("0100110001001x", ShaderDecode.Shl_C);
|
||||||
Set("0011100x01001x", ShaderDecode.Shl_I);
|
Set("0011100x01001x", ShaderDecode.Shl_I);
|
||||||
Set("0101110001001x", ShaderDecode.Shl_R);
|
Set("0101110001001x", ShaderDecode.Shl_R);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue