aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2019-10-13 03:02:07 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commit1876b346fea647e8284a66bb6d62c38801035cff (patch)
tree6eeff094298cda84d1613dc5ec0691e51d7b35f1 /Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs
parentf617fb542a0e3d36012d77a4b5acbde7b08902f2 (diff)
Initial work
Diffstat (limited to 'Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs')
-rw-r--r--Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs684
1 files changed, 0 insertions, 684 deletions
diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs
deleted file mode 100644
index 8e2b39bf..00000000
--- a/Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs
+++ /dev/null
@@ -1,684 +0,0 @@
-using Ryujinx.Graphics.Shader.Decoders;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-using System;
-
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
-using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
- static partial class InstEmit
- {
- public static void Bfe(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool isReverse = op.RawOpCode.Extract(40);
- bool isSigned = op.RawOpCode.Extract(48);
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
-
- if (isReverse)
- {
- srcA = context.BitfieldReverse(srcA);
- }
-
- Operand position = context.BitwiseAnd(srcB, Const(0xff));
-
- Operand size = context.BitfieldExtractU32(srcB, Const(8), Const(8));
-
- Operand res = isSigned
- ? context.BitfieldExtractS32(srcA, position, size)
- : context.BitfieldExtractU32(srcA, position, size);
-
- context.Copy(GetDest(context), res);
-
- // TODO: CC, X, corner cases
- }
-
- public static void Iadd(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool negateA = false, negateB = false;
-
- if (!(op is OpCodeAluImm32))
- {
- negateB = op.RawOpCode.Extract(48);
- negateA = op.RawOpCode.Extract(49);
- }
-
- Operand srcA = context.INegate(GetSrcA(context), negateA);
- Operand srcB = context.INegate(GetSrcB(context), negateB);
-
- Operand res = context.IAdd(srcA, srcB);
-
- bool isSubtraction = negateA || negateB;
-
- if (op.Extended)
- {
- // Add carry, or subtract borrow.
- res = context.IAdd(res, isSubtraction
- ? context.BitwiseNot(GetCF(context))
- : context.BitwiseAnd(GetCF(context), Const(1)));
- }
-
- SetIaddFlags(context, res, srcA, srcB, op.SetCondCode, op.Extended, isSubtraction);
-
- context.Copy(GetDest(context), res);
- }
-
- public static void Iadd3(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- IntegerHalfPart partC = (IntegerHalfPart)op.RawOpCode.Extract(31, 2);
- IntegerHalfPart partB = (IntegerHalfPart)op.RawOpCode.Extract(33, 2);
- IntegerHalfPart partA = (IntegerHalfPart)op.RawOpCode.Extract(35, 2);
-
- IntegerShift mode = (IntegerShift)op.RawOpCode.Extract(37, 2);
-
- bool negateC = op.RawOpCode.Extract(49);
- bool negateB = op.RawOpCode.Extract(50);
- bool negateA = op.RawOpCode.Extract(51);
-
- Operand Extend(Operand src, IntegerHalfPart part)
- {
- if (!(op is OpCodeAluReg) || part == IntegerHalfPart.B32)
- {
- return src;
- }
-
- if (part == IntegerHalfPart.H0)
- {
- return context.BitwiseAnd(src, Const(0xffff));
- }
- else if (part == IntegerHalfPart.H1)
- {
- return context.ShiftRightU32(src, Const(16));
- }
- else
- {
- // TODO: Warning.
- }
-
- return src;
- }
-
- Operand srcA = context.INegate(Extend(GetSrcA(context), partA), negateA);
- Operand srcB = context.INegate(Extend(GetSrcB(context), partB), negateB);
- Operand srcC = context.INegate(Extend(GetSrcC(context), partC), negateC);
-
- Operand res = context.IAdd(srcA, srcB);
-
- if (op is OpCodeAluReg && mode != IntegerShift.NoShift)
- {
- if (mode == IntegerShift.ShiftLeft)
- {
- res = context.ShiftLeft(res, Const(16));
- }
- else if (mode == IntegerShift.ShiftRight)
- {
- res = context.ShiftRightU32(res, Const(16));
- }
- else
- {
- // TODO: Warning.
- }
- }
-
- res = context.IAdd(res, srcC);
-
- context.Copy(GetDest(context), res);
-
- // TODO: CC, X, corner cases
- }
-
- public static void Imnmx(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool isSignedInt = op.RawOpCode.Extract(48);
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
-
- Operand resMin = isSignedInt
- ? context.IMinimumS32(srcA, srcB)
- : context.IMinimumU32(srcA, srcB);
-
- Operand resMax = isSignedInt
- ? context.IMaximumS32(srcA, srcB)
- : context.IMaximumU32(srcA, srcB);
-
- Operand pred = GetPredicate39(context);
-
- Operand dest = GetDest(context);
-
- context.Copy(dest, context.ConditionalSelect(pred, resMin, resMax));
-
- SetZnFlags(context, dest, op.SetCondCode);
-
- // TODO: X flags.
- }
-
- public static void Iscadd(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool negateA = false, negateB = false;
-
- if (!(op is OpCodeAluImm32))
- {
- negateB = op.RawOpCode.Extract(48);
- negateA = op.RawOpCode.Extract(49);
- }
-
- int shift = op is OpCodeAluImm32
- ? op.RawOpCode.Extract(53, 5)
- : op.RawOpCode.Extract(39, 5);
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
-
- srcA = context.ShiftLeft(srcA, Const(shift));
-
- srcA = context.INegate(srcA, negateA);
- srcB = context.INegate(srcB, negateB);
-
- Operand res = context.IAdd(srcA, srcB);
-
- context.Copy(GetDest(context), res);
-
- // TODO: CC, X
- }
-
- public static void Iset(EmitterContext context)
- {
- OpCodeSet op = (OpCodeSet)context.CurrOp;
-
- bool boolFloat = op.RawOpCode.Extract(44);
- bool isSigned = op.RawOpCode.Extract(48);
-
- IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3);
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
-
- Operand res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned);
-
- Operand pred = GetPredicate39(context);
-
- res = GetPredLogicalOp(context, op.LogicalOp, res, pred);
-
- Operand dest = GetDest(context);
-
- if (boolFloat)
- {
- context.Copy(dest, context.ConditionalSelect(res, ConstF(1), Const(0)));
- }
- else
- {
- context.Copy(dest, res);
- }
-
- // TODO: CC, X
- }
-
- public static void Isetp(EmitterContext context)
- {
- OpCodeSet op = (OpCodeSet)context.CurrOp;
-
- bool isSigned = op.RawOpCode.Extract(48);
-
- IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3);
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
-
- Operand p0Res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned);
-
- Operand p1Res = context.BitwiseNot(p0Res);
-
- Operand pred = GetPredicate39(context);
-
- p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred);
- p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred);
-
- context.Copy(Register(op.Predicate3), p0Res);
- context.Copy(Register(op.Predicate0), p1Res);
- }
-
- public static void Lop(EmitterContext context)
- {
- IOpCodeLop op = (IOpCodeLop)context.CurrOp;
-
- Operand srcA = context.BitwiseNot(GetSrcA(context), op.InvertA);
- Operand srcB = context.BitwiseNot(GetSrcB(context), op.InvertB);
-
- Operand res = srcB;
-
- switch (op.LogicalOp)
- {
- case LogicalOperation.And: res = context.BitwiseAnd (srcA, srcB); break;
- case LogicalOperation.Or: res = context.BitwiseOr (srcA, srcB); break;
- case LogicalOperation.ExclusiveOr: res = context.BitwiseExclusiveOr(srcA, srcB); break;
- }
-
- EmitLopPredWrite(context, op, res);
-
- Operand dest = GetDest(context);
-
- context.Copy(dest, res);
-
- SetZnFlags(context, dest, op.SetCondCode, op.Extended);
- }
-
- public static void Lop3(EmitterContext context)
- {
- IOpCodeLop op = (IOpCodeLop)context.CurrOp;
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
- Operand srcC = GetSrcC(context);
-
- bool regVariant = op is OpCodeLopReg;
-
- int truthTable = regVariant
- ? op.RawOpCode.Extract(28, 8)
- : op.RawOpCode.Extract(48, 8);
-
- Operand res = Lop3Expression.GetFromTruthTable(context, srcA, srcB, srcC, truthTable);
-
- if (regVariant)
- {
- EmitLopPredWrite(context, op, res);
- }
-
- Operand dest = GetDest(context);
-
- context.Copy(dest, res);
-
- SetZnFlags(context, dest, op.SetCondCode, op.Extended);
- }
-
- public static void Psetp(EmitterContext context)
- {
- OpCodePsetp op = (OpCodePsetp)context.CurrOp;
-
- bool invertA = op.RawOpCode.Extract(15);
- bool invertB = op.RawOpCode.Extract(32);
-
- Operand srcA = context.BitwiseNot(Register(op.Predicate12), invertA);
- Operand srcB = context.BitwiseNot(Register(op.Predicate29), invertB);
-
- Operand p0Res = GetPredLogicalOp(context, op.LogicalOpAB, srcA, srcB);
-
- Operand p1Res = context.BitwiseNot(p0Res);
-
- Operand pred = GetPredicate39(context);
-
- p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred);
- p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred);
-
- context.Copy(Register(op.Predicate3), p0Res);
- context.Copy(Register(op.Predicate0), p1Res);
- }
-
- public static void Rro(EmitterContext context)
- {
- // This is the range reduction operator,
- // we translate it as a simple move, as it
- // should be always followed by a matching
- // MUFU instruction.
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool negateB = op.RawOpCode.Extract(45);
- bool absoluteB = op.RawOpCode.Extract(49);
-
- Operand srcB = GetSrcB(context);
-
- srcB = context.FPAbsNeg(srcB, absoluteB, negateB);
-
- context.Copy(GetDest(context), srcB);
- }
-
- public static void Shl(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool isMasked = op.RawOpCode.Extract(39);
-
- Operand srcB = GetSrcB(context);
-
- if (isMasked)
- {
- srcB = context.BitwiseAnd(srcB, Const(0x1f));
- }
-
- Operand res = context.ShiftLeft(GetSrcA(context), srcB);
-
- if (!isMasked)
- {
- // Clamped shift value.
- Operand isLessThan32 = context.ICompareLessUnsigned(srcB, Const(32));
-
- res = context.ConditionalSelect(isLessThan32, res, Const(0));
- }
-
- // TODO: X, CC
-
- context.Copy(GetDest(context), res);
- }
-
- public static void Shr(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool isMasked = op.RawOpCode.Extract(39);
- bool isReverse = op.RawOpCode.Extract(40);
- bool isSigned = op.RawOpCode.Extract(48);
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
-
- if (isReverse)
- {
- srcA = context.BitfieldReverse(srcA);
- }
-
- if (isMasked)
- {
- srcB = context.BitwiseAnd(srcB, Const(0x1f));
- }
-
- Operand res = isSigned
- ? context.ShiftRightS32(srcA, srcB)
- : context.ShiftRightU32(srcA, srcB);
-
- if (!isMasked)
- {
- // Clamped shift value.
- Operand resShiftBy32;
-
- if (isSigned)
- {
- resShiftBy32 = context.ShiftRightS32(srcA, Const(31));
- }
- else
- {
- resShiftBy32 = Const(0);
- }
-
- Operand isLessThan32 = context.ICompareLessUnsigned(srcB, Const(32));
-
- res = context.ConditionalSelect(isLessThan32, res, resShiftBy32);
- }
-
- // TODO: X, CC
-
- context.Copy(GetDest(context), res);
- }
-
- public static void Xmad(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool signedA = context.CurrOp.RawOpCode.Extract(48);
- bool signedB = context.CurrOp.RawOpCode.Extract(49);
- bool highA = context.CurrOp.RawOpCode.Extract(53);
- bool highB = false;
-
- XmadCMode mode;
-
- if (op is OpCodeAluReg)
- {
- highB = context.CurrOp.RawOpCode.Extract(35);
-
- mode = (XmadCMode)context.CurrOp.RawOpCode.Extract(50, 3);
- }
- else
- {
- mode = (XmadCMode)context.CurrOp.RawOpCode.Extract(50, 2);
-
- if (!(op is OpCodeAluImm))
- {
- highB = context.CurrOp.RawOpCode.Extract(52);
- }
- }
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
- Operand srcC = GetSrcC(context);
-
- // XMAD immediates are 16-bits unsigned integers.
- if (srcB.Type == OperandType.Constant)
- {
- srcB = Const(srcB.Value & 0xffff);
- }
-
- 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);
-
- bool productShiftLeft = false;
- bool merge = false;
-
- if (!(op is OpCodeAluRegCbuf))
- {
- productShiftLeft = context.CurrOp.RawOpCode.Extract(36);
- merge = context.CurrOp.RawOpCode.Extract(37);
- }
-
- bool extended;
-
- if ((op is OpCodeAluReg) || (op is OpCodeAluImm))
- {
- extended = context.CurrOp.RawOpCode.Extract(38);
- }
- else
- {
- extended = context.CurrOp.RawOpCode.Extract(54);
- }
-
- Operand res = context.IMultiply(srcA, srcB);
-
- if (productShiftLeft)
- {
- res = context.ShiftLeft(res, Const(16));
- }
-
- switch (mode)
- {
- case XmadCMode.Cfull: break;
-
- case XmadCMode.Clo: srcC = Extend16To32(srcC, high: false, signed: false); break;
- case XmadCMode.Chi: srcC = Extend16To32(srcC, high: true, signed: false); break;
-
- case XmadCMode.Cbcc:
- {
- srcC = context.IAdd(srcC, context.ShiftLeft(GetSrcB(context), Const(16)));
-
- break;
- }
-
- case XmadCMode.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: /* TODO: Warning */ break;
- }
-
- Operand product = res;
-
- if (extended)
- {
- // Add with carry.
- res = context.IAdd(res, context.BitwiseAnd(GetCF(context), Const(1)));
- }
- else
- {
- // Add (no carry in).
- res = context.IAdd(res, srcC);
- }
-
- SetIaddFlags(context, res, product, srcC, op.SetCondCode, extended);
-
- if (merge)
- {
- res = context.BitwiseAnd(res, Const(0xffff));
- res = context.BitwiseOr(res, context.ShiftLeft(GetSrcB(context), Const(16)));
- }
-
- context.Copy(GetDest(context), res);
- }
-
- private static Operand GetIntComparison(
- EmitterContext context,
- IntegerCondition cond,
- Operand srcA,
- Operand srcB,
- bool isSigned)
- {
- Operand res;
-
- if (cond == IntegerCondition.Always)
- {
- res = Const(IrConsts.True);
- }
- else if (cond == IntegerCondition.Never)
- {
- res = Const(IrConsts.False);
- }
- else
- {
- Instruction inst;
-
- switch (cond)
- {
- case IntegerCondition.Less: inst = Instruction.CompareLessU32; break;
- case IntegerCondition.Equal: inst = Instruction.CompareEqual; break;
- case IntegerCondition.LessOrEqual: inst = Instruction.CompareLessOrEqualU32; break;
- case IntegerCondition.Greater: inst = Instruction.CompareGreaterU32; break;
- case IntegerCondition.NotEqual: inst = Instruction.CompareNotEqual; break;
- case IntegerCondition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqualU32; break;
-
- default: throw new InvalidOperationException($"Unexpected condition \"{cond}\".");
- }
-
- if (isSigned)
- {
- switch (cond)
- {
- case IntegerCondition.Less: inst = Instruction.CompareLess; break;
- case IntegerCondition.LessOrEqual: inst = Instruction.CompareLessOrEqual; break;
- case IntegerCondition.Greater: inst = Instruction.CompareGreater; break;
- case IntegerCondition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqual; break;
- }
- }
-
- res = context.Add(inst, Local(), srcA, srcB);
- }
-
- return res;
- }
-
- private static void EmitLopPredWrite(EmitterContext context, IOpCodeLop op, Operand result)
- {
- if (op is OpCodeLop opLop && !opLop.Predicate48.IsPT)
- {
- Operand pRes;
-
- if (opLop.CondOp == ConditionalOperation.False)
- {
- pRes = Const(IrConsts.False);
- }
- else if (opLop.CondOp == ConditionalOperation.True)
- {
- pRes = Const(IrConsts.True);
- }
- else if (opLop.CondOp == ConditionalOperation.Zero)
- {
- pRes = context.ICompareEqual(result, Const(0));
- }
- else /* if (opLop.CondOp == ConditionalOperation.NotZero) */
- {
- pRes = context.ICompareNotEqual(result, Const(0));
- }
-
- context.Copy(Register(opLop.Predicate48), pRes);
- }
- }
-
- private static void SetIaddFlags(
- EmitterContext context,
- Operand res,
- Operand srcA,
- Operand srcB,
- bool setCC,
- bool extended,
- bool isSubtraction = false)
- {
- if (!setCC)
- {
- return;
- }
-
- if (!extended || isSubtraction)
- {
- // C = d < a
- context.Copy(GetCF(context), context.ICompareLessUnsigned(res, srcA));
- }
- else
- {
- // C = (d == a && CIn) || d < a
- Operand tempC0 = context.ICompareEqual (res, srcA);
- Operand tempC1 = context.ICompareLessUnsigned(res, srcA);
-
- tempC0 = context.BitwiseAnd(tempC0, GetCF(context));
-
- context.Copy(GetCF(context), context.BitwiseOr(tempC0, tempC1));
- }
-
- // 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), context.ICompareLess(tempV, Const(0)));
-
- SetZnFlags(context, res, setCC: true, extended: extended);
- }
- }
-} \ No newline at end of file