diff options
| author | gdk <gab.dark.100@gmail.com> | 2019-10-13 03:02:07 -0300 |
|---|---|---|
| committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
| commit | 1876b346fea647e8284a66bb6d62c38801035cff (patch) | |
| tree | 6eeff094298cda84d1613dc5ec0691e51d7b35f1 /Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs | |
| parent | f617fb542a0e3d36012d77a4b5acbde7b08902f2 (diff) | |
Initial work
Diffstat (limited to 'Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs')
| -rw-r--r-- | Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs | 684 |
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 |
