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:
parent
0510fde25a
commit
a7109c767b
@ -60,14 +60,14 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads data from GPU memory.
|
||||
/// Gets a span of the specified memory location, containing shader code.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the data to be read</typeparam>
|
||||
/// <param name="address">GPU virtual address of the data</param>
|
||||
/// <returns>Data at the memory location</returns>
|
||||
public override T MemoryRead<T>(ulong address)
|
||||
/// <param name="minimumSize">Minimum size that the returned span may have</param>
|
||||
/// <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>
|
||||
|
@ -1,6 +1,8 @@
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Shader
|
||||
{
|
||||
@ -95,24 +97,15 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads data from GPU memory.
|
||||
/// Gets a span of the specified memory location, containing shader code.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the data to be read</typeparam>
|
||||
/// <param name="address">GPU virtual address of the data</param>
|
||||
/// <returns>Data at the memory location</returns>
|
||||
public override T MemoryRead<T>(ulong address)
|
||||
/// <param name="minimumSize">Minimum size that the returned span may have</param>
|
||||
/// <returns>Span of the memory location</returns>
|
||||
public override ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize)
|
||||
{
|
||||
return _channel.MemoryManager.Read<T>(address);
|
||||
}
|
||||
|
||||
/// <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);
|
||||
int size = Math.Max(minimumSize, 0x1000 - (int)(address & 0xfff));
|
||||
return MemoryMarshal.Cast<byte, ulong>(_channel.MemoryManager.GetSpan(address, size));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
/// <summary>
|
||||
/// Version of the codegen (to be changed when codegen or guest format change).
|
||||
/// </summary>
|
||||
private const ulong ShaderCodeGenVersion = 2646;
|
||||
private const ulong ShaderCodeGenVersion = 2697;
|
||||
|
||||
// Progress reporting helpers
|
||||
private volatile int _shaderCount;
|
||||
|
@ -1,6 +1,7 @@
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Gpu.Image;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Shader
|
||||
{
|
||||
@ -13,7 +14,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
_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);
|
||||
|
||||
|
@ -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.
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum BarrierLevel
|
||||
{
|
||||
Cta = 0,
|
||||
Gl = 1,
|
||||
Sys = 2,
|
||||
Vc = 3
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum BarrierMode
|
||||
{
|
||||
ReductionPopCount = 2,
|
||||
Scan = 3,
|
||||
ReductionAnd = 0xa,
|
||||
ReductionOr = 0x12,
|
||||
Sync = 0x80,
|
||||
Arrive = 0x81
|
||||
}
|
||||
}
|
@ -11,15 +11,5 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,57 +1,56 @@
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
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
|
||||
{
|
||||
public ulong Address { get; set; }
|
||||
public ulong Address { get; set; }
|
||||
public ulong EndAddress { get; set; }
|
||||
|
||||
private Block _next;
|
||||
private Block _branch;
|
||||
public List<Block> Predecessors { get; }
|
||||
public List<Block> Successors { get; }
|
||||
|
||||
public Block Next
|
||||
{
|
||||
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 List<InstOp> OpCodes { get; }
|
||||
public List<PushOpInfo> PushOpCodes { get; }
|
||||
public Dictionary<ulong, SyncTarget> SyncTargets { get; }
|
||||
|
||||
public Block(ulong address)
|
||||
{
|
||||
Address = address;
|
||||
|
||||
Predecessors = new HashSet<Block>();
|
||||
Predecessors = new List<Block>();
|
||||
Successors = new List<Block>();
|
||||
|
||||
OpCodes = new List<OpCode>();
|
||||
PushOpCodes = new List<OpCodePush>();
|
||||
OpCodes = new List<InstOp>();
|
||||
PushOpCodes = new List<PushOpInfo>();
|
||||
SyncTargets = new Dictionary<ulong, SyncTarget>();
|
||||
}
|
||||
|
||||
public void Split(Block rightBlock)
|
||||
@ -64,36 +63,56 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
}
|
||||
|
||||
int splitCount = OpCodes.Count - splitIndex;
|
||||
|
||||
if (splitCount <= 0)
|
||||
{
|
||||
throw new ArgumentException("Can't split at right block address.");
|
||||
}
|
||||
|
||||
rightBlock.EndAddress = EndAddress;
|
||||
|
||||
rightBlock.Next = Next;
|
||||
rightBlock.Branch = Branch;
|
||||
|
||||
rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount));
|
||||
|
||||
rightBlock.UpdatePushOps();
|
||||
rightBlock.Successors.AddRange(Successors);
|
||||
rightBlock.Predecessors.Add(this);
|
||||
|
||||
EndAddress = rightBlock.Address;
|
||||
|
||||
Next = rightBlock;
|
||||
Branch = null;
|
||||
Successors.Clear();
|
||||
Successors.Add(rightBlock);
|
||||
|
||||
// Move ops.
|
||||
rightBlock.OpCodes.AddRange(OpCodes.GetRange(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 right = opCodes.Count - 1;
|
||||
int right = opCodes.Count - 1;
|
||||
|
||||
while (left <= right)
|
||||
{
|
||||
@ -101,7 +120,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
|
||||
middle = left + (size >> 1);
|
||||
|
||||
OpCode opCode = opCodes[middle];
|
||||
InstOp opCode = opCodes[middle];
|
||||
|
||||
if (address == opCode.Address)
|
||||
{
|
||||
@ -121,29 +140,25 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
return middle;
|
||||
}
|
||||
|
||||
public OpCode GetLastOp()
|
||||
public InstOp GetLastOp()
|
||||
{
|
||||
if (OpCodes.Count != 0)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
if (!(OpCodes[index] is OpCodePush op))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PushOpCodes.Add(op);
|
||||
}
|
||||
public void AddPushOp(InstOp op)
|
||||
{
|
||||
PushOpCodes.Add(new PushOpInfo(op));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum CbIndexMode
|
||||
{
|
||||
Default = 0,
|
||||
Il = 1,
|
||||
Is = 2,
|
||||
Isl = 3
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum ConditionalOperation
|
||||
{
|
||||
False = 0,
|
||||
True = 1,
|
||||
Zero = 2,
|
||||
NotZero = 3
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
using Ryujinx.Graphics.Shader.Instructions;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
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,
|
||||
// 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
|
||||
// points to (when taken), "Next" is the block at the next address,
|
||||
// executed when the branch is not taken. For Unconditional Branches
|
||||
// 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(opBr.GetAbsoluteAddress());
|
||||
}
|
||||
else
|
||||
{
|
||||
currBlock.Branch = GetBlock(opBr.GetAbsoluteAddress());
|
||||
}
|
||||
EnqueueFunction(lastOp.GetAbsoluteAddress());
|
||||
}
|
||||
else if (lastOp.Name == InstName.Bra)
|
||||
{
|
||||
Block succBlock = GetBlock(lastOp.GetAbsoluteAddress());
|
||||
currBlock.Successors.Add(succBlock);
|
||||
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.
|
||||
hasNewTarget = false;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Try to find targets for BRX (indirect branch) instructions.
|
||||
hasNewTarget = FindBrxTargets(config, blocks, GetBlock);
|
||||
|
||||
// If we discovered new branch targets from the BRX instruction,
|
||||
// we need another round of decoding to decode the new blocks.
|
||||
@ -227,6 +203,10 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
IGpuAccessor gpuAccessor = config.GpuAccessor;
|
||||
|
||||
ulong address = block.Address;
|
||||
int bufferOffset = 0;
|
||||
ReadOnlySpan<ulong> buffer = ReadOnlySpan<ulong>.Empty;
|
||||
|
||||
InstOp op = default;
|
||||
|
||||
do
|
||||
{
|
||||
@ -239,66 +219,75 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
if ((address & 0x1f) == 0)
|
||||
{
|
||||
address += 8;
|
||||
|
||||
bufferOffset++;
|
||||
continue;
|
||||
}
|
||||
|
||||
ulong opAddress = address;
|
||||
|
||||
address += 8;
|
||||
|
||||
long opCode = gpuAccessor.MemoryRead<long>(startAddress + opAddress);
|
||||
|
||||
(InstEmitter emitter, OpCodeTable.MakeOp makeOp) = OpCodeTable.GetEmitter(opCode);
|
||||
|
||||
if (emitter == null)
|
||||
if (bufferOffset >= buffer.Length)
|
||||
{
|
||||
// TODO: Warning, illegal encoding.
|
||||
|
||||
block.OpCodes.Add(new OpCode(null, opAddress, opCode));
|
||||
|
||||
continue;
|
||||
buffer = gpuAccessor.GetCode(startAddress + address, 8);
|
||||
bufferOffset = 0;
|
||||
}
|
||||
|
||||
if (makeOp == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(makeOp));
|
||||
}
|
||||
ulong opCode = buffer[bufferOffset++];
|
||||
|
||||
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 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))
|
||||
if (op.Props.HasFlag(InstProps.TexB))
|
||||
{
|
||||
config.SetUsedFeature(FeatureFlags.Bindless);
|
||||
}
|
||||
|
||||
// Populate used attributes.
|
||||
if (op is IOpCodeAttribute opAttr)
|
||||
if (op.Name == InstName.Ald || op.Name == InstName.Ast || op.Name == InstName.Ipa)
|
||||
{
|
||||
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);
|
||||
|
||||
address += 8;
|
||||
}
|
||||
while (!IsControlFlowChange(block.GetLastOp()));
|
||||
while (!op.Props.HasFlag(InstProps.Bra));
|
||||
|
||||
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();
|
||||
}
|
||||
@ -309,14 +298,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
}
|
||||
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)
|
||||
{
|
||||
int index = (attr - AttributeConsts.UserAttributeBase) / 16;
|
||||
|
||||
if (opAttr.Emitter == InstEmit.Ast)
|
||||
if (isStore)
|
||||
{
|
||||
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 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) ||
|
||||
opCode is OpCodeBranchIndir ||
|
||||
opCode is OpCodeBranchPop ||
|
||||
opCode is OpCodeExit;
|
||||
bool hasNewTarget = false;
|
||||
|
||||
foreach (Block block in blocks)
|
||||
{
|
||||
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)
|
||||
@ -369,41 +388,51 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
HashSet<Block> visited = new HashSet<Block>();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (opLdc.Slot != 1 || opLdc.IndexMode != CbIndexMode.Default)
|
||||
GetOp<InstLdc>(ldcLocation, out var opLdc);
|
||||
|
||||
if (opLdc.CbufSlot != 1 || opLdc.AddressMode != 0)
|
||||
{
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
var shlLocation = FindFirstRegWrite(visited, ldcLocation, opLdc.Ra.Index);
|
||||
if (shlLocation.Block == null || shlLocation.Block.OpCodes[shlLocation.Index] is not OpCodeAluImm opShl)
|
||||
var shlLocation = FindFirstRegWrite(visited, ldcLocation, opLdc.SrcA);
|
||||
if (shlLocation.Block == null || !shlLocation.IsImmInst(InstName.Shl))
|
||||
{
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
if (opShl.Emitter != InstEmit.Shl || opShl.Immediate != 2)
|
||||
GetOp<InstShlI>(shlLocation, out var opShl);
|
||||
|
||||
if (opShl.Imm20 != 2)
|
||||
{
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
var imnmxLocation = FindFirstRegWrite(visited, shlLocation, opShl.Ra.Index);
|
||||
if (imnmxLocation.Block == null || imnmxLocation.Block.OpCodes[imnmxLocation.Index] is not OpCodeAluImm opImnmx)
|
||||
var imnmxLocation = FindFirstRegWrite(visited, shlLocation, opShl.SrcA);
|
||||
if (imnmxLocation.Block == null || !imnmxLocation.IsImmInst(InstName.Imnmx))
|
||||
{
|
||||
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 (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
|
||||
@ -416,6 +445,12 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
Block = block;
|
||||
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)
|
||||
@ -447,18 +482,20 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
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.
|
||||
if (opCode.Emitter == InstEmit.Fsetp ||
|
||||
opCode.Emitter == InstEmit.Hsetp2 ||
|
||||
opCode.Emitter == InstEmit.Isetp ||
|
||||
opCode.Emitter == InstEmit.R2p)
|
||||
if ((op.Props & (InstProps.Rd | InstProps.Rd2)) == 0)
|
||||
{
|
||||
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
|
||||
@ -527,14 +564,13 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
|
||||
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()];
|
||||
|
||||
Stack<PathBlockState> workQueue = new Stack<PathBlockState>();
|
||||
|
||||
HashSet<Block> visited = new HashSet<Block>();
|
||||
|
||||
Stack<(ulong, MergeType)> branchStack = new Stack<(ulong, MergeType)>();
|
||||
|
||||
void Push(PathBlockState pbs)
|
||||
@ -574,42 +610,30 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
}
|
||||
|
||||
int pushOpsCount = current.PushOpCodes.Count;
|
||||
|
||||
if (pushOpsCount != 0)
|
||||
{
|
||||
Push(new PathBlockState(branchStack.Count));
|
||||
|
||||
for (int index = pushOpIndex; index < pushOpsCount; index++)
|
||||
{
|
||||
OpCodePush currentPushOp = current.PushOpCodes[index];
|
||||
MergeType pushMergeType = currentPushOp.Emitter == InstEmit.Ssy ? MergeType.Sync : MergeType.Brk;
|
||||
InstOp currentPushOp = current.PushOpCodes[index].Op;
|
||||
MergeType pushMergeType = currentPushOp.Name == InstName.Ssy ? MergeType.Sync : MergeType.Brk;
|
||||
branchStack.Push((currentPushOp.GetAbsoluteAddress(), pushMergeType));
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
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;
|
||||
MergeType popMergeType = lastOp.Name == InstName.Sync ? MergeType.Sync : MergeType.Brk;
|
||||
|
||||
bool found = true;
|
||||
ulong targetAddress = 0UL;
|
||||
@ -641,20 +665,32 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
// If the entire stack was consumed, then the current pop 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);
|
||||
current.Successors.Add(target);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Push the block itself into the work "queue" (well, it's a stack)
|
||||
// for processing.
|
||||
// Push the block itself into the work queue for processing.
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum FPHalfSwizzle
|
||||
{
|
||||
FP16 = 0,
|
||||
FP32 = 1,
|
||||
DupH0 = 2,
|
||||
DupH1 = 3
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeAlu : IOpCodeRd, IOpCodeRa, IOpCodePredicate39
|
||||
{
|
||||
bool Extended { get; }
|
||||
bool SetCondCode { get; }
|
||||
bool Saturate { get; }
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeAttribute : IOpCode
|
||||
{
|
||||
int AttributeOffset { get; }
|
||||
int Count { get; }
|
||||
bool Indexed { get; }
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeCbuf : IOpCode
|
||||
{
|
||||
int Offset { get; }
|
||||
int Slot { get; }
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeFArith : IOpCodeAlu
|
||||
{
|
||||
RoundingMode RoundingMode { get; }
|
||||
|
||||
FPMultiplyScale Scale { get; }
|
||||
|
||||
bool FlushToZero { get; }
|
||||
bool AbsoluteA { get; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeImm : IOpCode
|
||||
{
|
||||
int Immediate { get; }
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeImmF : IOpCode
|
||||
{
|
||||
float Immediate { get; }
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeLop : IOpCodeAlu
|
||||
{
|
||||
LogicalOperation LogicalOp { get; }
|
||||
|
||||
bool InvertA { get; }
|
||||
bool InvertB { get; }
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodePredicate39
|
||||
{
|
||||
Register Predicate39 { get; }
|
||||
|
||||
bool InvertP { get; }
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeRa : IOpCode
|
||||
{
|
||||
Register Ra { get; }
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeRc : IOpCode
|
||||
{
|
||||
Register Rc { get; }
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeRd : IOpCode
|
||||
{
|
||||
Register Rd { get; }
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeReg : IOpCode
|
||||
{
|
||||
Register Rb { get; }
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeRegCbuf : IOpCodeRc
|
||||
{
|
||||
int Offset { get; }
|
||||
int Slot { get; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeTld4 : IOpCodeTexture
|
||||
{
|
||||
TextureGatherOffset Offset { get; }
|
||||
|
||||
int GatherCompIndex { get; }
|
||||
|
||||
bool Bindless { get; }
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum ImageComponents
|
||||
{
|
||||
Red = 1 << 0,
|
||||
Green = 1 << 1,
|
||||
Blue = 1 << 2,
|
||||
Alpha = 1 << 3
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum ImageDimensions
|
||||
{
|
||||
Image1D,
|
||||
ImageBuffer,
|
||||
Image1DArray,
|
||||
Image2D,
|
||||
Image2DArray,
|
||||
Image3D
|
||||
}
|
||||
}
|
5362
Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
Normal file
5362
Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
Normal file
File diff suppressed because it is too large
Load Diff
188
Ryujinx.Graphics.Shader/Decoders/InstName.cs
Normal file
188
Ryujinx.Graphics.Shader/Decoders/InstName.cs
Normal 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,
|
||||
}
|
||||
}
|
27
Ryujinx.Graphics.Shader/Decoders/InstOp.cs
Normal file
27
Ryujinx.Graphics.Shader/Decoders/InstOp.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
20
Ryujinx.Graphics.Shader/Decoders/InstProps.cs
Normal file
20
Ryujinx.Graphics.Shader/Decoders/InstProps.cs
Normal 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
|
||||
}
|
||||
}
|
388
Ryujinx.Graphics.Shader/Decoders/InstTable.cs
Normal file
388
Ryujinx.Graphics.Shader/Decoders/InstTable.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum IntegerHalfPart
|
||||
{
|
||||
B32 = 0,
|
||||
H0 = 1,
|
||||
H1 = 2
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum IntegerShift
|
||||
{
|
||||
NoShift = 0,
|
||||
ShiftRight = 1,
|
||||
ShiftLeft = 2
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum InterpolationMode
|
||||
{
|
||||
Pass,
|
||||
Default,
|
||||
Constant,
|
||||
Sc
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum LogicalOperation
|
||||
{
|
||||
And = 0,
|
||||
Or = 1,
|
||||
ExclusiveOr = 2,
|
||||
Passthrough = 3
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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>();
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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
Loading…
Reference in New Issue
Block a user