diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2022-01-10 12:08:00 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-10 12:08:00 -0300 |
| commit | 7f6b3d234a0dd82866e89930f05c520aca94946e (patch) | |
| tree | 49459142740eed719d431d9dc9ae37b0ff472ee8 /Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs | |
| parent | 952c6e4d454082da900a447e6bd1deb272c150c2 (diff) | |
Implement IMUL, PCNT and CONT shader instructions, fix FFMA32I and HFMA32I (#2972)
* Implement IMUL shader instruction
* Implement PCNT/CONT instruction and fix FFMA32I
* Add HFMA232I to the table
* Shader cache version bump
* No Rc on Ffma32i
Diffstat (limited to 'Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs')
| -rw-r--r-- | Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs index ac8cca1b..374e3d61 100644 --- a/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs +++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs @@ -138,6 +138,46 @@ namespace Ryujinx.Graphics.Shader.Instructions EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo); } + public static void ImulR(EmitterContext context) + { + InstImulR op = context.GetOp<InstImulR>(); + + var srcA = GetSrcReg(context, op.SrcA); + var srcB = GetSrcReg(context, op.SrcB); + + EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo); + } + + public static void ImulI(EmitterContext context) + { + InstImulI op = context.GetOp<InstImulI>(); + + var srcA = GetSrcReg(context, op.SrcA); + var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20)); + + EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo); + } + + public static void ImulC(EmitterContext context) + { + InstImulC op = context.GetOp<InstImulC>(); + + var srcA = GetSrcReg(context, op.SrcA); + var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); + + EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo); + } + + public static void Imul32i(EmitterContext context) + { + InstImul32i op = context.GetOp<InstImul32i>(); + + var srcA = GetSrcReg(context, op.SrcA); + var srcB = GetSrcImm(context, op.Imm32); + + EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo); + } + public static void IscaddR(EmitterContext context) { InstIscaddR op = context.GetOp<InstIscaddR>(); @@ -366,7 +406,7 @@ namespace Ryujinx.Graphics.Shader.Instructions // TODO: CC, X, corner cases. } - public static void EmitImad( + private static void EmitImad( EmitterContext context, Operand srcA, Operand srcB, @@ -407,7 +447,10 @@ namespace Ryujinx.Graphics.Shader.Instructions res = context.IMultiply(srcA, srcB); } - res = context.IAdd(res, srcC); + if (srcC.Type != OperandType.Constant || srcC.Value != 0) + { + res = context.IAdd(res, srcC); + } // TODO: CC, X, SAT, and more? |
