aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-08-13 19:46:36 -0300
committerGitHub <noreply@github.com>2018-08-13 19:46:36 -0300
commit4f499b6845f7f46542cde945bad8f3275d3a11d5 (patch)
tree1d3e59451d0dc9761b0971a989e61175857d7a4d /Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs
parent6e483120527c749854066b1ab0c5a1d53d49f0e3 (diff)
Fix FMUL and TEXS shader instructions (#347)
Diffstat (limited to 'Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs')
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs95
1 files changed, 55 insertions, 40 deletions
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs
index 8486d8a7..b60da7c1 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs
@@ -23,12 +23,12 @@ namespace Ryujinx.Graphics.Gal.Shader
public static void Fadd_C(ShaderIrBlock Block, long OpCode)
{
- EmitAluBinaryF(Block, OpCode, ShaderOper.CR, ShaderIrInst.Fadd);
+ EmitFadd(Block, OpCode, ShaderOper.CR);
}
public static void Fadd_I(ShaderIrBlock Block, long OpCode)
{
- EmitAluBinaryF(Block, OpCode, ShaderOper.Immf, ShaderIrInst.Fadd);
+ EmitFadd(Block, OpCode, ShaderOper.Immf);
}
public static void Fadd_I32(ShaderIrBlock Block, long OpCode)
@@ -51,7 +51,7 @@ namespace Ryujinx.Graphics.Gal.Shader
public static void Fadd_R(ShaderIrBlock Block, long OpCode)
{
- EmitAluBinaryF(Block, OpCode, ShaderOper.RR, ShaderIrInst.Fadd);
+ EmitFadd(Block, OpCode, ShaderOper.RR);
}
public static void Ffma_CR(ShaderIrBlock Block, long OpCode)
@@ -101,17 +101,17 @@ namespace Ryujinx.Graphics.Gal.Shader
public static void Fmul_C(ShaderIrBlock Block, long OpCode)
{
- EmitAluBinaryF(Block, OpCode, ShaderOper.CR, ShaderIrInst.Fmul);
+ EmitFmul(Block, OpCode, ShaderOper.CR);
}
public static void Fmul_I(ShaderIrBlock Block, long OpCode)
{
- EmitAluBinaryF(Block, OpCode, ShaderOper.Immf, ShaderIrInst.Fmul);
+ EmitFmul(Block, OpCode, ShaderOper.Immf);
}
public static void Fmul_R(ShaderIrBlock Block, long OpCode)
{
- EmitAluBinaryF(Block, OpCode, ShaderOper.RR, ShaderIrInst.Fmul);
+ EmitFmul(Block, OpCode, ShaderOper.RR);
}
public static void Fset_C(ShaderIrBlock Block, long OpCode)
@@ -519,40 +519,6 @@ namespace Ryujinx.Graphics.Gal.Shader
Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
}
- private static void EmitAluBinaryF(
- ShaderIrBlock Block,
- long OpCode,
- ShaderOper Oper,
- ShaderIrInst Inst)
- {
- bool NegB = ((OpCode >> 45) & 1) != 0;
- bool AbsA = ((OpCode >> 46) & 1) != 0;
- bool NegA = ((OpCode >> 48) & 1) != 0;
- bool AbsB = ((OpCode >> 49) & 1) != 0;
-
- ShaderIrNode OperA = GetOperGpr8(OpCode), OperB;
-
- if (Inst == ShaderIrInst.Fadd)
- {
- OperA = GetAluFabsFneg(OperA, AbsA, NegA);
- }
-
- switch (Oper)
- {
- case ShaderOper.CR: OperB = GetOperCbuf34 (OpCode); break;
- case ShaderOper.Immf: OperB = GetOperImmf19_20(OpCode); break;
- case ShaderOper.RR: OperB = GetOperGpr20 (OpCode); break;
-
- default: throw new ArgumentException(nameof(Oper));
- }
-
- OperB = GetAluFabsFneg(OperB, AbsB, NegB);
-
- ShaderIrNode Op = new ShaderIrOp(Inst, OperA, OperB);
-
- Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
- }
-
private static void EmitBfe(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
{
//TODO: Handle the case where position + length
@@ -609,6 +575,55 @@ namespace Ryujinx.Graphics.Gal.Shader
Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
}
+ private static void EmitFadd(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
+ {
+ bool NegB = ((OpCode >> 45) & 1) != 0;
+ bool AbsA = ((OpCode >> 46) & 1) != 0;
+ bool NegA = ((OpCode >> 48) & 1) != 0;
+ bool AbsB = ((OpCode >> 49) & 1) != 0;
+
+ ShaderIrNode OperA = GetOperGpr8(OpCode), OperB;
+
+ OperA = GetAluFabsFneg(OperA, AbsA, NegA);
+
+ switch (Oper)
+ {
+ case ShaderOper.CR: OperB = GetOperCbuf34 (OpCode); break;
+ case ShaderOper.Immf: OperB = GetOperImmf19_20(OpCode); break;
+ case ShaderOper.RR: OperB = GetOperGpr20 (OpCode); break;
+
+ default: throw new ArgumentException(nameof(Oper));
+ }
+
+ OperB = GetAluFabsFneg(OperB, AbsB, NegB);
+
+ ShaderIrNode Op = new ShaderIrOp(ShaderIrInst.Fadd, OperA, OperB);
+
+ Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
+ }
+
+ private static void EmitFmul(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
+ {
+ bool NegB = ((OpCode >> 48) & 1) != 0;
+
+ ShaderIrNode OperA = GetOperGpr8(OpCode), OperB;
+
+ switch (Oper)
+ {
+ case ShaderOper.CR: OperB = GetOperCbuf34 (OpCode); break;
+ case ShaderOper.Immf: OperB = GetOperImmf19_20(OpCode); break;
+ case ShaderOper.RR: OperB = GetOperGpr20 (OpCode); break;
+
+ default: throw new ArgumentException(nameof(Oper));
+ }
+
+ OperB = GetAluFneg(OperB, NegB);
+
+ ShaderIrNode Op = new ShaderIrOp(ShaderIrInst.Fmul, OperA, OperB);
+
+ Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
+ }
+
private static void EmitFfma(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
{
bool NegB = ((OpCode >> 48) & 1) != 0;