| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- using Ryujinx.Graphics.Shader.Decoders;
- using Ryujinx.Graphics.Shader.IntermediateRepresentation;
- using Ryujinx.Graphics.Shader.Translation;
- using System;
- using System.Runtime.CompilerServices;
- using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
- namespace Ryujinx.Graphics.Shader.Instructions
- {
- static class InstEmitHelper
- {
- public static Operand GetZF()
- {
- return Register(0, RegisterType.Flag);
- }
- public static Operand GetNF()
- {
- return Register(1, RegisterType.Flag);
- }
- public static Operand GetCF()
- {
- return Register(2, RegisterType.Flag);
- }
- public static Operand GetVF()
- {
- return Register(3, RegisterType.Flag);
- }
- public static Operand GetDest(int rd)
- {
- return Register(rd, RegisterType.Gpr);
- }
- public static Operand GetDest2(int rd)
- {
- return Register(rd | 1, RegisterType.Gpr);
- }
- public static Operand GetSrcCbuf(EmitterContext context, int cbufSlot, int cbufOffset, bool isFP64 = false)
- {
- if (isFP64)
- {
- return context.PackDouble2x32(
- Cbuf(cbufSlot, cbufOffset),
- Cbuf(cbufSlot, cbufOffset + 1));
- }
- else
- {
- return Cbuf(cbufSlot, cbufOffset);
- }
- }
- public static Operand GetSrcImm(EmitterContext context, int imm, bool isFP64 = false)
- {
- if (isFP64)
- {
- return context.PackDouble2x32(Const(0), Const(imm));
- }
- else
- {
- return Const(imm);
- }
- }
- public static Operand GetSrcReg(EmitterContext context, int reg, bool isFP64 = false)
- {
- if (isFP64)
- {
- return context.PackDouble2x32(Register(reg, RegisterType.Gpr), Register(reg | 1, RegisterType.Gpr));
- }
- else
- {
- return Register(reg, RegisterType.Gpr);
- }
- }
- public static Operand[] GetHalfSrc(
- EmitterContext context,
- HalfSwizzle swizzle,
- int ra,
- bool negate,
- bool absolute)
- {
- Operand[] operands = GetHalfUnpacked(context, GetSrcReg(context, ra), swizzle);
- return FPAbsNeg(context, operands, absolute, negate);
- }
- public static Operand[] GetHalfSrc(
- EmitterContext context,
- HalfSwizzle swizzle,
- int cbufSlot,
- int cbufOffset,
- bool negate,
- bool absolute)
- {
- Operand[] operands = GetHalfUnpacked(context, GetSrcCbuf(context, cbufSlot, cbufOffset), swizzle);
- return FPAbsNeg(context, operands, absolute, negate);
- }
- public static Operand[] GetHalfSrc(EmitterContext context, int immH0, int immH1)
- {
- ushort low = (ushort)(immH0 << 6);
- ushort high = (ushort)(immH1 << 6);
- return new Operand[]
- {
- ConstF((float)Unsafe.As<ushort, Half>(ref low)),
- ConstF((float)Unsafe.As<ushort, Half>(ref high))
- };
- }
- public static Operand[] GetHalfSrc(EmitterContext context, int imm32)
- {
- ushort low = (ushort)imm32;
- ushort high = (ushort)(imm32 >> 16);
- return new Operand[]
- {
- ConstF((float)Unsafe.As<ushort, Half>(ref low)),
- ConstF((float)Unsafe.As<ushort, Half>(ref high))
- };
- }
- public static Operand[] FPAbsNeg(EmitterContext context, Operand[] operands, bool abs, bool neg)
- {
- for (int index = 0; index < operands.Length; index++)
- {
- operands[index] = context.FPAbsNeg(operands[index], abs, neg);
- }
- return operands;
- }
- public static Operand[] GetHalfUnpacked(EmitterContext context, Operand src, HalfSwizzle swizzle)
- {
- switch (swizzle)
- {
- case HalfSwizzle.F16:
- return new Operand[]
- {
- context.UnpackHalf2x16Low (src),
- context.UnpackHalf2x16High(src)
- };
- case HalfSwizzle.F32: return new Operand[] { src, src };
- case HalfSwizzle.H0H0:
- return new Operand[]
- {
- context.UnpackHalf2x16Low(src),
- context.UnpackHalf2x16Low(src)
- };
- case HalfSwizzle.H1H1:
- return new Operand[]
- {
- context.UnpackHalf2x16High(src),
- context.UnpackHalf2x16High(src)
- };
- }
- throw new ArgumentException($"Invalid swizzle \"{swizzle}\".");
- }
- public static Operand GetHalfPacked(EmitterContext context, OFmt swizzle, Operand[] results, int rd)
- {
- switch (swizzle)
- {
- case OFmt.F16: return context.PackHalf2x16(results[0], results[1]);
- case OFmt.F32: return results[0];
- case OFmt.MrgH0:
- {
- Operand h1 = GetHalfDest(context, rd, isHigh: true);
- return context.PackHalf2x16(results[0], h1);
- }
- case OFmt.MrgH1:
- {
- Operand h0 = GetHalfDest(context, rd, isHigh: false);
- return context.PackHalf2x16(h0, results[1]);
- }
- }
- throw new ArgumentException($"Invalid swizzle \"{swizzle}\".");
- }
- public static Operand GetHalfDest(EmitterContext context, int rd, bool isHigh)
- {
- if (isHigh)
- {
- return context.UnpackHalf2x16High(GetDest(rd));
- }
- else
- {
- return context.UnpackHalf2x16Low(GetDest(rd));
- }
- }
- public static Operand GetPredicate(EmitterContext context, int pred, bool not)
- {
- Operand local = Register(pred, RegisterType.Predicate);
- if (not)
- {
- local = context.BitwiseNot(local);
- }
- return local;
- }
- public static void SetDest(EmitterContext context, Operand value, int rd, bool isFP64)
- {
- if (isFP64)
- {
- context.Copy(GetDest(rd), context.UnpackDouble2x32Low(value));
- context.Copy(GetDest2(rd), context.UnpackDouble2x32High(value));
- }
- else
- {
- context.Copy(GetDest(rd), value);
- }
- }
- public static int Imm16ToSInt(int imm16)
- {
- return (short)imm16;
- }
- public static int Imm20ToFloat(int imm20)
- {
- return imm20 << 12;
- }
- public static int Imm20ToSInt(int imm20)
- {
- return (imm20 << 12) >> 12;
- }
- public static int Imm24ToSInt(int imm24)
- {
- return (imm24 << 8) >> 8;
- }
- public static Operand SignExtendTo32(EmitterContext context, Operand src, int srcBits)
- {
- return context.BitfieldExtractS32(src, Const(0), Const(srcBits));
- }
- public static Operand ZeroExtendTo32(EmitterContext context, Operand src, int srcBits)
- {
- int mask = (int)(uint.MaxValue >> (32 - srcBits));
- return context.BitwiseAnd(src, Const(mask));
- }
- }
- }
|