diff options
Diffstat (limited to 'Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs')
| -rw-r--r-- | Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs | 699 |
1 files changed, 0 insertions, 699 deletions
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs deleted file mode 100644 index 374e3d61..00000000 --- a/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs +++ /dev/null @@ -1,699 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; - -using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper; -using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void IaddR(EmitterContext context) - { - InstIaddR op = context.GetOp<InstIaddR>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcReg(context, op.SrcB); - - EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC); - } - - public static void IaddI(EmitterContext context) - { - InstIaddI op = context.GetOp<InstIaddI>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20)); - - EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC); - } - - public static void IaddC(EmitterContext context) - { - InstIaddC op = context.GetOp<InstIaddC>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); - - EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC); - } - - public static void Iadd32i(EmitterContext context) - { - InstIadd32i op = context.GetOp<InstIadd32i>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcImm(context, op.Imm32); - - EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC); - } - - public static void Iadd3R(EmitterContext context) - { - InstIadd3R op = context.GetOp<InstIadd3R>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcReg(context, op.SrcB); - var srcC = GetSrcReg(context, op.SrcC); - - EmitIadd3(context, op.Lrs, srcA, srcB, srcC, op.Apart, op.Bpart, op.Cpart, op.Dest, op.NegA, op.NegB, op.NegC); - } - - public static void Iadd3I(EmitterContext context) - { - InstIadd3I op = context.GetOp<InstIadd3I>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20)); - var srcC = GetSrcReg(context, op.SrcC); - - EmitIadd3(context, Lrs.None, srcA, srcB, srcC, HalfSelect.B32, HalfSelect.B32, HalfSelect.B32, op.Dest, op.NegA, op.NegB, op.NegC); - } - - public static void Iadd3C(EmitterContext context) - { - InstIadd3C op = context.GetOp<InstIadd3C>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); - var srcC = GetSrcReg(context, op.SrcC); - - EmitIadd3(context, Lrs.None, srcA, srcB, srcC, HalfSelect.B32, HalfSelect.B32, HalfSelect.B32, op.Dest, op.NegA, op.NegB, op.NegC); - } - - public static void ImadR(EmitterContext context) - { - InstImadR op = context.GetOp<InstImadR>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcReg(context, op.SrcB); - var srcC = GetSrcReg(context, op.SrcC); - - EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo); - } - - public static void ImadI(EmitterContext context) - { - InstImadI op = context.GetOp<InstImadI>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20)); - var srcC = GetSrcReg(context, op.SrcC); - - EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo); - } - - public static void ImadC(EmitterContext context) - { - InstImadC op = context.GetOp<InstImadC>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); - var srcC = GetSrcReg(context, op.SrcC); - - EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo); - } - - public static void ImadRc(EmitterContext context) - { - InstImadRc op = context.GetOp<InstImadRc>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcReg(context, op.SrcC); - var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); - - EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo); - } - - public static void Imad32i(EmitterContext context) - { - InstImad32i op = context.GetOp<InstImad32i>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcImm(context, op.Imm32); - var srcC = GetSrcReg(context, op.Dest); - - 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>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcReg(context, op.SrcB); - - EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, op.AvgMode, op.WriteCC); - } - - public static void IscaddI(EmitterContext context) - { - InstIscaddI op = context.GetOp<InstIscaddI>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20)); - - EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, op.AvgMode, op.WriteCC); - } - - public static void IscaddC(EmitterContext context) - { - InstIscaddC op = context.GetOp<InstIscaddC>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); - - EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, op.AvgMode, op.WriteCC); - } - - public static void Iscadd32i(EmitterContext context) - { - InstIscadd32i op = context.GetOp<InstIscadd32i>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcImm(context, op.Imm32); - - EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, AvgMode.NoNeg, op.WriteCC); - } - - public static void LeaR(EmitterContext context) - { - InstLeaR op = context.GetOp<InstLeaR>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcReg(context, op.SrcB); - - EmitLea(context, srcA, srcB, op.Dest, op.NegA, op.ImmU5); - } - - public static void LeaI(EmitterContext context) - { - InstLeaI op = context.GetOp<InstLeaI>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20)); - - EmitLea(context, srcA, srcB, op.Dest, op.NegA, op.ImmU5); - } - - public static void LeaC(EmitterContext context) - { - InstLeaC op = context.GetOp<InstLeaC>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); - - EmitLea(context, srcA, srcB, op.Dest, op.NegA, op.ImmU5); - } - - public static void LeaHiR(EmitterContext context) - { - InstLeaHiR op = context.GetOp<InstLeaHiR>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcReg(context, op.SrcB); - var srcC = GetSrcReg(context, op.SrcC); - - EmitLeaHi(context, srcA, srcB, srcC, op.Dest, op.NegA, op.ImmU5); - } - - public static void LeaHiC(EmitterContext context) - { - InstLeaHiC op = context.GetOp<InstLeaHiC>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); - var srcC = GetSrcReg(context, op.SrcC); - - EmitLeaHi(context, srcA, srcB, srcC, op.Dest, op.NegA, op.ImmU5); - } - - public static void XmadR(EmitterContext context) - { - InstXmadR op = context.GetOp<InstXmadR>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcReg(context, op.SrcB); - var srcC = GetSrcReg(context, op.SrcC); - - EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, op.HiloB, op.Psl, op.Mrg, op.X, op.WriteCC); - } - - public static void XmadI(EmitterContext context) - { - InstXmadI op = context.GetOp<InstXmadI>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcImm(context, op.Imm16); - var srcC = GetSrcReg(context, op.SrcC); - - EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, false, op.Psl, op.Mrg, op.X, op.WriteCC); - } - - public static void XmadC(EmitterContext context) - { - InstXmadC op = context.GetOp<InstXmadC>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); - var srcC = GetSrcReg(context, op.SrcC); - - EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, op.HiloB, op.Psl, op.Mrg, op.X, op.WriteCC); - } - - public static void XmadRc(EmitterContext context) - { - InstXmadRc op = context.GetOp<InstXmadRc>(); - - var srcA = GetSrcReg(context, op.SrcA); - var srcB = GetSrcReg(context, op.SrcC); - var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); - - EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, op.HiloB, false, false, op.X, op.WriteCC); - } - - private static void EmitIadd( - EmitterContext context, - Operand srcA, - Operand srcB, - int rd, - AvgMode avgMode, - bool extended, - bool writeCC) - { - srcA = context.INegate(srcA, avgMode == AvgMode.NegA); - srcB = context.INegate(srcB, avgMode == AvgMode.NegB); - - Operand res = context.IAdd(srcA, srcB); - - if (extended) - { - res = context.IAdd(res, context.BitwiseAnd(GetCF(), Const(1))); - } - - SetIaddFlags(context, res, srcA, srcB, writeCC, extended); - - // TODO: SAT. - - context.Copy(GetDest(rd), res); - } - - private static void EmitIadd3( - EmitterContext context, - Lrs mode, - Operand srcA, - Operand srcB, - Operand srcC, - HalfSelect partA, - HalfSelect partB, - HalfSelect partC, - int rd, - bool negateA, - bool negateB, - bool negateC) - { - Operand Extend(Operand src, HalfSelect part) - { - if (part == HalfSelect.B32) - { - return src; - } - - if (part == HalfSelect.H0) - { - return context.BitwiseAnd(src, Const(0xffff)); - } - else if (part == HalfSelect.H1) - { - return context.ShiftRightU32(src, Const(16)); - } - else - { - context.Config.GpuAccessor.Log($"Iadd3 has invalid component selection {part}."); - } - - return src; - } - - srcA = context.INegate(Extend(srcA, partA), negateA); - srcB = context.INegate(Extend(srcB, partB), negateB); - srcC = context.INegate(Extend(srcC, partC), negateC); - - Operand res = context.IAdd(srcA, srcB); - - if (mode != Lrs.None) - { - if (mode == Lrs.LeftShift) - { - res = context.ShiftLeft(res, Const(16)); - } - else if (mode == Lrs.RightShift) - { - res = context.ShiftRightU32(res, Const(16)); - } - else - { - // TODO: Warning. - } - } - - res = context.IAdd(res, srcC); - - context.Copy(GetDest(rd), res); - - // TODO: CC, X, corner cases. - } - - private static void EmitImad( - EmitterContext context, - Operand srcA, - Operand srcB, - Operand srcC, - int rd, - AvgMode avgMode, - bool signedA, - bool signedB, - bool high) - { - srcB = context.INegate(srcB, avgMode == AvgMode.NegA); - srcC = context.INegate(srcC, avgMode == AvgMode.NegB); - - Operand res; - - if (high) - { - if (signedA && signedB) - { - res = context.MultiplyHighS32(srcA, srcB); - } - else - { - res = context.MultiplyHighU32(srcA, srcB); - - if (signedA) - { - res = context.IAdd(res, context.IMultiply(srcB, context.ShiftRightS32(srcA, Const(31)))); - } - else if (signedB) - { - res = context.IAdd(res, context.IMultiply(srcA, context.ShiftRightS32(srcB, Const(31)))); - } - } - } - else - { - res = context.IMultiply(srcA, srcB); - } - - if (srcC.Type != OperandType.Constant || srcC.Value != 0) - { - res = context.IAdd(res, srcC); - } - - // TODO: CC, X, SAT, and more? - - context.Copy(GetDest(rd), res); - } - - private static void EmitIscadd( - EmitterContext context, - Operand srcA, - Operand srcB, - int rd, - int shift, - AvgMode avgMode, - bool writeCC) - { - srcA = context.ShiftLeft(srcA, Const(shift)); - - srcA = context.INegate(srcA, avgMode == AvgMode.NegA); - srcB = context.INegate(srcB, avgMode == AvgMode.NegB); - - Operand res = context.IAdd(srcA, srcB); - - SetIaddFlags(context, res, srcA, srcB, writeCC, false); - - context.Copy(GetDest(rd), res); - } - - public static void EmitLea(EmitterContext context, Operand srcA, Operand srcB, int rd, bool negateA, int shift) - { - srcA = context.ShiftLeft(srcA, Const(shift)); - srcA = context.INegate(srcA, negateA); - - Operand res = context.IAdd(srcA, srcB); - - context.Copy(GetDest(rd), res); - - // TODO: CC, X. - } - - private static void EmitLeaHi( - EmitterContext context, - Operand srcA, - Operand srcB, - Operand srcC, - int rd, - bool negateA, - int shift) - { - Operand aLow = context.ShiftLeft(srcA, Const(shift)); - Operand aHigh = shift == 0 ? Const(0) : context.ShiftRightU32(srcA, Const(32 - shift)); - aHigh = context.BitwiseOr(aHigh, context.ShiftLeft(srcC, Const(shift))); - - if (negateA) - { - // Perform 64-bit negation by doing bitwise not of the value, - // then adding 1 and carrying over from low to high. - aLow = context.BitwiseNot(aLow); - aHigh = context.BitwiseNot(aHigh); - - aLow = AddWithCarry(context, aLow, Const(1), out Operand aLowCOut); - aHigh = context.IAdd(aHigh, aLowCOut); - } - - Operand res = context.IAdd(aHigh, srcB); - - context.Copy(GetDest(rd), res); - - // TODO: CC, X. - } - - public static void EmitXmad( - EmitterContext context, - XmadCop2 mode, - Operand srcA, - Operand srcB, - Operand srcC, - int rd, - bool signedA, - bool signedB, - bool highA, - bool highB, - bool productShiftLeft, - bool merge, - bool extended, - bool writeCC) - { - XmadCop modeConv; - switch (mode) - { - case XmadCop2.Cfull: - modeConv = XmadCop.Cfull; - break; - case XmadCop2.Clo: - modeConv = XmadCop.Clo; - break; - case XmadCop2.Chi: - modeConv = XmadCop.Chi; - break; - case XmadCop2.Csfu: - modeConv = XmadCop.Csfu; - break; - default: - context.Config.GpuAccessor.Log($"Invalid XMAD mode \"{mode}\"."); - return; - } - - EmitXmad(context, modeConv, srcA, srcB, srcC, rd, signedA, signedB, highA, highB, productShiftLeft, merge, extended, writeCC); - } - - public static void EmitXmad( - EmitterContext context, - XmadCop mode, - Operand srcA, - Operand srcB, - Operand srcC, - int rd, - bool signedA, - bool signedB, - bool highA, - bool highB, - bool productShiftLeft, - bool merge, - bool extended, - bool writeCC) - { - var srcBUnmodified = srcB; - - Operand Extend16To32(Operand src, bool high, bool signed) - { - if (signed && high) - { - return context.ShiftRightS32(src, Const(16)); - } - else if (signed) - { - return context.BitfieldExtractS32(src, Const(0), Const(16)); - } - else if (high) - { - return context.ShiftRightU32(src, Const(16)); - } - else - { - return context.BitwiseAnd(src, Const(0xffff)); - } - } - - srcA = Extend16To32(srcA, highA, signedA); - srcB = Extend16To32(srcB, highB, signedB); - - Operand res = context.IMultiply(srcA, srcB); - - if (productShiftLeft) - { - res = context.ShiftLeft(res, Const(16)); - } - - switch (mode) - { - case XmadCop.Cfull: - break; - - case XmadCop.Clo: - srcC = Extend16To32(srcC, high: false, signed: false); - break; - case XmadCop.Chi: - srcC = Extend16To32(srcC, high: true, signed: false); - break; - - case XmadCop.Cbcc: - srcC = context.IAdd(srcC, context.ShiftLeft(srcBUnmodified, Const(16))); - break; - - case XmadCop.Csfu: - Operand signAdjustA = context.ShiftLeft(context.ShiftRightU32(srcA, Const(31)), Const(16)); - Operand signAdjustB = context.ShiftLeft(context.ShiftRightU32(srcB, Const(31)), Const(16)); - - srcC = context.ISubtract(srcC, context.IAdd(signAdjustA, signAdjustB)); - break; - - default: - context.Config.GpuAccessor.Log($"Invalid XMAD mode \"{mode}\"."); - return; - } - - Operand product = res; - - if (extended) - { - // Add with carry. - res = context.IAdd(res, context.BitwiseAnd(GetCF(), Const(1))); - } - else - { - // Add (no carry in). - res = context.IAdd(res, srcC); - } - - SetIaddFlags(context, res, product, srcC, writeCC, extended); - - if (merge) - { - res = context.BitwiseAnd(res, Const(0xffff)); - res = context.BitwiseOr(res, context.ShiftLeft(srcBUnmodified, Const(16))); - } - - context.Copy(GetDest(rd), res); - } - - private static void SetIaddFlags(EmitterContext context, Operand res, Operand srcA, Operand srcB, bool setCC, bool extended) - { - if (!setCC) - { - return; - } - - if (extended) - { - // C = (d == a && CIn) || d < a - Operand tempC0 = context.ICompareEqual(res, srcA); - Operand tempC1 = context.ICompareLessUnsigned(res, srcA); - - tempC0 = context.BitwiseAnd(tempC0, GetCF()); - - context.Copy(GetCF(), context.BitwiseOr(tempC0, tempC1)); - } - else - { - // C = d < a - context.Copy(GetCF(), context.ICompareLessUnsigned(res, srcA)); - } - - // V = (d ^ a) & ~(a ^ b) < 0 - Operand tempV0 = context.BitwiseExclusiveOr(res, srcA); - Operand tempV1 = context.BitwiseExclusiveOr(srcA, srcB); - - tempV1 = context.BitwiseNot(tempV1); - - Operand tempV = context.BitwiseAnd(tempV0, tempV1); - - context.Copy(GetVF(), context.ICompareLess(tempV, Const(0))); - - SetZnFlags(context, res, setCC: true, extended: extended); - } - } -}
\ No newline at end of file |
