Rewrite shader decoding stage (#2698)

* Rewrite shader decoding stage

* Fix P2R constant buffer encoding

* Fix PSET/PSETP

* PR feedback

* Log unimplemented shader instructions

* Implement NOP

* Remove using

* PR feedback
This commit is contained in:
gdkchan 2021-10-12 17:35:31 -03:00 committed by GitHub
parent 0510fde25a
commit a7109c767b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
168 changed files with 12022 additions and 6388 deletions

View file

@ -60,14 +60,14 @@ namespace Ryujinx.Graphics.Gpu.Shader
} }
/// <summary> /// <summary>
/// Reads data from GPU memory. /// Gets a span of the specified memory location, containing shader code.
/// </summary> /// </summary>
/// <typeparam name="T">Type of the data to be read</typeparam>
/// <param name="address">GPU virtual address of the data</param> /// <param name="address">GPU virtual address of the data</param>
/// <returns>Data at the memory location</returns> /// <param name="minimumSize">Minimum size that the returned span may have</param>
public override T MemoryRead<T>(ulong address) /// <returns>Span of the memory location</returns>
public override ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize)
{ {
return MemoryMarshal.Cast<byte, T>(_data.Span.Slice((int)address))[0]; return MemoryMarshal.Cast<byte, ulong>(_data.Span.Slice((int)address));
} }
/// <summary> /// <summary>

View file

@ -1,6 +1,8 @@
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader;
using System;
using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.Gpu.Shader namespace Ryujinx.Graphics.Gpu.Shader
{ {
@ -95,24 +97,15 @@ namespace Ryujinx.Graphics.Gpu.Shader
} }
/// <summary> /// <summary>
/// Reads data from GPU memory. /// Gets a span of the specified memory location, containing shader code.
/// </summary> /// </summary>
/// <typeparam name="T">Type of the data to be read</typeparam>
/// <param name="address">GPU virtual address of the data</param> /// <param name="address">GPU virtual address of the data</param>
/// <returns>Data at the memory location</returns> /// <param name="minimumSize">Minimum size that the returned span may have</param>
public override T MemoryRead<T>(ulong address) /// <returns>Span of the memory location</returns>
public override ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize)
{ {
return _channel.MemoryManager.Read<T>(address); int size = Math.Max(minimumSize, 0x1000 - (int)(address & 0xfff));
} return MemoryMarshal.Cast<byte, ulong>(_channel.MemoryManager.GetSpan(address, size));
/// <summary>
/// Checks if a given memory address is mapped.
/// </summary>
/// <param name="address">GPU virtual address to be checked</param>
/// <returns>True if the address is mapped, false otherwise</returns>
public bool MemoryMapped(ulong address)
{
return _channel.MemoryManager.IsMapped(address);
} }
/// <summary> /// <summary>

View file

@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <summary> /// <summary>
/// Version of the codegen (to be changed when codegen or guest format change). /// Version of the codegen (to be changed when codegen or guest format change).
/// </summary> /// </summary>
private const ulong ShaderCodeGenVersion = 2646; private const ulong ShaderCodeGenVersion = 2697;
// Progress reporting helpers // Progress reporting helpers
private volatile int _shaderCount; private volatile int _shaderCount;

View file

@ -1,6 +1,7 @@
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Gpu.Image;
using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader;
using System;
namespace Ryujinx.Graphics.Gpu.Shader namespace Ryujinx.Graphics.Gpu.Shader
{ {
@ -13,7 +14,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
_context = context; _context = context;
} }
public abstract T MemoryRead<T>(ulong address) where T : unmanaged; public abstract ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize);
public abstract ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot); public abstract ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot);

View file

@ -1,16 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum AtomicOp
{
Add = 0,
Minimum = 1,
Maximum = 2,
Increment = 3,
Decrement = 4,
BitwiseAnd = 5,
BitwiseOr = 6,
BitwiseExclusiveOr = 7,
Swap = 8,
SafeAdd = 10 // Only supported by ATOM.
}
}

View file

@ -1,10 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum BarrierLevel
{
Cta = 0,
Gl = 1,
Sys = 2,
Vc = 3
}
}

View file

@ -1,12 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum BarrierMode
{
ReductionPopCount = 2,
Scan = 3,
ReductionAnd = 0xa,
ReductionOr = 0x12,
Sync = 0x80,
Arrive = 0x81
}
}

View file

@ -11,15 +11,5 @@ namespace Ryujinx.Graphics.Shader.Decoders
{ {
return (value >> lsb) & (int)(uint.MaxValue >> (32 - length)); return (value >> lsb) & (int)(uint.MaxValue >> (32 - length));
} }
public static bool Extract(this long value, int lsb)
{
return ((int)(value >> lsb) & 1) != 0;
}
public static int Extract(this long value, int lsb, int length)
{
return (int)(value >> lsb) & (int)(uint.MaxValue >> (32 - length));
}
} }
} }

View file

@ -1,57 +1,56 @@
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace Ryujinx.Graphics.Shader.Decoders namespace Ryujinx.Graphics.Shader.Decoders
{ {
class PushOpInfo
{
public InstOp Op { get; }
public Dictionary<Block, Operand> Consumers;
public PushOpInfo(InstOp op)
{
Op = op;
Consumers = new Dictionary<Block, Operand>();
}
}
struct SyncTarget
{
public PushOpInfo PushOpInfo { get; }
public int PushOpId { get; }
public SyncTarget(PushOpInfo pushOpInfo, int pushOpId)
{
PushOpInfo = pushOpInfo;
PushOpId = pushOpId;
}
}
class Block class Block
{ {
public ulong Address { get; set; } public ulong Address { get; set; }
public ulong EndAddress { get; set; } public ulong EndAddress { get; set; }
private Block _next; public List<Block> Predecessors { get; }
private Block _branch; public List<Block> Successors { get; }
public Block Next public List<InstOp> OpCodes { get; }
{ public List<PushOpInfo> PushOpCodes { get; }
get public Dictionary<ulong, SyncTarget> SyncTargets { get; }
{
return _next;
}
set
{
_next?.Predecessors.Remove(this);
value?.Predecessors.Add(this);
_next = value;
}
}
public Block Branch
{
get
{
return _branch;
}
set
{
_branch?.Predecessors.Remove(this);
value?.Predecessors.Add(this);
_branch = value;
}
}
public HashSet<Block> Predecessors { get; }
public List<OpCode> OpCodes { get; }
public List<OpCodePush> PushOpCodes { get; }
public Block(ulong address) public Block(ulong address)
{ {
Address = address; Address = address;
Predecessors = new HashSet<Block>(); Predecessors = new List<Block>();
Successors = new List<Block>();
OpCodes = new List<OpCode>(); OpCodes = new List<InstOp>();
PushOpCodes = new List<OpCodePush>(); PushOpCodes = new List<PushOpInfo>();
SyncTargets = new Dictionary<ulong, SyncTarget>();
} }
public void Split(Block rightBlock) public void Split(Block rightBlock)
@ -64,36 +63,56 @@ namespace Ryujinx.Graphics.Shader.Decoders
} }
int splitCount = OpCodes.Count - splitIndex; int splitCount = OpCodes.Count - splitIndex;
if (splitCount <= 0) if (splitCount <= 0)
{ {
throw new ArgumentException("Can't split at right block address."); throw new ArgumentException("Can't split at right block address.");
} }
rightBlock.EndAddress = EndAddress; rightBlock.EndAddress = EndAddress;
rightBlock.Successors.AddRange(Successors);
rightBlock.Next = Next; rightBlock.Predecessors.Add(this);
rightBlock.Branch = Branch;
rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount));
rightBlock.UpdatePushOps();
EndAddress = rightBlock.Address; EndAddress = rightBlock.Address;
Next = rightBlock; Successors.Clear();
Branch = null; Successors.Add(rightBlock);
// Move ops.
rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount));
OpCodes.RemoveRange(splitIndex, splitCount); OpCodes.RemoveRange(splitIndex, splitCount);
UpdatePushOps(); // Update push consumers that points to this block.
foreach (SyncTarget syncTarget in SyncTargets.Values)
{
PushOpInfo pushOpInfo = syncTarget.PushOpInfo;
Operand local = pushOpInfo.Consumers[this];
pushOpInfo.Consumers.Remove(this);
pushOpInfo.Consumers.Add(rightBlock, local);
}
rightBlock.SyncTargets.Union(SyncTargets);
SyncTargets.Clear();
// Move push ops.
for (int i = 0; i < PushOpCodes.Count; i++)
{
if (PushOpCodes[i].Op.Address >= rightBlock.Address)
{
int count = PushOpCodes.Count - i;
rightBlock.PushOpCodes.AddRange(PushOpCodes.Skip(i));
PushOpCodes.RemoveRange(i, count);
break;
}
}
} }
private static int BinarySearch(List<OpCode> opCodes, ulong address) private static int BinarySearch(List<InstOp> opCodes, ulong address)
{ {
int left = 0; int left = 0;
int middle = 0; int middle = 0;
int right = opCodes.Count - 1; int right = opCodes.Count - 1;
while (left <= right) while (left <= right)
{ {
@ -101,7 +120,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
middle = left + (size >> 1); middle = left + (size >> 1);
OpCode opCode = opCodes[middle]; InstOp opCode = opCodes[middle];
if (address == opCode.Address) if (address == opCode.Address)
{ {
@ -121,29 +140,25 @@ namespace Ryujinx.Graphics.Shader.Decoders
return middle; return middle;
} }
public OpCode GetLastOp() public InstOp GetLastOp()
{ {
if (OpCodes.Count != 0) if (OpCodes.Count != 0)
{ {
return OpCodes[OpCodes.Count - 1]; return OpCodes[OpCodes.Count - 1];
} }
return null; return default;
} }
public void UpdatePushOps() public bool HasNext()
{ {
PushOpCodes.Clear(); InstOp lastOp = GetLastOp();
return OpCodes.Count != 0 && !Decoder.IsUnconditionalBranch(ref lastOp);
}
for (int index = 0; index < OpCodes.Count; index++) public void AddPushOp(InstOp op)
{ {
if (!(OpCodes[index] is OpCodePush op)) PushOpCodes.Add(new PushOpInfo(op));
{
continue;
}
PushOpCodes.Add(op);
}
} }
} }
} }

View file

@ -1,10 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum CbIndexMode
{
Default = 0,
Il = 1,
Is = 2,
Isl = 3
}
}

View file

@ -1,45 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum Condition
{
Less = 1 << 0,
Equal = 1 << 1,
Greater = 1 << 2,
Nan = 1 << 3,
Unsigned = 1 << 4,
Never = 0,
LessOrEqual = Less | Equal,
NotEqual = Less | Greater,
GreaterOrEqual = Greater | Equal,
Number = Greater | Equal | Less,
LessUnordered = Less | Nan,
EqualUnordered = Equal | Nan,
LessOrEqualUnordered = LessOrEqual | Nan,
GreaterUnordered = Greater | Nan,
NotEqualUnordered = NotEqual | Nan,
GreaterOrEqualUnordered = GreaterOrEqual | Nan,
Always = 0xf,
Off = Unsigned | Never,
Lower = Unsigned | Less,
Sff = Unsigned | Equal,
LowerOrSame = Unsigned | LessOrEqual,
Higher = Unsigned | Greater,
Sft = Unsigned | NotEqual,
HigherOrSame = Unsigned | GreaterOrEqual,
Oft = Unsigned | Always,
CsmTa = 0x18,
CsmTr = 0x19,
CsmMx = 0x1a,
FcsmTa = 0x1b,
FcsmTr = 0x1c,
FcsmMx = 0x1d,
Rle = 0x1e,
Rgt = 0x1f
}
}

View file

@ -1,10 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum ConditionalOperation
{
False = 0,
True = 1,
Zero = 2,
NotZero = 3
}
}

View file

@ -1,8 +1,8 @@
using Ryujinx.Graphics.Shader.Instructions;
using Ryujinx.Graphics.Shader.Translation; using Ryujinx.Graphics.Shader.Translation;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices;
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
@ -95,32 +95,33 @@ namespace Ryujinx.Graphics.Shader.Decoders
{ {
// We should have blocks for all possible branch targets, // We should have blocks for all possible branch targets,
// including those from SSY/PBK instructions. // including those from SSY/PBK instructions.
foreach (OpCodePush pushOp in currBlock.PushOpCodes) foreach (PushOpInfo pushOp in currBlock.PushOpCodes)
{ {
GetBlock(pushOp.GetAbsoluteAddress()); GetBlock(pushOp.Op.GetAbsoluteAddress());
} }
// Set child blocks. "Branch" is the block the branch instruction // Set child blocks. "Branch" is the block the branch instruction
// points to (when taken), "Next" is the block at the next address, // points to (when taken), "Next" is the block at the next address,
// executed when the branch is not taken. For Unconditional Branches // executed when the branch is not taken. For Unconditional Branches
// or end of program, Next is null. // or end of program, Next is null.
OpCode lastOp = currBlock.GetLastOp(); InstOp lastOp = currBlock.GetLastOp();
if (lastOp is OpCodeBranch opBr) if (lastOp.Name == InstName.Cal)
{ {
if (lastOp.Emitter == InstEmit.Cal) EnqueueFunction(lastOp.GetAbsoluteAddress());
{ }
EnqueueFunction(opBr.GetAbsoluteAddress()); else if (lastOp.Name == InstName.Bra)
} {
else Block succBlock = GetBlock(lastOp.GetAbsoluteAddress());
{ currBlock.Successors.Add(succBlock);
currBlock.Branch = GetBlock(opBr.GetAbsoluteAddress()); succBlock.Predecessors.Add(currBlock);
}
} }
if (!IsUnconditionalBranch(lastOp)) if (!IsUnconditionalBranch(ref lastOp))
{ {
currBlock.Next = GetBlock(currBlock.EndAddress); Block succBlock = GetBlock(currBlock.EndAddress);
currBlock.Successors.Insert(0, succBlock);
succBlock.Predecessors.Add(currBlock);
} }
} }
@ -146,33 +147,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
} }
} }
// Try to find target for BRX (indirect branch) instructions. // Try to find targets for BRX (indirect branch) instructions.
hasNewTarget = false; hasNewTarget = FindBrxTargets(config, blocks, GetBlock);
foreach (Block block in blocks)
{
if (block.GetLastOp() is OpCodeBranchIndir opBrIndir && opBrIndir.PossibleTargets.Count == 0)
{
ulong baseOffset = opBrIndir.Address + 8 + (ulong)opBrIndir.Offset;
// An indirect branch could go anywhere,
// try to get the possible target offsets from the constant buffer.
(int cbBaseOffset, int cbOffsetsCount) = FindBrxTargetRange(block, opBrIndir.Ra.Index);
if (cbOffsetsCount != 0)
{
hasNewTarget = true;
}
for (int i = 0; i < cbOffsetsCount; i++)
{
uint targetOffset = config.GpuAccessor.ConstantBuffer1Read(cbBaseOffset + i * 4);
Block target = GetBlock(baseOffset + targetOffset);
opBrIndir.PossibleTargets.Add(target);
target.Predecessors.Add(block);
}
}
}
// If we discovered new branch targets from the BRX instruction, // If we discovered new branch targets from the BRX instruction,
// we need another round of decoding to decode the new blocks. // we need another round of decoding to decode the new blocks.
@ -227,6 +203,10 @@ namespace Ryujinx.Graphics.Shader.Decoders
IGpuAccessor gpuAccessor = config.GpuAccessor; IGpuAccessor gpuAccessor = config.GpuAccessor;
ulong address = block.Address; ulong address = block.Address;
int bufferOffset = 0;
ReadOnlySpan<ulong> buffer = ReadOnlySpan<ulong>.Empty;
InstOp op = default;
do do
{ {
@ -239,66 +219,75 @@ namespace Ryujinx.Graphics.Shader.Decoders
if ((address & 0x1f) == 0) if ((address & 0x1f) == 0)
{ {
address += 8; address += 8;
bufferOffset++;
continue; continue;
} }
ulong opAddress = address; if (bufferOffset >= buffer.Length)
address += 8;
long opCode = gpuAccessor.MemoryRead<long>(startAddress + opAddress);
(InstEmitter emitter, OpCodeTable.MakeOp makeOp) = OpCodeTable.GetEmitter(opCode);
if (emitter == null)
{ {
// TODO: Warning, illegal encoding. buffer = gpuAccessor.GetCode(startAddress + address, 8);
bufferOffset = 0;
block.OpCodes.Add(new OpCode(null, opAddress, opCode));
continue;
} }
if (makeOp == null) ulong opCode = buffer[bufferOffset++];
{
throw new ArgumentNullException(nameof(makeOp));
}
OpCode op = makeOp(emitter, opAddress, opCode); op = InstTable.GetOp(address, opCode);
// We check these patterns to figure out the presence of bindless access if (op.Props.HasFlag(InstProps.TexB))
if ((op is OpCodeImage image && image.IsBindless) ||
(op is OpCodeTxd txd && txd.IsBindless) ||
(op is OpCodeTld4B) ||
(emitter == InstEmit.TexB) ||
(emitter == InstEmit.TldB) ||
(emitter == InstEmit.TmmlB) ||
(emitter == InstEmit.TxqB))
{ {
config.SetUsedFeature(FeatureFlags.Bindless); config.SetUsedFeature(FeatureFlags.Bindless);
} }
// Populate used attributes. if (op.Name == InstName.Ald || op.Name == InstName.Ast || op.Name == InstName.Ipa)
if (op is IOpCodeAttribute opAttr)
{ {
SetUserAttributeUses(config, opAttr); SetUserAttributeUses(config, op.Name, opCode);
}
else if (op.Name == InstName.Ssy || op.Name == InstName.Pbk)
{
block.AddPushOp(op);
} }
block.OpCodes.Add(op); block.OpCodes.Add(op);
address += 8;
} }
while (!IsControlFlowChange(block.GetLastOp())); while (!op.Props.HasFlag(InstProps.Bra));
block.EndAddress = address; block.EndAddress = address;
block.UpdatePushOps();
} }
private static void SetUserAttributeUses(ShaderConfig config, IOpCodeAttribute opAttr) private static void SetUserAttributeUses(ShaderConfig config, InstName name, ulong opCode)
{ {
if (opAttr.Indexed) int offset;
int count = 1;
bool isStore = false;
bool indexed = false;
if (name == InstName.Ast)
{ {
if (opAttr.Emitter == InstEmit.Ast) InstAst opAst = new InstAst(opCode);
count = (int)opAst.AlSize + 1;
offset = opAst.Imm11;
indexed = opAst.Phys;
isStore = true;
}
else if (name == InstName.Ald)
{
InstAld opAld = new InstAld(opCode);
count = (int)opAld.AlSize + 1;
indexed = opAld.Phys;
offset = opAld.Imm11;
}
else /* if (name == InstName.Ipa) */
{
InstIpa opIpa = new InstIpa(opCode);
offset = opIpa.Imm10;
indexed = opIpa.Idx;
}
if (indexed)
{
if (isStore)
{ {
config.SetAllOutputUserAttributes(); config.SetAllOutputUserAttributes();
} }
@ -309,14 +298,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
} }
else else
{ {
for (int elemIndex = 0; elemIndex < opAttr.Count; elemIndex++) for (int elemIndex = 0; elemIndex < count; elemIndex++)
{ {
int attr = opAttr.AttributeOffset + elemIndex * 4; int attr = offset + elemIndex * 4;
if (attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd) if (attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd)
{ {
int index = (attr - AttributeConsts.UserAttributeBase) / 16; int index = (attr - AttributeConsts.UserAttributeBase) / 16;
if (opAttr.Emitter == InstEmit.Ast) if (isStore)
{ {
config.SetOutputUserAttribute(index); config.SetOutputUserAttribute(index);
} }
@ -329,27 +318,57 @@ namespace Ryujinx.Graphics.Shader.Decoders
} }
} }
private static bool IsUnconditionalBranch(OpCode opCode) public static bool IsUnconditionalBranch(ref InstOp op)
{ {
return IsUnconditional(opCode) && IsControlFlowChange(opCode); return IsUnconditional(ref op) && op.Props.HasFlag(InstProps.Bra);
} }
private static bool IsUnconditional(OpCode opCode) private static bool IsUnconditional(ref InstOp op)
{ {
if (opCode is OpCodeExit op && op.Condition != Condition.Always) InstConditional condOp = new InstConditional(op.RawOpCode);
if (op.Name == InstName.Exit && condOp.Ccc != Ccc.T)
{ {
return false; return false;
} }
return opCode.Predicate.Index == RegisterConsts.PredicateTrueIndex && !opCode.InvertPredicate; return condOp.Pred == RegisterConsts.PredicateTrueIndex && !condOp.PredInv;
} }
private static bool IsControlFlowChange(OpCode opCode) private static bool FindBrxTargets(ShaderConfig config, IEnumerable<Block> blocks, Func<ulong, Block> getBlock)
{ {
return (opCode is OpCodeBranch opBranch && !opBranch.PushTarget) || bool hasNewTarget = false;
opCode is OpCodeBranchIndir ||
opCode is OpCodeBranchPop || foreach (Block block in blocks)
opCode is OpCodeExit; {
InstOp lastOp = block.GetLastOp();
bool hasNext = block.HasNext();
if (lastOp.Name == InstName.Brx && block.Successors.Count == (hasNext ? 1 : 0))
{
InstBrx opBrx = new InstBrx(lastOp.RawOpCode);
ulong baseOffset = lastOp.GetAbsoluteAddress();
// An indirect branch could go anywhere,
// try to get the possible target offsets from the constant buffer.
(int cbBaseOffset, int cbOffsetsCount) = FindBrxTargetRange(block, opBrx.SrcA);
if (cbOffsetsCount != 0)
{
hasNewTarget = true;
}
for (int i = 0; i < cbOffsetsCount; i++)
{
uint targetOffset = config.GpuAccessor.ConstantBuffer1Read(cbBaseOffset + i * 4);
Block target = getBlock(baseOffset + targetOffset);
target.Predecessors.Add(block);
block.Successors.Add(target);
}
}
}
return hasNewTarget;
} }
private static (int, int) FindBrxTargetRange(Block block, int brxReg) private static (int, int) FindBrxTargetRange(Block block, int brxReg)
@ -369,41 +388,51 @@ namespace Ryujinx.Graphics.Shader.Decoders
HashSet<Block> visited = new HashSet<Block>(); HashSet<Block> visited = new HashSet<Block>();
var ldcLocation = FindFirstRegWrite(visited, new BlockLocation(block, block.OpCodes.Count - 1), brxReg); var ldcLocation = FindFirstRegWrite(visited, new BlockLocation(block, block.OpCodes.Count - 1), brxReg);
if (ldcLocation.Block == null || ldcLocation.Block.OpCodes[ldcLocation.Index] is not OpCodeLdc opLdc) if (ldcLocation.Block == null || ldcLocation.Block.OpCodes[ldcLocation.Index].Name != InstName.Ldc)
{ {
return (0, 0); return (0, 0);
} }
if (opLdc.Slot != 1 || opLdc.IndexMode != CbIndexMode.Default) GetOp<InstLdc>(ldcLocation, out var opLdc);
if (opLdc.CbufSlot != 1 || opLdc.AddressMode != 0)
{ {
return (0, 0); return (0, 0);
} }
var shlLocation = FindFirstRegWrite(visited, ldcLocation, opLdc.Ra.Index); var shlLocation = FindFirstRegWrite(visited, ldcLocation, opLdc.SrcA);
if (shlLocation.Block == null || shlLocation.Block.OpCodes[shlLocation.Index] is not OpCodeAluImm opShl) if (shlLocation.Block == null || !shlLocation.IsImmInst(InstName.Shl))
{ {
return (0, 0); return (0, 0);
} }
if (opShl.Emitter != InstEmit.Shl || opShl.Immediate != 2) GetOp<InstShlI>(shlLocation, out var opShl);
if (opShl.Imm20 != 2)
{ {
return (0, 0); return (0, 0);
} }
var imnmxLocation = FindFirstRegWrite(visited, shlLocation, opShl.Ra.Index); var imnmxLocation = FindFirstRegWrite(visited, shlLocation, opShl.SrcA);
if (imnmxLocation.Block == null || imnmxLocation.Block.OpCodes[imnmxLocation.Index] is not OpCodeAluImm opImnmx) if (imnmxLocation.Block == null || !imnmxLocation.IsImmInst(InstName.Imnmx))
{ {
return (0, 0); return (0, 0);
} }
bool isImnmxS32 = opImnmx.RawOpCode.Extract(48); GetOp<InstImnmxI>(imnmxLocation, out var opImnmx);
if (opImnmx.Emitter != InstEmit.Imnmx || isImnmxS32 || !opImnmx.Predicate39.IsPT || opImnmx.InvertP) if (opImnmx.Signed || opImnmx.SrcPred != RegisterConsts.PredicateTrueIndex || opImnmx.SrcPredInv)
{ {
return (0, 0); return (0, 0);
} }
return (opLdc.Offset, opImnmx.Immediate + 1); return (opLdc.CbufOffset, opImnmx.Imm20 + 1);
}
private static void GetOp<T>(BlockLocation location, out T op) where T : unmanaged
{
ulong rawOp = location.Block.OpCodes[location.Index].RawOpCode;
op = Unsafe.As<ulong, T>(ref rawOp);
} }
private struct BlockLocation private struct BlockLocation
@ -416,6 +445,12 @@ namespace Ryujinx.Graphics.Shader.Decoders
Block = block; Block = block;
Index = index; Index = index;
} }
public bool IsImmInst(InstName name)
{
InstOp op = Block.OpCodes[Index];
return op.Name == name && op.Props.HasFlag(InstProps.Ib);
}
} }
private static BlockLocation FindFirstRegWrite(HashSet<Block> visited, BlockLocation location, int regIndex) private static BlockLocation FindFirstRegWrite(HashSet<Block> visited, BlockLocation location, int regIndex)
@ -447,18 +482,20 @@ namespace Ryujinx.Graphics.Shader.Decoders
return new BlockLocation(null, 0); return new BlockLocation(null, 0);
} }
private static bool WritesToRegister(OpCode opCode, int regIndex) private static bool WritesToRegister(InstOp op, int regIndex)
{ {
// Predicate instruction only ever writes to predicate, so we shouldn't check those. // Predicate instruction only ever writes to predicate, so we shouldn't check those.
if (opCode.Emitter == InstEmit.Fsetp || if ((op.Props & (InstProps.Rd | InstProps.Rd2)) == 0)
opCode.Emitter == InstEmit.Hsetp2 ||
opCode.Emitter == InstEmit.Isetp ||
opCode.Emitter == InstEmit.R2p)
{ {
return false; return false;
} }
return opCode is IOpCodeRd opRd && opRd.Rd.Index == regIndex; if (op.Props.HasFlag(InstProps.Rd2) && (byte)(op.RawOpCode >> 28) == regIndex)
{
return true;
}
return (byte)op.RawOpCode == regIndex;
} }
private enum MergeType private enum MergeType
@ -527,14 +564,13 @@ namespace Ryujinx.Graphics.Shader.Decoders
private static void PropagatePushOp(Dictionary<ulong, Block> blocks, Block currBlock, int pushOpIndex) private static void PropagatePushOp(Dictionary<ulong, Block> blocks, Block currBlock, int pushOpIndex)
{ {
OpCodePush pushOp = currBlock.PushOpCodes[pushOpIndex]; PushOpInfo pushOpInfo = currBlock.PushOpCodes[pushOpIndex];
InstOp pushOp = pushOpInfo.Op;
Block target = blocks[pushOp.GetAbsoluteAddress()]; Block target = blocks[pushOp.GetAbsoluteAddress()];
Stack<PathBlockState> workQueue = new Stack<PathBlockState>(); Stack<PathBlockState> workQueue = new Stack<PathBlockState>();
HashSet<Block> visited = new HashSet<Block>(); HashSet<Block> visited = new HashSet<Block>();
Stack<(ulong, MergeType)> branchStack = new Stack<(ulong, MergeType)>(); Stack<(ulong, MergeType)> branchStack = new Stack<(ulong, MergeType)>();
void Push(PathBlockState pbs) void Push(PathBlockState pbs)
@ -574,42 +610,30 @@ namespace Ryujinx.Graphics.Shader.Decoders
} }
int pushOpsCount = current.PushOpCodes.Count; int pushOpsCount = current.PushOpCodes.Count;
if (pushOpsCount != 0) if (pushOpsCount != 0)
{ {
Push(new PathBlockState(branchStack.Count)); Push(new PathBlockState(branchStack.Count));
for (int index = pushOpIndex; index < pushOpsCount; index++) for (int index = pushOpIndex; index < pushOpsCount; index++)
{ {
OpCodePush currentPushOp = current.PushOpCodes[index]; InstOp currentPushOp = current.PushOpCodes[index].Op;
MergeType pushMergeType = currentPushOp.Emitter == InstEmit.Ssy ? MergeType.Sync : MergeType.Brk; MergeType pushMergeType = currentPushOp.Name == InstName.Ssy ? MergeType.Sync : MergeType.Brk;
branchStack.Push((currentPushOp.GetAbsoluteAddress(), pushMergeType)); branchStack.Push((currentPushOp.GetAbsoluteAddress(), pushMergeType));
} }
} }
pushOpIndex = 0; pushOpIndex = 0;
if (current.Next != null) bool hasNext = current.HasNext();
if (hasNext)
{ {
Push(new PathBlockState(current.Next)); Push(new PathBlockState(current.Successors[0]));
} }
if (current.Branch != null) InstOp lastOp = current.GetLastOp();
if (lastOp.Name == InstName.Sync || lastOp.Name == InstName.Brk)
{ {
Push(new PathBlockState(current.Branch)); MergeType popMergeType = lastOp.Name == InstName.Sync ? MergeType.Sync : MergeType.Brk;
}
else if (current.GetLastOp() is OpCodeBranchIndir brIndir)
{
// By adding them in descending order (sorted by address), we process the blocks
// in order (of ascending address), since we work with a LIFO.
foreach (Block possibleTarget in brIndir.PossibleTargets.OrderByDescending(x => x.Address))
{
Push(new PathBlockState(possibleTarget));
}
}
else if (current.GetLastOp() is OpCodeBranchPop op)
{
MergeType popMergeType = op.Emitter == InstEmit.Sync ? MergeType.Sync : MergeType.Brk;
bool found = true; bool found = true;
ulong targetAddress = 0UL; ulong targetAddress = 0UL;
@ -641,20 +665,32 @@ namespace Ryujinx.Graphics.Shader.Decoders
{ {
// If the entire stack was consumed, then the current pop instruction // If the entire stack was consumed, then the current pop instruction
// just consumed the address from our push instruction. // just consumed the address from our push instruction.
if (op.Targets.TryAdd(pushOp, op.Targets.Count)) if (current.SyncTargets.TryAdd(pushOp.Address, new SyncTarget(pushOpInfo, current.SyncTargets.Count)))
{ {
pushOp.PopOps.Add(op, Local()); pushOpInfo.Consumers.Add(current, Local());
target.Predecessors.Add(current); target.Predecessors.Add(current);
current.Successors.Add(target);
} }
} }
else else
{ {
// Push the block itself into the work "queue" (well, it's a stack) // Push the block itself into the work queue for processing.
// for processing.
Push(new PathBlockState(blocks[targetAddress])); Push(new PathBlockState(blocks[targetAddress]));
} }
} }
} }
else
{
// By adding them in descending order (sorted by address), we process the blocks
// in order (of ascending address), since we work with a LIFO.
foreach (Block possibleTarget in current.Successors.OrderByDescending(x => x.Address))
{
if (!hasNext || possibleTarget != current.Successors[0])
{
Push(new PathBlockState(possibleTarget));
}
}
}
} }
} }
} }

View file

@ -1,74 +0,0 @@
using System;
namespace Ryujinx.Graphics.Shader.Decoders
{
static class DecoderHelper
{
public static int DecodeS20Immediate(long opCode)
{
int imm = opCode.Extract(20, 19);
bool sign = opCode.Extract(56);
if (sign)
{
imm = (imm << 13) >> 13;
}
return imm;
}
public static int Decode2xF10Immediate(long opCode)
{
int immH0 = opCode.Extract(20, 9);
int immH1 = opCode.Extract(30, 9);
bool negateH0 = opCode.Extract(29);
bool negateH1 = opCode.Extract(56);
if (negateH0)
{
immH0 |= 1 << 9;
}
if (negateH1)
{
immH1 |= 1 << 9;
}
return immH1 << 22 | immH0 << 6;
}
public static float DecodeF20Immediate(long opCode)
{
int imm = opCode.Extract(20, 19);
bool negate = opCode.Extract(56);
imm <<= 12;
if (negate)
{
imm |= 1 << 31;
}
return BitConverter.Int32BitsToSingle(imm);
}
public static float DecodeD20Immediate(long opCode)
{
long imm = opCode.Extract(20, 19);
bool negate = opCode.Extract(56);
imm <<= 44;
if (negate)
{
imm |= 1L << 63;
}
return (float)BitConverter.Int64BitsToDouble(imm);
}
}
}

View file

@ -1,10 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum FPHalfSwizzle
{
FP16 = 0,
FP32 = 1,
DupH0 = 2,
DupH1 = 3
}
}

View file

@ -1,13 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum FPMultiplyScale
{
None = 0,
Divide2 = 1,
Divide4 = 2,
Divide8 = 3,
Multiply8 = 4,
Multiply4 = 5,
Multiply2 = 6
}
}

View file

@ -1,19 +0,0 @@
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
namespace Ryujinx.Graphics.Shader.Decoders
{
enum FPType
{
FP16 = 1,
FP32 = 2,
FP64 = 3
}
static class FPTypeExtensions
{
public static Instruction ToInstFPType(this FPType type)
{
return type == FPType.FP64 ? Instruction.FP64 : Instruction.FP32;
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCode
{
InstEmitter Emitter { get; }
ulong Address { get; }
long RawOpCode { get; }
Register Predicate { get; }
bool InvertPredicate { get; }
}
}

View file

@ -1,9 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeAlu : IOpCodeRd, IOpCodeRa, IOpCodePredicate39
{
bool Extended { get; }
bool SetCondCode { get; }
bool Saturate { get; }
}
}

View file

@ -1,9 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeAttribute : IOpCode
{
int AttributeOffset { get; }
int Count { get; }
bool Indexed { get; }
}
}

View file

@ -1,8 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeCbuf : IOpCode
{
int Offset { get; }
int Slot { get; }
}
}

View file

@ -1,12 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeFArith : IOpCodeAlu
{
RoundingMode RoundingMode { get; }
FPMultiplyScale Scale { get; }
bool FlushToZero { get; }
bool AbsoluteA { get; }
}
}

View file

@ -1,13 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeHfma : IOpCode
{
bool NegateB { get; }
bool NegateC { get; }
bool Saturate { get; }
FPHalfSwizzle SwizzleA { get; }
FPHalfSwizzle SwizzleB { get; }
FPHalfSwizzle SwizzleC { get; }
}
}

View file

@ -1,7 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeImm : IOpCode
{
int Immediate { get; }
}
}

View file

@ -1,7 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeImmF : IOpCode
{
float Immediate { get; }
}
}

View file

@ -1,10 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeLop : IOpCodeAlu
{
LogicalOperation LogicalOp { get; }
bool InvertA { get; }
bool InvertB { get; }
}
}

View file

@ -1,9 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodePredicate39
{
Register Predicate39 { get; }
bool InvertP { get; }
}
}

View file

@ -1,7 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeRa : IOpCode
{
Register Ra { get; }
}
}

View file

@ -1,7 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeRc : IOpCode
{
Register Rc { get; }
}
}

View file

@ -1,7 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeRd : IOpCode
{
Register Rd { get; }
}
}

View file

@ -1,7 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeReg : IOpCode
{
Register Rb { get; }
}
}

View file

@ -1,8 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeRegCbuf : IOpCodeRc
{
int Offset { get; }
int Slot { get; }
}
}

View file

@ -1,23 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeTexture : IOpCode
{
Register Rd { get; }
Register Ra { get; }
Register Rb { get; }
bool IsArray { get; }
TextureDimensions Dimensions { get; }
int ComponentMask { get; }
int HandleOffset { get; }
TextureLodMode LodMode { get; }
bool HasOffset { get; }
bool HasDepthCompare { get; }
bool IsMultisample { get; }
}
}

View file

@ -1,11 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
interface IOpCodeTld4 : IOpCodeTexture
{
TextureGatherOffset Offset { get; }
int GatherCompIndex { get; }
bool Bindless { get; }
}
}

View file

@ -1,10 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum ImageComponents
{
Red = 1 << 0,
Green = 1 << 1,
Blue = 1 << 2,
Alpha = 1 << 3
}
}

View file

@ -1,12 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum ImageDimensions
{
Image1D,
ImageBuffer,
Image1DArray,
Image2D,
Image2DArray,
Image3D
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,188 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum InstName : byte
{
Invalid = 0,
Al2p,
Ald,
Ast,
Atom,
AtomCas,
Atoms,
AtomsCas,
B2r,
Bar,
Bfe,
Bfi,
Bpt,
Bra,
Brk,
Brx,
Cal,
Cctl,
Cctll,
Cctlt,
Cont,
Cset,
Csetp,
Cs2r,
Dadd,
Depbar,
Dfma,
Dmnmx,
Dmul,
Dset,
Dsetp,
Exit,
F2f,
F2i,
Fadd,
Fadd32i,
Fchk,
Fcmp,
Ffma,
Ffma32i,
Flo,
Fmnmx,
Fmul,
Fmul32i,
Fset,
Fsetp,
Fswzadd,
Getcrsptr,
Getlmembase,
Hadd2,
Hadd232i,
Hfma2,
Hmul2,
Hmul232i,
Hset2,
Hsetp2,
I2f,
I2i,
Iadd,
Iadd32i,
Iadd3,
Icmp,
Ide,
Idp,
Imad,
Imad32i,
Imadsp,
Imnmx,
Imul,
Imul32i,
Ipa,
Isberd,
Iscadd,
Iscadd32i,
Iset,
Isetp,
Jcal,
Jmp,
Jmx,
Kil,
Ld,
Ldc,
Ldg,
Ldl,
Lds,
Lea,
LeaHi,
Lepc,
Longjmp,
Lop,
Lop3,
Lop32i,
Membar,
Mov,
Mov32i,
Mufu,
Nop,
Out,
P2r,
Pbk,
Pcnt,
Pexit,
Pixld,
Plongjmp,
Popc,
Pret,
Prmt,
Pset,
Psetp,
R2b,
R2p,
Ram,
Red,
Ret,
Rro,
Rtt,
S2r,
Sam,
Sel,
Setcrsptr,
Setlmembase,
Shf,
Shf_2,
Shf_3,
Shf_4,
Shfl,
Shl,
Shr,
Ssy,
St,
Stg,
Stl,
Stp,
Sts,
SuatomB,
Suatom,
SuatomB2,
SuatomCasB,
SuatomCas,
SuldDB,
SuldD,
SuldB,
Suld,
SuredB,
Sured,
SustDB,
SustD,
SustB,
Sust,
Sync,
Tex,
TexB,
Texs,
TexsF16,
Tld,
TldB,
Tlds,
TldsF16,
Tld4,
Tld4B,
Tld4s,
Tld4sF16,
Tmml,
TmmlB,
Txa,
Txd,
TxdB,
Txq,
TxqB,
Vabsdiff,
Vabsdiff4,
Vadd,
Vmad,
Vmnmx,
Vote,
Votevtg,
Vset,
Vsetp,
Vshl,
Vshr,
Xmad,
}
}

View file

@ -0,0 +1,27 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
readonly struct InstOp
{
public readonly ulong Address;
public readonly ulong RawOpCode;
public readonly InstEmitter Emitter;
public readonly InstProps Props;
public readonly InstName Name;
public InstOp(ulong address, ulong rawOpCode, InstName name, InstEmitter emitter, InstProps props)
{
Address = address;
RawOpCode = rawOpCode;
Name = name;
Emitter = emitter;
Props = props;
}
public ulong GetAbsoluteAddress()
{
return (ulong)((long)Address + (((int)(RawOpCode >> 20) << 8) >> 8) + 8);
}
}
}

View file

@ -0,0 +1,20 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum InstProps : ushort
{
None = 0,
Rd = 1 << 0,
Rd2 = 1 << 1,
Ra = 1 << 2,
Rb = 1 << 3,
Ib = 1 << 4,
Rc = 1 << 5,
Pd = 1 << 6,
Pd2 = 1 << 7,
Pdn = 1 << 8,
Tex = 1 << 9,
TexB = 1 << 10,
Bra = 1 << 11,
NoPred = 1 << 12
}
}

View file

@ -0,0 +1,388 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
static class InstTable
{
private const int EncodingBits = 14;
private struct TableEntry
{
public InstName Name { get; }
public InstEmitter Emitter { get; }
public InstProps Props { get; }
public int XBits { get; }
public TableEntry(InstName name, InstEmitter emitter, InstProps props, int xBits)
{
Name = name;
Emitter = emitter;
Props = props;
XBits = xBits;
}
}
private static TableEntry[] _opCodes;
static InstTable()
{
_opCodes = new TableEntry[1 << EncodingBits];
#region Instructions
Add("1110111110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Al2p, InstEmit.Al2p, InstProps.Rd | InstProps.Ra);
Add("1110111111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ald, InstEmit.Ald, InstProps.Rd | InstProps.Ra);
Add("1110111111110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ast, InstEmit.Ast, InstProps.Ra | InstProps.Rc);
Add("11101101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Atom, InstEmit.Atom, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("111011101111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.AtomCas, InstEmit.AtomCas, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("11101100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Atoms, InstEmit.Atoms, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("111011100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.AtomsCas, InstEmit.AtomsCas, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("1111000010111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.B2r, InstEmit.B2r, InstProps.Rd | InstProps.Ra);
Add("1111000010101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bar, InstEmit.Bar, InstProps.Ra);
Add("0101110000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfe, InstEmit.BfeR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x00000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfe, InstEmit.BfeI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfe, InstEmit.BfeC, InstProps.Rd | InstProps.Ra);
Add("0101101111110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfi, InstEmit.BfiR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0011011x11110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfi, InstEmit.BfiI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("0100101111110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfi, InstEmit.BfiC, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("0101001111110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfi, InstEmit.BfiRc, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("111000111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bpt, InstEmit.Bpt, InstProps.NoPred);
Add("111000100100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bra, InstEmit.Bra, InstProps.Bra);
Add("111000110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Brk, InstEmit.Brk, InstProps.Bra);
Add("111000100101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Brx, InstEmit.Brx, InstProps.Ra | InstProps.Bra);
Add("111000100110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cal, InstEmit.Cal, InstProps.Bra | InstProps.NoPred);
Add("11101111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cctl, InstEmit.Cctl, InstProps.Ra);
Add("1110111110000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cctll, InstEmit.Cctll, InstProps.Ra);
Add("1110101111110xx0000000000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cctlt, InstEmit.Cctlt);
Add("1110101111101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cctlt, InstEmit.Cctlt, InstProps.Rc);
Add("111000110101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cont, InstEmit.Cont);
Add("0101000010011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cset, InstEmit.Cset, InstProps.Rd);
Add("0101000010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Csetp, InstEmit.Csetp, InstProps.Pd | InstProps.Pdn);
Add("0101000011001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cs2r, InstEmit.Cs2r, InstProps.Rd);
Add("0101110001110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dadd, InstEmit.DaddR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x01110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dadd, InstEmit.DaddI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110001110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dadd, InstEmit.DaddC, InstProps.Rd | InstProps.Ra);
Add("1111000011110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Depbar, InstEmit.Depbar);
Add("010110110111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dfma, InstEmit.DfmaR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0011011x0111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dfma, InstEmit.DfmaI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("010010110111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dfma, InstEmit.DfmaC, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("010100110111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dfma, InstEmit.DfmaRc, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("0101110001010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmnmx, InstEmit.DmnmxR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x01010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmnmx, InstEmit.DmnmxI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110001010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmnmx, InstEmit.DmnmxC, InstProps.Rd | InstProps.Ra);
Add("0101110010000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmul, InstEmit.DmulR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x10000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmul, InstEmit.DmulI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110010000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmul, InstEmit.DmulC, InstProps.Rd | InstProps.Ra);
Add("010110010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dset, InstEmit.DsetR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011001x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dset, InstEmit.DsetI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("010010010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dset, InstEmit.DsetC, InstProps.Rd | InstProps.Ra);
Add("010110111000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dsetp, InstEmit.DsetpR, InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.Pdn);
Add("0011011x1000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dsetp, InstEmit.DsetpI, InstProps.Ra | InstProps.Ib | InstProps.Pd | InstProps.Pdn);
Add("010010111000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dsetp, InstEmit.DsetpC, InstProps.Ra | InstProps.Pd | InstProps.Pdn);
Add("111000110000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Exit, InstEmit.Exit, InstProps.Bra);
Add("0101110010101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.F2f, InstEmit.F2fR, InstProps.Rd | InstProps.Rb);
Add("0011100x10101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.F2f, InstEmit.F2fI, InstProps.Rd | InstProps.Ib);
Add("0100110010101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.F2f, InstEmit.F2fC, InstProps.Rd);
Add("0101110010110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.F2i, InstEmit.F2iR, InstProps.Rd | InstProps.Rb);
Add("0011100x10110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.F2i, InstEmit.F2iI, InstProps.Rd | InstProps.Ib);
Add("0100110010110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.F2i, InstEmit.F2iC, InstProps.Rd);
Add("0101110001011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fadd, InstEmit.FaddR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x01011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fadd, InstEmit.FaddI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110001011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fadd, InstEmit.FaddC, InstProps.Rd | InstProps.Ra);
Add("000010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fadd32i, InstEmit.Fadd32i, InstProps.Rd | InstProps.Ra);
Add("0101110010001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fchk, InstEmit.FchkR, InstProps.Ra | InstProps.Rb | InstProps.Pd);
Add("0011100x10001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fchk, InstEmit.FchkI, InstProps.Ra | InstProps.Ib | InstProps.Pd);
Add("0100110010001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fchk, InstEmit.FchkC, InstProps.Ra | InstProps.Pd);
Add("010110111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fcmp, InstEmit.FcmpR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0011011x1010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fcmp, InstEmit.FcmpI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("010010111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fcmp, InstEmit.FcmpC, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("010100111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fcmp, InstEmit.FcmpRc, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("010110011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ffma, InstEmit.FfmaR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0011001x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ffma, InstEmit.FfmaI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("010010011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ffma, InstEmit.FfmaC, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("010100011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ffma, InstEmit.FfmaRc, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("000011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ffma32i, InstEmit.Ffma32i, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("0101110000110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Flo, InstEmit.FloR, InstProps.Rd | InstProps.Rb);
Add("0011100x00110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Flo, InstEmit.FloI, InstProps.Rd | InstProps.Ib);
Add("0100110000110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Flo, InstEmit.FloC, InstProps.Rd);
Add("0101110001100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmnmx, InstEmit.FmnmxR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x01100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmnmx, InstEmit.FmnmxI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110001100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmnmx, InstEmit.FmnmxC, InstProps.Rd | InstProps.Ra);
Add("0101110001101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmul, InstEmit.FmulR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x01101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmul, InstEmit.FmulI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110001101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmul, InstEmit.FmulC, InstProps.Rd | InstProps.Ra);
Add("00011110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmul32i, InstEmit.Fmul32i, InstProps.Rd | InstProps.Ra);
Add("01011000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fset, InstEmit.FsetR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fset, InstEmit.FsetI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("01001000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fset, InstEmit.FsetC, InstProps.Rd | InstProps.Ra);
Add("010110111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fsetp, InstEmit.FsetpR, InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.Pdn);
Add("0011011x1011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fsetp, InstEmit.FsetpI, InstProps.Ra | InstProps.Ib | InstProps.Pd | InstProps.Pdn);
Add("010010111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fsetp, InstEmit.FsetpC, InstProps.Ra | InstProps.Pd | InstProps.Pdn);
Add("0101000011111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fswzadd, InstEmit.Fswzadd, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("111000101100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Getcrsptr, InstEmit.Getcrsptr, InstProps.Rd | InstProps.NoPred);
Add("111000101101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Getlmembase, InstEmit.Getlmembase, InstProps.Rd | InstProps.NoPred);
Add("0101110100010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hadd2, InstEmit.Hadd2R, InstProps.Rd | InstProps.Ra);
Add("0111101x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hadd2, InstEmit.Hadd2I, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0111101x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hadd2, InstEmit.Hadd2C, InstProps.Rd | InstProps.Ra);
Add("0010110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hadd232i, InstEmit.Hadd232i, InstProps.Rd | InstProps.Ra);
Add("0101110100000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hfma2, InstEmit.Hfma2R, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("01110xxx0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hfma2, InstEmit.Hfma2I, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("01110xxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hfma2, InstEmit.Hfma2C, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("01100xxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hfma2, InstEmit.Hfma2Rc, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("0101110100001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hmul2, InstEmit.Hmul2R, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0111100x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hmul2, InstEmit.Hmul2I, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0111100x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hmul2, InstEmit.Hmul2C, InstProps.Rd | InstProps.Ra);
Add("0010101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hmul232i, InstEmit.Hmul232i, InstProps.Rd | InstProps.Ra);
Add("0101110100011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hset2, InstEmit.Hset2R, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0111110x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hset2, InstEmit.Hset2I, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0111110x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hset2, InstEmit.Hset2C, InstProps.Rd | InstProps.Ra);
Add("0101110100100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hsetp2, InstEmit.Hsetp2R, InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.Pdn);
Add("0111111x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hsetp2, InstEmit.Hsetp2I, InstProps.Ra | InstProps.Ib | InstProps.Pd | InstProps.Pdn);
Add("0111111x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hsetp2, InstEmit.Hsetp2C, InstProps.Ra | InstProps.Pd | InstProps.Pdn);
Add("0101110010111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.I2f, InstEmit.I2fR, InstProps.Rd | InstProps.Rb);
Add("0011100x10111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.I2f, InstEmit.I2fI, InstProps.Rd | InstProps.Ib);
Add("0100110010111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.I2f, InstEmit.I2fC, InstProps.Rd);
Add("0101110011100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.I2i, InstEmit.I2iR, InstProps.Rd | InstProps.Rb);
Add("0011100x11100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.I2i, InstEmit.I2iI, InstProps.Rd | InstProps.Ib);
Add("0100110011100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.I2i, InstEmit.I2iC, InstProps.Rd);
Add("0101110000010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd, InstEmit.IaddR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x00010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd, InstEmit.IaddI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110000010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd, InstEmit.IaddC, InstProps.Rd | InstProps.Ra);
Add("0001110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd32i, InstEmit.Iadd32i, InstProps.Rd | InstProps.Ra);
Add("010111001100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd3, InstEmit.Iadd3R, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0011100x1100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd3, InstEmit.Iadd3I, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("010011001100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd3, InstEmit.Iadd3C, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("010110110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Icmp, InstEmit.IcmpR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0011011x0100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Icmp, InstEmit.IcmpI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("010010110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Icmp, InstEmit.IcmpC, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("010100110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Icmp, InstEmit.IcmpRc, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("111000111001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ide, InstEmit.Ide, InstProps.NoPred);
Add("0101001111111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Idp, InstEmit.IdpR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0101001111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Idp, InstEmit.IdpC, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("010110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imad, InstEmit.ImadR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0011010x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imad, InstEmit.ImadI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("010010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imad, InstEmit.ImadC, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("010100100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imad, InstEmit.ImadRc, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("000100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imad32i, InstEmit.Imad32i, InstProps.Rd | InstProps.Ra);
Add("010110101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imadsp, InstEmit.ImadspR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0011010x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imadsp, InstEmit.ImadspI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("010010101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imadsp, InstEmit.ImadspC, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("010100101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imadsp, InstEmit.ImadspRc, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("0101110000100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imnmx, InstEmit.ImnmxR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x00100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imnmx, InstEmit.ImnmxI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110000100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imnmx, InstEmit.ImnmxC, InstProps.Rd | InstProps.Ra);
Add("0101110000111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imul, InstEmit.ImulR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x00111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imul, InstEmit.ImulI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110000111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imul, InstEmit.ImulC, InstProps.Rd | InstProps.Ra);
Add("00011111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imul32i, InstEmit.Imul32i, InstProps.Rd | InstProps.Ra);
Add("11100000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ipa, InstEmit.Ipa, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("1110111111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Isberd, InstEmit.Isberd, InstProps.Rd | InstProps.Ra);
Add("0101110000011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iscadd, InstEmit.IscaddR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x00011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iscadd, InstEmit.IscaddI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110000011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iscadd, InstEmit.IscaddC, InstProps.Rd | InstProps.Ra);
Add("000101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iscadd32i, InstEmit.Iscadd32i, InstProps.Rd | InstProps.Ra);
Add("010110110101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iset, InstEmit.IsetR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011011x0101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iset, InstEmit.IsetI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("010010110101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iset, InstEmit.IsetC, InstProps.Rd | InstProps.Ra);
Add("010110110110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Isetp, InstEmit.IsetpR, InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.Pdn);
Add("0011011x0110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Isetp, InstEmit.IsetpI, InstProps.Ra | InstProps.Ib | InstProps.Pd | InstProps.Pdn);
Add("010010110110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Isetp, InstEmit.IsetpC, InstProps.Ra | InstProps.Pd | InstProps.Pdn);
Add("111000100010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Jcal, InstEmit.Jcal, InstProps.Bra);
Add("111000100001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Jmp, InstEmit.Jmp, InstProps.Ra | InstProps.Bra);
Add("111000100000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Jmx, InstEmit.Jmx, InstProps.Ra | InstProps.Bra);
Add("111000110011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Kil, InstEmit.Kil, InstProps.Bra);
Add("100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ld, InstEmit.Ld, InstProps.Rd | InstProps.Ra);
Add("1110111110010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ldc, InstEmit.Ldc, InstProps.Rd | InstProps.Ra);
Add("1110111011010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ldg, InstEmit.Ldg, InstProps.Rd | InstProps.Ra);
Add("1110111101000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ldl, InstEmit.Ldl, InstProps.Rd | InstProps.Ra);
Add("1110111101001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lds, InstEmit.Lds, InstProps.Rd | InstProps.Ra);
Add("0101101111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lea, InstEmit.LeaR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Pd);
Add("0011011x11010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lea, InstEmit.LeaI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Pd);
Add("0100101111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lea, InstEmit.LeaC, InstProps.Rd | InstProps.Ra | InstProps.Pd);
Add("0101101111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.LeaHi, InstEmit.LeaHiR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc | InstProps.Pd);
Add("000110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.LeaHi, InstEmit.LeaHiC, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.Pd);
Add("0101000011010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lepc, InstEmit.Lepc);
Add("111000110001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Longjmp, InstEmit.Longjmp, InstProps.Bra);
Add("0101110001000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop, InstEmit.LopR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Pd);
Add("0011100x01000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop, InstEmit.LopI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Pd);
Add("0100110001000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop, InstEmit.LopC, InstProps.Rd | InstProps.Ra | InstProps.Pd);
Add("0101101111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop3, InstEmit.Lop3R, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc | InstProps.Pd);
Add("001111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop3, InstEmit.Lop3I, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("0000001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop3, InstEmit.Lop3C, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("000001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop32i, InstEmit.Lop32i, InstProps.Rd | InstProps.Ra);
Add("1110111110011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Membar, InstEmit.Membar);
Add("0101110010011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Mov, InstEmit.MovR, InstProps.Rd | InstProps.Ra);
Add("0011100x10011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Mov, InstEmit.MovI, InstProps.Rd | InstProps.Ib);
Add("0100110010011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Mov, InstEmit.MovC, InstProps.Rd);
Add("000000010000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Mov32i, InstEmit.Mov32i, InstProps.Rd);
Add("0101000010000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Mufu, InstEmit.Mufu, InstProps.Rd | InstProps.Ra);
Add("0101000010110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Nop, InstEmit.Nop);
Add("1111101111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Out, InstEmit.OutR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("1111011x11100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Out, InstEmit.OutI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("1110101111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Out, InstEmit.OutC, InstProps.Rd | InstProps.Ra);
Add("0101110011101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.P2r, InstEmit.P2rR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x11101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.P2r, InstEmit.P2rI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110011101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.P2r, InstEmit.P2rC, InstProps.Rd | InstProps.Ra);
Add("111000101010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Pbk, InstEmit.Pbk, InstProps.NoPred);
Add("111000101011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Pcnt, InstEmit.Pcnt, InstProps.NoPred);
Add("111000100011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Pexit, InstEmit.Pexit);
Add("1110111111101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Pixld, InstEmit.Pixld, InstProps.Rd | InstProps.Ra);
Add("111000101000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Plongjmp, InstEmit.Plongjmp, InstProps.Bra | InstProps.NoPred);
Add("0101110000001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Popc, InstEmit.PopcR, InstProps.Rd | InstProps.Rb);
Add("0011100x00001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Popc, InstEmit.PopcI, InstProps.Rd | InstProps.Ib);
Add("0100110000001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Popc, InstEmit.PopcC, InstProps.Rd);
Add("111000100111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Pret, InstEmit.Pret, InstProps.NoPred);
Add("010110111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Prmt, InstEmit.PrmtR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0011011x1100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Prmt, InstEmit.PrmtI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("010010111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Prmt, InstEmit.PrmtC, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("010100111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Prmt, InstEmit.PrmtRc, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("0101000010001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Pset, InstEmit.Pset, InstProps.Rd);
Add("0101000010010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Psetp, InstEmit.Psetp, InstProps.Pd | InstProps.Pdn);
Add("1111000011000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.R2b, InstEmit.R2b, InstProps.Rb);
Add("0101110011110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.R2p, InstEmit.R2pR, InstProps.Ra | InstProps.Rb);
Add("0011100x11110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.R2p, InstEmit.R2pI, InstProps.Ra | InstProps.Ib);
Add("0100110011110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.R2p, InstEmit.R2pC, InstProps.Ra);
Add("111000111000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ram, InstEmit.Ram, InstProps.NoPred);
Add("1110101111111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Red, InstEmit.Red, InstProps.Ra);
Add("111000110010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ret, InstEmit.Ret, InstProps.Bra);
Add("0101110010010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Rro, InstEmit.RroR, InstProps.Rd | InstProps.Rb);
Add("0011100x10010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Rro, InstEmit.RroI, InstProps.Rd | InstProps.Ib);
Add("0100110010010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Rro, InstEmit.RroC, InstProps.Rd);
Add("111000110110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Rtt, InstEmit.Rtt, InstProps.NoPred);
Add("1111000011001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.S2r, InstEmit.S2r, InstProps.Rd);
Add("111000110111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sam, InstEmit.Sam, InstProps.NoPred);
Add("0101110010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sel, InstEmit.SelR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x10100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sel, InstEmit.SelI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sel, InstEmit.SelC, InstProps.Rd | InstProps.Ra);
Add("111000101110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Setcrsptr, InstEmit.Setcrsptr, InstProps.Ra | InstProps.NoPred);
Add("111000101111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Setlmembase, InstEmit.Setlmembase, InstProps.Ra | InstProps.NoPred);
Add("0101101111111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shf, InstEmit.ShfLR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0101110011111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shf, InstEmit.ShfRR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0011011x11111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shf, InstEmit.ShfLI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("0011100x11111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shf, InstEmit.ShfRI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("1110111100010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shfl, InstEmit.Shfl, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc | InstProps.Pd);
Add("0101110001001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shl, InstEmit.ShlR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x01001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shl, InstEmit.ShlI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110001001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shl, InstEmit.ShlC, InstProps.Rd | InstProps.Ra);
Add("0101110000101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shr, InstEmit.ShrR, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("0011100x00101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shr, InstEmit.ShrI, InstProps.Rd | InstProps.Ra | InstProps.Ib);
Add("0100110000101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shr, InstEmit.ShrC, InstProps.Rd | InstProps.Ra);
Add("111000101001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ssy, InstEmit.Ssy, InstProps.NoPred);
Add("101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.St, InstEmit.St, InstProps.Rd | InstProps.Ra);
Add("1110111011011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Stg, InstEmit.Stg, InstProps.Rd | InstProps.Ra);
Add("1110111101010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Stl, InstEmit.Stl, InstProps.Rd | InstProps.Ra);
Add("1110111010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Stp, InstEmit.Stp, InstProps.NoPred);
Add("1110111101011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sts, InstEmit.Sts, InstProps.Rd | InstProps.Ra);
Add("1110101001110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuatomB, InstEmit.SuatomB, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("11101010x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Suatom, InstEmit.Suatom, InstProps.Rd | InstProps.Ra | InstProps.Rb);
Add("1110101110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuatomB2, InstEmit.SuatomB2, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("1110101011010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuatomCasB, InstEmit.SuatomCasB, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc | InstProps.Pd2);
Add("1110101x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuatomCas, InstEmit.SuatomCas, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Pd2);
Add("111010110001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldDB, InstEmit.SuldDB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.Pd2 | InstProps.TexB);
Add("1110101100011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldD, InstEmit.SuldD, InstProps.Rd | InstProps.Ra | InstProps.Pd2 | InstProps.Tex);
Add("11101011000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldB, InstEmit.SuldB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.Pd2 | InstProps.TexB);
Add("11101011000x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Suld, InstEmit.Suld, InstProps.Rd | InstProps.Ra | InstProps.Pd2 | InstProps.Tex);
Add("111010110101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuredB, InstEmit.SuredB, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("1110101101011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sured, InstEmit.Sured, InstProps.Rd | InstProps.Ra);
Add("111010110011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SustDB, InstEmit.SustDB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.TexB);
Add("1110101100111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SustD, InstEmit.SustD, InstProps.Rd | InstProps.Ra | InstProps.Tex);
Add("11101011001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SustB, InstEmit.SustB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.TexB);
Add("11101011001x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sust, InstEmit.Sust, InstProps.Rd | InstProps.Ra | InstProps.Tex);
Add("1111000011111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sync, InstEmit.Sync, InstProps.Bra);
Add("11000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tex, InstEmit.Tex, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.Tex);
Add("1101111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TexB, InstEmit.TexB, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.TexB);
Add("1101100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Texs, InstEmit.Texs, InstProps.Rd | InstProps.Rd2 | InstProps.Ra | InstProps.Rb | InstProps.Tex);
Add("1101000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TexsF16, InstEmit.TexsF16, InstProps.Rd | InstProps.Rd2 | InstProps.Ra | InstProps.Rb | InstProps.Tex);
Add("11011100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tld, InstEmit.Tld, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.Tex);
Add("11011101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TldB, InstEmit.TldB, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.TexB);
Add("1101101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tlds, InstEmit.Tlds, InstProps.Rd | InstProps.Rd2 | InstProps.Ra | InstProps.Rb | InstProps.Tex);
Add("1101001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TldsF16, InstEmit.TldsF16, InstProps.Rd | InstProps.Rd2 | InstProps.Ra | InstProps.Rb | InstProps.Tex);
Add("110010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tld4, InstEmit.Tld4, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.Tex);
Add("1101111011xxxxxxxxxxxxx0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tld4B, InstEmit.Tld4B, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.TexB);
Add("1101111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tld4s, InstEmit.Tld4s, InstProps.Rd | InstProps.Rd2 | InstProps.Ra | InstProps.Rb | InstProps.Tex);
Add("1101111110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tld4sF16, InstEmit.Tld4sF16, InstProps.Rd | InstProps.Rd2 | InstProps.Ra | InstProps.Rb | InstProps.Tex);
Add("1101111101011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tmml, InstEmit.Tmml, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Tex);
Add("1101111101100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TmmlB, InstEmit.TmmlB, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.TexB);
Add("1101111101000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Txa, InstEmit.Txa, InstProps.Rd | InstProps.Ra | InstProps.Tex);
Add("110111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Txd, InstEmit.Txd, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.Tex);
Add("1101111001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TxdB, InstEmit.TxdB, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.TexB);
Add("1101111101001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Txq, InstEmit.Txq, InstProps.Rd | InstProps.Ra | InstProps.Tex);
Add("1101111101010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TxqB, InstEmit.TxqB, InstProps.Rd | InstProps.Ra | InstProps.TexB);
Add("01010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vabsdiff, InstEmit.Vabsdiff, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("010100000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vabsdiff4, InstEmit.Vabsdiff4, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("001000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vadd, InstEmit.Vadd, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("01011111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vmad, InstEmit.Vmad, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0011101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vmnmx, InstEmit.Vmnmx, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0101000011011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vote, InstEmit.Vote, InstProps.Rd);
Add("0101000011100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Votevtg, InstEmit.Votevtg);
Add("0100000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vset, InstEmit.Vset, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0101000011110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vsetp, InstEmit.Vsetp, InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.Pdn);
Add("01010111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vshl, InstEmit.Vshl, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("01010110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vshr, InstEmit.Vshr, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0101101100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad, InstEmit.XmadR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("0011011x00xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad, InstEmit.XmadI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
Add("0100111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad, InstEmit.XmadC, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("010100010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad, InstEmit.XmadRc, InstProps.Rd | InstProps.Ra | InstProps.Rc);
#endregion
}
private static void Add(string encoding, InstName name, InstEmitter emitter, InstProps props = InstProps.None)
{
encoding = encoding.Substring(0, EncodingBits);
int bit = encoding.Length - 1;
int value = 0;
int xMask = 0;
int xBits = 0;
int[] xPos = new int[encoding.Length];
for (int index = 0; index < encoding.Length; index++, bit--)
{
char chr = encoding[index];
if (chr == '1')
{
value |= 1 << bit;
}
else if (chr == 'x')
{
xMask |= 1 << bit;
xPos[xBits++] = bit;
}
}
xMask = ~xMask;
TableEntry entry = new TableEntry(name, emitter, props, xBits);
for (int index = 0; index < (1 << xBits); index++)
{
value &= xMask;
for (int x = 0; x < xBits; x++)
{
value |= ((index >> x) & 1) << xPos[x];
}
if (_opCodes[value].Emitter == null || _opCodes[value].XBits > xBits)
{
_opCodes[value] = entry;
}
}
}
public static InstOp GetOp(ulong address, ulong opCode)
{
ref TableEntry entry = ref _opCodes[opCode >> (64 - EncodingBits)];
if (entry.Emitter != null)
{
return new InstOp(address, opCode, entry.Name, entry.Emitter, entry.Props);
}
return new InstOp(address, opCode, InstName.Invalid, null, InstProps.None);
}
}
}

View file

@ -1,18 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum IntegerCondition
{
Less = 1 << 0,
Equal = 1 << 1,
Greater = 1 << 2,
Never = 0,
LessOrEqual = Less | Equal,
NotEqual = Less | Greater,
GreaterOrEqual = Greater | Equal,
Number = Greater | Equal | Less,
Always = 7
}
}

View file

@ -1,9 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum IntegerHalfPart
{
B32 = 0,
H0 = 1,
H1 = 2
}
}

View file

@ -1,9 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum IntegerShift
{
NoShift = 0,
ShiftRight = 1,
ShiftLeft = 2
}
}

View file

@ -1,14 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum IntegerSize
{
U8 = 0,
S8 = 1,
U16 = 2,
S16 = 3,
B32 = 4,
B64 = 5,
B128 = 6,
UB128 = 7
}
}

View file

@ -1,14 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum IntegerType
{
U8 = 0,
U16 = 1,
U32 = 2,
U64 = 3,
S8 = 4,
S16 = 5,
S32 = 6,
S64 = 7
}
}

View file

@ -1,10 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum InterpolationMode
{
Pass,
Default,
Constant,
Sc
}
}

View file

@ -1,10 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum LogicalOperation
{
And = 0,
Or = 1,
ExclusiveOr = 2,
Passthrough = 3
}
}

View file

@ -1,15 +0,0 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
enum MufuOperation
{
Cosine = 0,
Sine = 1,
ExponentB2 = 2,
LogarithmB2 = 3,
Reciprocal = 4,
ReciprocalSquareRoot = 5,
Reciprocal64H = 6,
ReciprocalSquareRoot64H = 7,
SquareRoot = 8
}
}

View file

@ -1,32 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCode
{
public InstEmitter Emitter { get; }
public ulong Address { get; }
public long RawOpCode { get; }
public Register Predicate { get; protected set; }
public bool InvertPredicate { get; protected set; }
// When inverted, the always true predicate == always false.
public bool NeverExecute => Predicate.Index == RegisterConsts.PredicateTrueIndex && InvertPredicate;
public static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCode(emitter, address, opCode);
public OpCode(InstEmitter emitter, ulong address, long opCode)
{
Emitter = emitter;
Address = address;
RawOpCode = opCode;
Predicate = new Register(opCode.Extract(16, 3), RegisterType.Predicate);
InvertPredicate = opCode.Extract(19);
}
}
}

View file

@ -1,24 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeAl2p : OpCode, IOpCodeRd, IOpCodeRa
{
public Register Rd { get; }
public Register Ra { get; }
public Register Predicate44 { get; }
public int Immediate { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAl2p(emitter, address, opCode);
public OpCodeAl2p(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
Predicate44 = new Register(opCode.Extract(44, 3), RegisterType.Predicate);
Immediate = ((int)opCode << 1) >> 21;
}
}
}

View file

@ -1,36 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeAlu : OpCode, IOpCodeAlu, IOpCodeRc
{
public Register Rd { get; }
public Register Ra { get; }
public Register Rc { get; }
public Register Predicate39 { get; }
public int ByteSelection { get; }
public bool InvertP { get; }
public bool Extended { get; protected set; }
public bool SetCondCode { get; protected set; }
public bool Saturate { get; protected set; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAlu(emitter, address, opCode);
public OpCodeAlu(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
Predicate39 = new Register(opCode.Extract(39, 3), RegisterType.Predicate);
ByteSelection = opCode.Extract(41, 2);
InvertP = opCode.Extract(42);
Extended = opCode.Extract(43);
SetCondCode = opCode.Extract(47);
Saturate = opCode.Extract(50);
}
}
}

View file

@ -1,18 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeAluCbuf : OpCodeAlu, IOpCodeCbuf
{
public int Offset { get; }
public int Slot { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAluCbuf(emitter, address, opCode);
public OpCodeAluCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Offset = opCode.Extract(20, 14);
Slot = opCode.Extract(34, 5);
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeAluImm : OpCodeAlu, IOpCodeImm
{
public int Immediate { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAluImm(emitter, address, opCode);
public OpCodeAluImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Immediate = DecoderHelper.DecodeS20Immediate(opCode);
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeAluImm2x10 : OpCodeAlu, IOpCodeImm
{
public int Immediate { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAluImm2x10(emitter, address, opCode);
public OpCodeAluImm2x10(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Immediate = DecoderHelper.Decode2xF10Immediate(opCode);
}
}
}

View file

@ -1,20 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeAluImm32 : OpCodeAlu, IOpCodeImm
{
public int Immediate { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAluImm32(emitter, address, opCode);
public OpCodeAluImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Immediate = opCode.Extract(20, 32);
SetCondCode = opCode.Extract(52);
Extended = opCode.Extract(53);
Saturate = opCode.Extract(54);
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeAluReg : OpCodeAlu, IOpCodeReg
{
public Register Rb { get; protected set; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAluReg(emitter, address, opCode);
public OpCodeAluReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
}
}
}

View file

@ -1,20 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeAluRegCbuf : OpCodeAluReg, IOpCodeRegCbuf
{
public int Offset { get; }
public int Slot { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAluRegCbuf(emitter, address, opCode);
public OpCodeAluRegCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Offset = opCode.Extract(20, 14);
Slot = opCode.Extract(34, 5);
Rb = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
}
}
}

View file

@ -1,28 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeAtom : OpCode, IOpCodeRd, IOpCodeRa, IOpCodeReg
{
public Register Rd { get; }
public Register Ra { get; }
public Register Rb { get; }
public bool Extended { get; }
public AtomicOp AtomicOp { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAtom(emitter, address, opCode);
public OpCodeAtom(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
Extended = opCode.Extract(48);
AtomicOp = (AtomicOp)opCode.Extract(52, 4);
}
}
}

View file

@ -1,23 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeAttribute : OpCodeAluReg, IOpCodeAttribute
{
public int AttributeOffset { get; }
public bool Patch { get; }
public int Count { get; }
public bool Phys => !Patch && AttributeOffset == 0 && !Ra.IsRZ;
public bool Indexed => Phys;
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAttribute(emitter, address, opCode);
public OpCodeAttribute(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
AttributeOffset = opCode.Extract(20, 10);
Patch = opCode.Extract(31);
Count = opCode.Extract(47, 2) + 1;
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeBarrier : OpCode
{
public BarrierMode Mode { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeBarrier(emitter, address, opCode);
public OpCodeBarrier(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Mode = (BarrierMode)((opCode >> 32) & 0x9b);
}
}
}

View file

@ -1,25 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeBranch : OpCodeConditional
{
public int Offset { get; }
public bool PushTarget { get; protected set; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeBranch(emitter, address, opCode);
public OpCodeBranch(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Offset = ((int)(opCode >> 20) << 8) >> 8;
PushTarget = false;
}
public ulong GetAbsoluteAddress()
{
return (ulong)((long)Address + (long)Offset + 8);
}
}
}

View file

@ -1,25 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
using System.Collections.Generic;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeBranchIndir : OpCode
{
public HashSet<Block> PossibleTargets { get; }
public Register Ra { get; }
public int Offset { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeBranchIndir(emitter, address, opCode);
public OpCodeBranchIndir(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
PossibleTargets = new HashSet<Block>();
Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
Offset = ((int)(opCode >> 20) << 8) >> 8;
}
}
}

View file

@ -1,17 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
using System.Collections.Generic;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeBranchPop : OpCodeConditional
{
public Dictionary<OpCodePush, int> Targets { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeBranchPop(emitter, address, opCode);
public OpCodeBranchPop(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Targets = new Dictionary<OpCodePush, int>();
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeConditional : OpCode
{
public Condition Condition { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeConditional(emitter, address, opCode);
public OpCodeConditional(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Condition = (Condition)opCode.Extract(0, 5);
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeDArithImm : OpCodeFArith, IOpCodeImmF
{
public float Immediate { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeDArithImm(emitter, address, opCode);
public OpCodeDArithImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Immediate = DecoderHelper.DecodeD20Immediate(opCode);
}
}
}

View file

@ -1,13 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeExit : OpCodeConditional
{
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeExit(emitter, address, opCode);
public OpCodeExit(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
}
}
}

View file

@ -1,26 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeFArith : OpCodeAlu, IOpCodeFArith
{
public RoundingMode RoundingMode { get; }
public FPMultiplyScale Scale { get; }
public bool FlushToZero { get; }
public bool AbsoluteA { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFArith(emitter, address, opCode);
public OpCodeFArith(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
RoundingMode = (RoundingMode)opCode.Extract(39, 2);
Scale = (FPMultiplyScale)opCode.Extract(41, 3);
FlushToZero = opCode.Extract(44);
AbsoluteA = opCode.Extract(46);
}
}
}

View file

@ -1,18 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeFArithCbuf : OpCodeFArith, IOpCodeCbuf
{
public int Offset { get; }
public int Slot { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFArithCbuf(emitter, address, opCode);
public OpCodeFArithCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Offset = opCode.Extract(20, 14);
Slot = opCode.Extract(34, 5);
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeFArithImm : OpCodeFArith, IOpCodeImmF
{
public float Immediate { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFArithImm(emitter, address, opCode);
public OpCodeFArithImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Immediate = DecoderHelper.DecodeF20Immediate(opCode);
}
}
}

View file

@ -1,32 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
using System;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeFArithImm32 : OpCodeAlu, IOpCodeFArith, IOpCodeImmF
{
public RoundingMode RoundingMode => RoundingMode.ToNearest;
public FPMultiplyScale Scale => FPMultiplyScale.None;
public bool FlushToZero { get; }
public bool AbsoluteA { get; }
public float Immediate { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFArithImm32(emitter, address, opCode);
public OpCodeFArithImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
int imm = opCode.Extract(20, 32);
Immediate = BitConverter.Int32BitsToSingle(imm);
SetCondCode = opCode.Extract(52);
AbsoluteA = opCode.Extract(54);
FlushToZero = opCode.Extract(55);
Saturate = false;
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeFArithReg : OpCodeFArith, IOpCodeReg
{
public Register Rb { get; protected set; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFArithReg(emitter, address, opCode);
public OpCodeFArithReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
}
}
}

View file

@ -1,18 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeFArithRegCbuf : OpCodeFArith, IOpCodeRegCbuf
{
public int Offset { get; }
public int Slot { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFArithRegCbuf(emitter, address, opCode);
public OpCodeFArithRegCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Offset = opCode.Extract(20, 14);
Slot = opCode.Extract(34, 5);
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeFsetImm : OpCodeSet, IOpCodeImmF
{
public float Immediate { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFsetImm(emitter, address, opCode);
public OpCodeFsetImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Immediate = DecoderHelper.DecodeF20Immediate(opCode);
}
}
}

View file

@ -1,24 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeHfma : OpCode, IOpCodeRd, IOpCodeRa, IOpCodeRc
{
public Register Rd { get; }
public Register Ra { get; }
public Register Rc { get; protected set; }
public FPHalfSwizzle SwizzleA { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHfma(emitter, address, opCode);
public OpCodeHfma(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
SwizzleA = (FPHalfSwizzle)opCode.Extract(47, 2);
}
}
}

View file

@ -1,32 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeHfmaCbuf : OpCodeHfma, IOpCodeHfma, IOpCodeCbuf
{
public int Offset { get; }
public int Slot { get; }
public bool NegateB { get; }
public bool NegateC { get; }
public bool Saturate { get; }
public FPHalfSwizzle SwizzleB => FPHalfSwizzle.FP32;
public FPHalfSwizzle SwizzleC { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHfmaCbuf(emitter, address, opCode);
public OpCodeHfmaCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Offset = opCode.Extract(20, 14);
Slot = opCode.Extract(34, 5);
NegateC = opCode.Extract(51);
Saturate = opCode.Extract(52);
SwizzleC = (FPHalfSwizzle)opCode.Extract(53, 2);
NegateB = opCode.Extract(56);
}
}
}

View file

@ -1,28 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeHfmaImm2x10 : OpCodeHfma, IOpCodeHfma, IOpCodeImm
{
public int Immediate { get; }
public bool NegateB => false;
public bool NegateC { get; }
public bool Saturate { get; }
public FPHalfSwizzle SwizzleB => FPHalfSwizzle.FP16;
public FPHalfSwizzle SwizzleC { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHfmaImm2x10(emitter, address, opCode);
public OpCodeHfmaImm2x10(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Immediate = DecoderHelper.Decode2xF10Immediate(opCode);
NegateC = opCode.Extract(51);
Saturate = opCode.Extract(52);
SwizzleC = (FPHalfSwizzle)opCode.Extract(53, 2);
}
}
}

View file

@ -1,27 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeHfmaImm32 : OpCodeHfma, IOpCodeHfma, IOpCodeImm
{
public int Immediate { get; }
public bool NegateB => false;
public bool NegateC { get; }
public bool Saturate => false;
public FPHalfSwizzle SwizzleB => FPHalfSwizzle.FP16;
public FPHalfSwizzle SwizzleC => FPHalfSwizzle.FP16;
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHfmaImm32(emitter, address, opCode);
public OpCodeHfmaImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Immediate = opCode.Extract(20, 32);
NegateC = opCode.Extract(52);
Rc = Rd;
}
}
}

View file

@ -1,31 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeHfmaReg : OpCodeHfma, IOpCodeHfma, IOpCodeReg
{
public Register Rb { get; }
public bool NegateB { get; }
public bool NegateC { get; }
public bool Saturate { get; }
public FPHalfSwizzle SwizzleB { get; }
public FPHalfSwizzle SwizzleC { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHfmaReg(emitter, address, opCode);
public OpCodeHfmaReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
SwizzleB = (FPHalfSwizzle)opCode.Extract(28, 2);
NegateC = opCode.Extract(30);
NegateB = opCode.Extract(31);
Saturate = opCode.Extract(32);
SwizzleC = (FPHalfSwizzle)opCode.Extract(35, 2);
}
}
}

View file

@ -1,32 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeHfmaRegCbuf : OpCodeHfma, IOpCodeHfma, IOpCodeRegCbuf
{
public int Offset { get; }
public int Slot { get; }
public bool NegateB { get; }
public bool NegateC { get; }
public bool Saturate { get; }
public FPHalfSwizzle SwizzleB { get; }
public FPHalfSwizzle SwizzleC => FPHalfSwizzle.FP32;
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHfmaRegCbuf(emitter, address, opCode);
public OpCodeHfmaRegCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Offset = opCode.Extract(20, 14);
Slot = opCode.Extract(34, 5);
NegateC = opCode.Extract(51);
Saturate = opCode.Extract(52);
SwizzleB = (FPHalfSwizzle)opCode.Extract(53, 2);
NegateB = opCode.Extract(56);
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeHsetImm2x10 : OpCodeSet, IOpCodeImm
{
public int Immediate { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHsetImm2x10(emitter, address, opCode);
public OpCodeHsetImm2x10(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Immediate = DecoderHelper.Decode2xF10Immediate(opCode);
}
}
}

View file

@ -1,47 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeImage : OpCodeTextureBase
{
public Register Ra { get; }
public Register Rb { get; }
public Register Rc { get; }
public ImageComponents Components { get; }
public IntegerSize Size { get; }
public bool ByteAddress { get; }
public ImageDimensions Dimensions { get; }
public bool UseComponents { get; }
public bool IsBindless { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeImage(emitter, address, opCode);
public OpCodeImage(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
Rb = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
UseComponents = !opCode.Extract(52);
if (UseComponents)
{
Components = (ImageComponents)opCode.Extract(20, 4);
}
else
{
Size = (IntegerSize)opCode.Extract(20, 4);
}
ByteAddress = opCode.Extract(23);
Dimensions = (ImageDimensions)opCode.Extract(33, 3);
IsBindless = !opCode.Extract(51);
}
}
}

View file

@ -1,28 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeIpa : OpCodeAluReg, IOpCodeAttribute
{
public int AttributeOffset { get; }
public int Count => 1;
public bool Idx { get; }
public bool Indexed => Idx;
public InterpolationMode Mode { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeIpa(emitter, address, opCode);
public OpCodeIpa(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
AttributeOffset = opCode.Extract(28, 10);
Idx = opCode.Extract(38);
Saturate = opCode.Extract(51);
Mode = (InterpolationMode)opCode.Extract(54, 2);
}
}
}

View file

@ -1,30 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeLdc : OpCode, IOpCodeRd, IOpCodeRa, IOpCodeCbuf
{
public Register Rd { get; }
public Register Ra { get; }
public int Offset { get; }
public int Slot { get; }
public CbIndexMode IndexMode { get; }
public IntegerSize Size { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeLdc(emitter, address, opCode);
public OpCodeLdc(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
Offset = (opCode.Extract(20, 16) << 16) >> 16;
Slot = opCode.Extract(36, 5);
IndexMode = (CbIndexMode)opCode.Extract(44, 2);
Size = (IntegerSize)opCode.Extract(48, 3);
}
}
}

View file

@ -1,26 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeLop : OpCodeAlu, IOpCodeLop
{
public bool InvertA { get; protected set; }
public bool InvertB { get; protected set; }
public LogicalOperation LogicalOp { get; }
public Register Predicate48 { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeLop(emitter, address, opCode);
public OpCodeLop(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
InvertA = opCode.Extract(39);
InvertB = opCode.Extract(40);
LogicalOp = (LogicalOperation)opCode.Extract(41, 2);
Predicate48 = new Register(opCode.Extract(48, 3), RegisterType.Predicate);
}
}
}

View file

@ -1,18 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeLopCbuf : OpCodeLop, IOpCodeCbuf
{
public int Offset { get; }
public int Slot { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeLopCbuf(emitter, address, opCode);
public OpCodeLopCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Offset = opCode.Extract(20, 14);
Slot = opCode.Extract(34, 5);
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeLopImm : OpCodeLop, IOpCodeImm
{
public int Immediate { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeLopImm(emitter, address, opCode);
public OpCodeLopImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Immediate = DecoderHelper.DecodeS20Immediate(opCode);
}
}
}

View file

@ -1,24 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeLopImm32 : OpCodeAluImm32, IOpCodeLop, IOpCodeImm
{
public LogicalOperation LogicalOp { get; }
public bool InvertA { get; }
public bool InvertB { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeLopImm32(emitter, address, opCode);
public OpCodeLopImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
LogicalOp = (LogicalOperation)opCode.Extract(53, 2);
InvertA = opCode.Extract(55);
InvertB = opCode.Extract(56);
Extended = opCode.Extract(57);
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeLopReg : OpCodeLop, IOpCodeReg
{
public Register Rb { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeLopReg(emitter, address, opCode);
public OpCodeLopReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
}
}
}

View file

@ -1,30 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeMemory : OpCode, IOpCodeRd, IOpCodeRa
{
public Register Rd { get; }
public Register Ra { get; }
public int Offset { get; }
public bool Extended { get; }
public IntegerSize Size { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeMemory(emitter, address, opCode);
public OpCodeMemory(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
Offset = (opCode.Extract(20, 24) << 8) >> 8;
Extended = opCode.Extract(45);
Size = (IntegerSize)opCode.Extract(48, 3);
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeMemoryBarrier : OpCode
{
public BarrierLevel Level { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeMemoryBarrier(emitter, address, opCode);
public OpCodeMemoryBarrier(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Level = (BarrierLevel)opCode.Extract(8, 2);
}
}
}

View file

@ -1,28 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodePset : OpCodeSet
{
public Register Predicate12 { get; }
public Register Predicate29 { get; }
public bool InvertA { get; }
public bool InvertB { get; }
public LogicalOperation LogicalOpAB { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodePset(emitter, address, opCode);
public OpCodePset(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Predicate12 = new Register(opCode.Extract(12, 3), RegisterType.Predicate);
Predicate29 = new Register(opCode.Extract(29, 3), RegisterType.Predicate);
InvertA = opCode.Extract(15);
InvertB = opCode.Extract(32);
LogicalOpAB = (LogicalOperation)opCode.Extract(24, 2);
}
}
}

View file

@ -1,24 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using System.Collections.Generic;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodePush : OpCodeBranch
{
public Dictionary<OpCodeBranchPop, Operand> PopOps { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodePush(emitter, address, opCode);
public OpCodePush(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
PopOps = new Dictionary<OpCodeBranchPop, Operand>();
Predicate = new Register(RegisterConsts.PredicateTrueIndex, RegisterType.Predicate);
InvertPredicate = false;
PushTarget = true;
}
}
}

View file

@ -1,34 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeRed : OpCode, IOpCodeRd, IOpCodeRa
{
public Register Rd { get; }
public Register Ra { get; }
public AtomicOp AtomicOp { get; }
public ReductionType Type { get; }
public int Offset { get; }
public bool Extended { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeRed(emitter, address, opCode);
public OpCodeRed(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
Type = (ReductionType)opCode.Extract(20, 3);
AtomicOp = (AtomicOp)opCode.Extract(23, 3);
Offset = (opCode.Extract(28, 20) << 12) >> 12;
Extended = opCode.Extract(48);
}
}
}

View file

@ -1,28 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeSet : OpCodeAlu
{
public Register Predicate0 { get; }
public Register Predicate3 { get; }
public bool NegateP { get; }
public LogicalOperation LogicalOp { get; }
public bool FlushToZero { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeSet(emitter, address, opCode);
public OpCodeSet(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Predicate0 = new Register(opCode.Extract(0, 3), RegisterType.Predicate);
Predicate3 = new Register(opCode.Extract(3, 3), RegisterType.Predicate);
LogicalOp = (LogicalOperation)opCode.Extract(45, 2);
FlushToZero = opCode.Extract(47);
}
}
}

View file

@ -1,18 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeSetCbuf : OpCodeSet, IOpCodeCbuf
{
public int Offset { get; }
public int Slot { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeSetCbuf(emitter, address, opCode);
public OpCodeSetCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Offset = opCode.Extract(20, 14);
Slot = opCode.Extract(34, 5);
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeSetImm : OpCodeSet, IOpCodeImm
{
public int Immediate { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeSetImm(emitter, address, opCode);
public OpCodeSetImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Immediate = DecoderHelper.DecodeS20Immediate(opCode);
}
}
}

View file

@ -1,16 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeSetReg : OpCodeSet, IOpCodeReg
{
public Register Rb { get; protected set; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeSetReg(emitter, address, opCode);
public OpCodeSetReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
}
}
}

View file

@ -1,42 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeShuffle : OpCode, IOpCodeRd, IOpCodeRa
{
public Register Rd { get; }
public Register Ra { get; }
public Register Rb { get; }
public Register Rc { get; }
public int ImmediateB { get; }
public int ImmediateC { get; }
public bool IsBImmediate { get; }
public bool IsCImmediate { get; }
public ShuffleType ShuffleType { get; }
public Register Predicate48 { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeShuffle(emitter, address, opCode);
public OpCodeShuffle(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
ImmediateB = opCode.Extract(20, 5);
ImmediateC = opCode.Extract(34, 13);
IsBImmediate = opCode.Extract(28);
IsCImmediate = opCode.Extract(29);
ShuffleType = (ShuffleType)opCode.Extract(30, 2);
Predicate48 = new Register(opCode.Extract(48, 3), RegisterType.Predicate);
}
}
}

View file

@ -1,46 +0,0 @@
using Ryujinx.Graphics.Shader.Instructions;
namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeSuatom : OpCodeTextureBase
{
public Register Rd { get; }
public Register Ra { get; }
public Register Rb { get; }
public Register Rc { get; }
public ReductionType Type { get; }
public AtomicOp AtomicOp { get; }
public ImageDimensions Dimensions { get; }
public ClampMode ClampMode { get; }
public bool ByteAddress { get; }
public bool UseType { get; }
public bool IsBindless { get; }
public bool CompareAndSwap { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeSuatom(emitter, address, opCode);
public OpCodeSuatom(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
bool supportsBindless = opCode.Extract(54);
Type = (ReductionType)opCode.Extract(supportsBindless ? 36 : 51, 3);
ByteAddress = opCode.Extract(28);
AtomicOp = (AtomicOp)opCode.Extract(29, 4); // Only useful if CAS is not true.
Dimensions = (ImageDimensions)opCode.Extract(33, 3);
ClampMode = (ClampMode)opCode.Extract(49, 2);
IsBindless = supportsBindless && !opCode.Extract(51);
UseType = !supportsBindless || opCode.Extract(52);
CompareAndSwap = opCode.Extract(55);
}
}
}

Some files were not shown because too many files have changed in this diff Show more