mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2024-11-15 01:25:25 +00:00
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>
|
/// <summary>
|
||||||
/// Reads data from GPU memory.
|
/// Gets a span of the specified memory location, containing shader code.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Type of the data to be read</typeparam>
|
|
||||||
/// <param name="address">GPU virtual address of the data</param>
|
/// <param name="address">GPU virtual address of the data</param>
|
||||||
/// <returns>Data at the memory location</returns>
|
/// <param name="minimumSize">Minimum size that the returned span may have</param>
|
||||||
public override T MemoryRead<T>(ulong address)
|
/// <returns>Span of the memory location</returns>
|
||||||
|
public override ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize)
|
||||||
{
|
{
|
||||||
return MemoryMarshal.Cast<byte, T>(_data.Span.Slice((int)address))[0];
|
return MemoryMarshal.Cast<byte, ulong>(_data.Span.Slice((int)address));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Shader
|
namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
{
|
{
|
||||||
|
@ -95,24 +97,15 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads data from GPU memory.
|
/// Gets a span of the specified memory location, containing shader code.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Type of the data to be read</typeparam>
|
|
||||||
/// <param name="address">GPU virtual address of the data</param>
|
/// <param name="address">GPU virtual address of the data</param>
|
||||||
/// <returns>Data at the memory location</returns>
|
/// <param name="minimumSize">Minimum size that the returned span may have</param>
|
||||||
public override T MemoryRead<T>(ulong address)
|
/// <returns>Span of the memory location</returns>
|
||||||
|
public override ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize)
|
||||||
{
|
{
|
||||||
return _channel.MemoryManager.Read<T>(address);
|
int size = Math.Max(minimumSize, 0x1000 - (int)(address & 0xfff));
|
||||||
}
|
return MemoryMarshal.Cast<byte, ulong>(_channel.MemoryManager.GetSpan(address, size));
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if a given memory address is mapped.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="address">GPU virtual address to be checked</param>
|
|
||||||
/// <returns>True if the address is mapped, false otherwise</returns>
|
|
||||||
public bool MemoryMapped(ulong address)
|
|
||||||
{
|
|
||||||
return _channel.MemoryManager.IsMapped(address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version of the codegen (to be changed when codegen or guest format change).
|
/// Version of the codegen (to be changed when codegen or guest format change).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const ulong ShaderCodeGenVersion = 2646;
|
private const ulong ShaderCodeGenVersion = 2697;
|
||||||
|
|
||||||
// Progress reporting helpers
|
// Progress reporting helpers
|
||||||
private volatile int _shaderCount;
|
private volatile int _shaderCount;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Gpu.Image;
|
using Ryujinx.Graphics.Gpu.Image;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Shader
|
namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
{
|
{
|
||||||
|
@ -13,7 +14,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
_context = context;
|
_context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract T MemoryRead<T>(ulong address) where T : unmanaged;
|
public abstract ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize);
|
||||||
|
|
||||||
public abstract ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot);
|
public abstract ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot);
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
{
|
{
|
||||||
texCall = "int(" + texCall + ")";
|
texCall = "int(" + texCall + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
texCall += ")" + (texOp.Inst == Instruction.ImageLoad ? GetMask(texOp.Index) : "");
|
texCall += ")" + (texOp.Inst == Instruction.ImageLoad ? GetMask(texOp.Index) : "");
|
||||||
|
|
|
@ -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));
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Decoders
|
namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
{
|
{
|
||||||
|
class PushOpInfo
|
||||||
|
{
|
||||||
|
public InstOp Op { get; }
|
||||||
|
public Dictionary<Block, Operand> Consumers;
|
||||||
|
|
||||||
|
public PushOpInfo(InstOp op)
|
||||||
|
{
|
||||||
|
Op = op;
|
||||||
|
Consumers = new Dictionary<Block, Operand>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SyncTarget
|
||||||
|
{
|
||||||
|
public PushOpInfo PushOpInfo { get; }
|
||||||
|
public int PushOpId { get; }
|
||||||
|
|
||||||
|
public SyncTarget(PushOpInfo pushOpInfo, int pushOpId)
|
||||||
|
{
|
||||||
|
PushOpInfo = pushOpInfo;
|
||||||
|
PushOpId = pushOpId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Block
|
class Block
|
||||||
{
|
{
|
||||||
public ulong Address { get; set; }
|
public ulong Address { get; set; }
|
||||||
public ulong EndAddress { get; set; }
|
public ulong EndAddress { get; set; }
|
||||||
|
|
||||||
private Block _next;
|
public List<Block> Predecessors { get; }
|
||||||
private Block _branch;
|
public List<Block> Successors { get; }
|
||||||
|
|
||||||
public Block Next
|
public List<InstOp> OpCodes { get; }
|
||||||
{
|
public List<PushOpInfo> PushOpCodes { get; }
|
||||||
get
|
public Dictionary<ulong, SyncTarget> SyncTargets { get; }
|
||||||
{
|
|
||||||
return _next;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_next?.Predecessors.Remove(this);
|
|
||||||
value?.Predecessors.Add(this);
|
|
||||||
_next = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Block Branch
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _branch;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_branch?.Predecessors.Remove(this);
|
|
||||||
value?.Predecessors.Add(this);
|
|
||||||
_branch = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashSet<Block> Predecessors { get; }
|
|
||||||
|
|
||||||
public List<OpCode> OpCodes { get; }
|
|
||||||
public List<OpCodePush> PushOpCodes { get; }
|
|
||||||
|
|
||||||
public Block(ulong address)
|
public Block(ulong address)
|
||||||
{
|
{
|
||||||
Address = address;
|
Address = address;
|
||||||
|
|
||||||
Predecessors = new HashSet<Block>();
|
Predecessors = new List<Block>();
|
||||||
|
Successors = new List<Block>();
|
||||||
|
|
||||||
OpCodes = new List<OpCode>();
|
OpCodes = new List<InstOp>();
|
||||||
PushOpCodes = new List<OpCodePush>();
|
PushOpCodes = new List<PushOpInfo>();
|
||||||
|
SyncTargets = new Dictionary<ulong, SyncTarget>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Split(Block rightBlock)
|
public void Split(Block rightBlock)
|
||||||
|
@ -64,36 +63,56 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
}
|
}
|
||||||
|
|
||||||
int splitCount = OpCodes.Count - splitIndex;
|
int splitCount = OpCodes.Count - splitIndex;
|
||||||
|
|
||||||
if (splitCount <= 0)
|
if (splitCount <= 0)
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Can't split at right block address.");
|
throw new ArgumentException("Can't split at right block address.");
|
||||||
}
|
}
|
||||||
|
|
||||||
rightBlock.EndAddress = EndAddress;
|
rightBlock.EndAddress = EndAddress;
|
||||||
|
rightBlock.Successors.AddRange(Successors);
|
||||||
rightBlock.Next = Next;
|
rightBlock.Predecessors.Add(this);
|
||||||
rightBlock.Branch = Branch;
|
|
||||||
|
|
||||||
rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount));
|
|
||||||
|
|
||||||
rightBlock.UpdatePushOps();
|
|
||||||
|
|
||||||
EndAddress = rightBlock.Address;
|
EndAddress = rightBlock.Address;
|
||||||
|
|
||||||
Next = rightBlock;
|
Successors.Clear();
|
||||||
Branch = null;
|
Successors.Add(rightBlock);
|
||||||
|
|
||||||
|
// Move ops.
|
||||||
|
rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount));
|
||||||
|
|
||||||
OpCodes.RemoveRange(splitIndex, splitCount);
|
OpCodes.RemoveRange(splitIndex, splitCount);
|
||||||
|
|
||||||
UpdatePushOps();
|
// Update push consumers that points to this block.
|
||||||
|
foreach (SyncTarget syncTarget in SyncTargets.Values)
|
||||||
|
{
|
||||||
|
PushOpInfo pushOpInfo = syncTarget.PushOpInfo;
|
||||||
|
|
||||||
|
Operand local = pushOpInfo.Consumers[this];
|
||||||
|
pushOpInfo.Consumers.Remove(this);
|
||||||
|
pushOpInfo.Consumers.Add(rightBlock, local);
|
||||||
|
}
|
||||||
|
|
||||||
|
rightBlock.SyncTargets.Union(SyncTargets);
|
||||||
|
SyncTargets.Clear();
|
||||||
|
|
||||||
|
// Move push ops.
|
||||||
|
for (int i = 0; i < PushOpCodes.Count; i++)
|
||||||
|
{
|
||||||
|
if (PushOpCodes[i].Op.Address >= rightBlock.Address)
|
||||||
|
{
|
||||||
|
int count = PushOpCodes.Count - i;
|
||||||
|
rightBlock.PushOpCodes.AddRange(PushOpCodes.Skip(i));
|
||||||
|
PushOpCodes.RemoveRange(i, count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int BinarySearch(List<OpCode> opCodes, ulong address)
|
private static int BinarySearch(List<InstOp> opCodes, ulong address)
|
||||||
{
|
{
|
||||||
int left = 0;
|
int left = 0;
|
||||||
int middle = 0;
|
int middle = 0;
|
||||||
int right = opCodes.Count - 1;
|
int right = opCodes.Count - 1;
|
||||||
|
|
||||||
while (left <= right)
|
while (left <= right)
|
||||||
{
|
{
|
||||||
|
@ -101,7 +120,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
|
|
||||||
middle = left + (size >> 1);
|
middle = left + (size >> 1);
|
||||||
|
|
||||||
OpCode opCode = opCodes[middle];
|
InstOp opCode = opCodes[middle];
|
||||||
|
|
||||||
if (address == opCode.Address)
|
if (address == opCode.Address)
|
||||||
{
|
{
|
||||||
|
@ -121,29 +140,25 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
return middle;
|
return middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpCode GetLastOp()
|
public InstOp GetLastOp()
|
||||||
{
|
{
|
||||||
if (OpCodes.Count != 0)
|
if (OpCodes.Count != 0)
|
||||||
{
|
{
|
||||||
return OpCodes[OpCodes.Count - 1];
|
return OpCodes[OpCodes.Count - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdatePushOps()
|
public bool HasNext()
|
||||||
{
|
{
|
||||||
PushOpCodes.Clear();
|
InstOp lastOp = GetLastOp();
|
||||||
|
return OpCodes.Count != 0 && !Decoder.IsUnconditionalBranch(ref lastOp);
|
||||||
|
}
|
||||||
|
|
||||||
for (int index = 0; index < OpCodes.Count; index++)
|
public void AddPushOp(InstOp op)
|
||||||
{
|
{
|
||||||
if (!(OpCodes[index] is OpCodePush op))
|
PushOpCodes.Add(new PushOpInfo(op));
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PushOpCodes.Add(op);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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 Ryujinx.Graphics.Shader.Translation;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
|
@ -95,32 +95,33 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
{
|
{
|
||||||
// We should have blocks for all possible branch targets,
|
// We should have blocks for all possible branch targets,
|
||||||
// including those from SSY/PBK instructions.
|
// including those from SSY/PBK instructions.
|
||||||
foreach (OpCodePush pushOp in currBlock.PushOpCodes)
|
foreach (PushOpInfo pushOp in currBlock.PushOpCodes)
|
||||||
{
|
{
|
||||||
GetBlock(pushOp.GetAbsoluteAddress());
|
GetBlock(pushOp.Op.GetAbsoluteAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set child blocks. "Branch" is the block the branch instruction
|
// Set child blocks. "Branch" is the block the branch instruction
|
||||||
// points to (when taken), "Next" is the block at the next address,
|
// points to (when taken), "Next" is the block at the next address,
|
||||||
// executed when the branch is not taken. For Unconditional Branches
|
// executed when the branch is not taken. For Unconditional Branches
|
||||||
// or end of program, Next is null.
|
// or end of program, Next is null.
|
||||||
OpCode lastOp = currBlock.GetLastOp();
|
InstOp lastOp = currBlock.GetLastOp();
|
||||||
|
|
||||||
if (lastOp is OpCodeBranch opBr)
|
if (lastOp.Name == InstName.Cal)
|
||||||
{
|
{
|
||||||
if (lastOp.Emitter == InstEmit.Cal)
|
EnqueueFunction(lastOp.GetAbsoluteAddress());
|
||||||
{
|
}
|
||||||
EnqueueFunction(opBr.GetAbsoluteAddress());
|
else if (lastOp.Name == InstName.Bra)
|
||||||
}
|
{
|
||||||
else
|
Block succBlock = GetBlock(lastOp.GetAbsoluteAddress());
|
||||||
{
|
currBlock.Successors.Add(succBlock);
|
||||||
currBlock.Branch = GetBlock(opBr.GetAbsoluteAddress());
|
succBlock.Predecessors.Add(currBlock);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsUnconditionalBranch(lastOp))
|
if (!IsUnconditionalBranch(ref lastOp))
|
||||||
{
|
{
|
||||||
currBlock.Next = GetBlock(currBlock.EndAddress);
|
Block succBlock = GetBlock(currBlock.EndAddress);
|
||||||
|
currBlock.Successors.Insert(0, succBlock);
|
||||||
|
succBlock.Predecessors.Add(currBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,33 +147,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to find target for BRX (indirect branch) instructions.
|
// Try to find targets for BRX (indirect branch) instructions.
|
||||||
hasNewTarget = false;
|
hasNewTarget = FindBrxTargets(config, blocks, GetBlock);
|
||||||
|
|
||||||
foreach (Block block in blocks)
|
|
||||||
{
|
|
||||||
if (block.GetLastOp() is OpCodeBranchIndir opBrIndir && opBrIndir.PossibleTargets.Count == 0)
|
|
||||||
{
|
|
||||||
ulong baseOffset = opBrIndir.Address + 8 + (ulong)opBrIndir.Offset;
|
|
||||||
|
|
||||||
// An indirect branch could go anywhere,
|
|
||||||
// try to get the possible target offsets from the constant buffer.
|
|
||||||
(int cbBaseOffset, int cbOffsetsCount) = FindBrxTargetRange(block, opBrIndir.Ra.Index);
|
|
||||||
|
|
||||||
if (cbOffsetsCount != 0)
|
|
||||||
{
|
|
||||||
hasNewTarget = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < cbOffsetsCount; i++)
|
|
||||||
{
|
|
||||||
uint targetOffset = config.GpuAccessor.ConstantBuffer1Read(cbBaseOffset + i * 4);
|
|
||||||
Block target = GetBlock(baseOffset + targetOffset);
|
|
||||||
opBrIndir.PossibleTargets.Add(target);
|
|
||||||
target.Predecessors.Add(block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we discovered new branch targets from the BRX instruction,
|
// If we discovered new branch targets from the BRX instruction,
|
||||||
// we need another round of decoding to decode the new blocks.
|
// we need another round of decoding to decode the new blocks.
|
||||||
|
@ -227,6 +203,10 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
IGpuAccessor gpuAccessor = config.GpuAccessor;
|
IGpuAccessor gpuAccessor = config.GpuAccessor;
|
||||||
|
|
||||||
ulong address = block.Address;
|
ulong address = block.Address;
|
||||||
|
int bufferOffset = 0;
|
||||||
|
ReadOnlySpan<ulong> buffer = ReadOnlySpan<ulong>.Empty;
|
||||||
|
|
||||||
|
InstOp op = default;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -239,66 +219,75 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
if ((address & 0x1f) == 0)
|
if ((address & 0x1f) == 0)
|
||||||
{
|
{
|
||||||
address += 8;
|
address += 8;
|
||||||
|
bufferOffset++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong opAddress = address;
|
if (bufferOffset >= buffer.Length)
|
||||||
|
|
||||||
address += 8;
|
|
||||||
|
|
||||||
long opCode = gpuAccessor.MemoryRead<long>(startAddress + opAddress);
|
|
||||||
|
|
||||||
(InstEmitter emitter, OpCodeTable.MakeOp makeOp) = OpCodeTable.GetEmitter(opCode);
|
|
||||||
|
|
||||||
if (emitter == null)
|
|
||||||
{
|
{
|
||||||
// TODO: Warning, illegal encoding.
|
buffer = gpuAccessor.GetCode(startAddress + address, 8);
|
||||||
|
bufferOffset = 0;
|
||||||
block.OpCodes.Add(new OpCode(null, opAddress, opCode));
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (makeOp == null)
|
ulong opCode = buffer[bufferOffset++];
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(makeOp));
|
|
||||||
}
|
|
||||||
|
|
||||||
OpCode op = makeOp(emitter, opAddress, opCode);
|
op = InstTable.GetOp(address, opCode);
|
||||||
|
|
||||||
// We check these patterns to figure out the presence of bindless access
|
if (op.Props.HasFlag(InstProps.TexB))
|
||||||
if ((op is OpCodeImage image && image.IsBindless) ||
|
|
||||||
(op is OpCodeTxd txd && txd.IsBindless) ||
|
|
||||||
(op is OpCodeTld4B) ||
|
|
||||||
(emitter == InstEmit.TexB) ||
|
|
||||||
(emitter == InstEmit.TldB) ||
|
|
||||||
(emitter == InstEmit.TmmlB) ||
|
|
||||||
(emitter == InstEmit.TxqB))
|
|
||||||
{
|
{
|
||||||
config.SetUsedFeature(FeatureFlags.Bindless);
|
config.SetUsedFeature(FeatureFlags.Bindless);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate used attributes.
|
if (op.Name == InstName.Ald || op.Name == InstName.Ast || op.Name == InstName.Ipa)
|
||||||
if (op is IOpCodeAttribute opAttr)
|
|
||||||
{
|
{
|
||||||
SetUserAttributeUses(config, opAttr);
|
SetUserAttributeUses(config, op.Name, opCode);
|
||||||
|
}
|
||||||
|
else if (op.Name == InstName.Ssy || op.Name == InstName.Pbk)
|
||||||
|
{
|
||||||
|
block.AddPushOp(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
block.OpCodes.Add(op);
|
block.OpCodes.Add(op);
|
||||||
|
|
||||||
|
address += 8;
|
||||||
}
|
}
|
||||||
while (!IsControlFlowChange(block.GetLastOp()));
|
while (!op.Props.HasFlag(InstProps.Bra));
|
||||||
|
|
||||||
block.EndAddress = address;
|
block.EndAddress = address;
|
||||||
|
|
||||||
block.UpdatePushOps();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetUserAttributeUses(ShaderConfig config, IOpCodeAttribute opAttr)
|
private static void SetUserAttributeUses(ShaderConfig config, InstName name, ulong opCode)
|
||||||
{
|
{
|
||||||
if (opAttr.Indexed)
|
int offset;
|
||||||
|
int count = 1;
|
||||||
|
bool isStore = false;
|
||||||
|
bool indexed = false;
|
||||||
|
|
||||||
|
if (name == InstName.Ast)
|
||||||
{
|
{
|
||||||
if (opAttr.Emitter == InstEmit.Ast)
|
InstAst opAst = new InstAst(opCode);
|
||||||
|
count = (int)opAst.AlSize + 1;
|
||||||
|
offset = opAst.Imm11;
|
||||||
|
indexed = opAst.Phys;
|
||||||
|
isStore = true;
|
||||||
|
}
|
||||||
|
else if (name == InstName.Ald)
|
||||||
|
{
|
||||||
|
InstAld opAld = new InstAld(opCode);
|
||||||
|
count = (int)opAld.AlSize + 1;
|
||||||
|
indexed = opAld.Phys;
|
||||||
|
offset = opAld.Imm11;
|
||||||
|
}
|
||||||
|
else /* if (name == InstName.Ipa) */
|
||||||
|
{
|
||||||
|
InstIpa opIpa = new InstIpa(opCode);
|
||||||
|
offset = opIpa.Imm10;
|
||||||
|
indexed = opIpa.Idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indexed)
|
||||||
|
{
|
||||||
|
if (isStore)
|
||||||
{
|
{
|
||||||
config.SetAllOutputUserAttributes();
|
config.SetAllOutputUserAttributes();
|
||||||
}
|
}
|
||||||
|
@ -309,14 +298,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int elemIndex = 0; elemIndex < opAttr.Count; elemIndex++)
|
for (int elemIndex = 0; elemIndex < count; elemIndex++)
|
||||||
{
|
{
|
||||||
int attr = opAttr.AttributeOffset + elemIndex * 4;
|
int attr = offset + elemIndex * 4;
|
||||||
if (attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd)
|
if (attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd)
|
||||||
{
|
{
|
||||||
int index = (attr - AttributeConsts.UserAttributeBase) / 16;
|
int index = (attr - AttributeConsts.UserAttributeBase) / 16;
|
||||||
|
|
||||||
if (opAttr.Emitter == InstEmit.Ast)
|
if (isStore)
|
||||||
{
|
{
|
||||||
config.SetOutputUserAttribute(index);
|
config.SetOutputUserAttribute(index);
|
||||||
}
|
}
|
||||||
|
@ -329,27 +318,57 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsUnconditionalBranch(OpCode opCode)
|
public static bool IsUnconditionalBranch(ref InstOp op)
|
||||||
{
|
{
|
||||||
return IsUnconditional(opCode) && IsControlFlowChange(opCode);
|
return IsUnconditional(ref op) && op.Props.HasFlag(InstProps.Bra);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsUnconditional(OpCode opCode)
|
private static bool IsUnconditional(ref InstOp op)
|
||||||
{
|
{
|
||||||
if (opCode is OpCodeExit op && op.Condition != Condition.Always)
|
InstConditional condOp = new InstConditional(op.RawOpCode);
|
||||||
|
|
||||||
|
if (op.Name == InstName.Exit && condOp.Ccc != Ccc.T)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return opCode.Predicate.Index == RegisterConsts.PredicateTrueIndex && !opCode.InvertPredicate;
|
return condOp.Pred == RegisterConsts.PredicateTrueIndex && !condOp.PredInv;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsControlFlowChange(OpCode opCode)
|
private static bool FindBrxTargets(ShaderConfig config, IEnumerable<Block> blocks, Func<ulong, Block> getBlock)
|
||||||
{
|
{
|
||||||
return (opCode is OpCodeBranch opBranch && !opBranch.PushTarget) ||
|
bool hasNewTarget = false;
|
||||||
opCode is OpCodeBranchIndir ||
|
|
||||||
opCode is OpCodeBranchPop ||
|
foreach (Block block in blocks)
|
||||||
opCode is OpCodeExit;
|
{
|
||||||
|
InstOp lastOp = block.GetLastOp();
|
||||||
|
bool hasNext = block.HasNext();
|
||||||
|
|
||||||
|
if (lastOp.Name == InstName.Brx && block.Successors.Count == (hasNext ? 1 : 0))
|
||||||
|
{
|
||||||
|
InstBrx opBrx = new InstBrx(lastOp.RawOpCode);
|
||||||
|
ulong baseOffset = lastOp.GetAbsoluteAddress();
|
||||||
|
|
||||||
|
// An indirect branch could go anywhere,
|
||||||
|
// try to get the possible target offsets from the constant buffer.
|
||||||
|
(int cbBaseOffset, int cbOffsetsCount) = FindBrxTargetRange(block, opBrx.SrcA);
|
||||||
|
|
||||||
|
if (cbOffsetsCount != 0)
|
||||||
|
{
|
||||||
|
hasNewTarget = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < cbOffsetsCount; i++)
|
||||||
|
{
|
||||||
|
uint targetOffset = config.GpuAccessor.ConstantBuffer1Read(cbBaseOffset + i * 4);
|
||||||
|
Block target = getBlock(baseOffset + targetOffset);
|
||||||
|
target.Predecessors.Add(block);
|
||||||
|
block.Successors.Add(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasNewTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static (int, int) FindBrxTargetRange(Block block, int brxReg)
|
private static (int, int) FindBrxTargetRange(Block block, int brxReg)
|
||||||
|
@ -369,41 +388,51 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
HashSet<Block> visited = new HashSet<Block>();
|
HashSet<Block> visited = new HashSet<Block>();
|
||||||
|
|
||||||
var ldcLocation = FindFirstRegWrite(visited, new BlockLocation(block, block.OpCodes.Count - 1), brxReg);
|
var ldcLocation = FindFirstRegWrite(visited, new BlockLocation(block, block.OpCodes.Count - 1), brxReg);
|
||||||
if (ldcLocation.Block == null || ldcLocation.Block.OpCodes[ldcLocation.Index] is not OpCodeLdc opLdc)
|
if (ldcLocation.Block == null || ldcLocation.Block.OpCodes[ldcLocation.Index].Name != InstName.Ldc)
|
||||||
{
|
{
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opLdc.Slot != 1 || opLdc.IndexMode != CbIndexMode.Default)
|
GetOp<InstLdc>(ldcLocation, out var opLdc);
|
||||||
|
|
||||||
|
if (opLdc.CbufSlot != 1 || opLdc.AddressMode != 0)
|
||||||
{
|
{
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var shlLocation = FindFirstRegWrite(visited, ldcLocation, opLdc.Ra.Index);
|
var shlLocation = FindFirstRegWrite(visited, ldcLocation, opLdc.SrcA);
|
||||||
if (shlLocation.Block == null || shlLocation.Block.OpCodes[shlLocation.Index] is not OpCodeAluImm opShl)
|
if (shlLocation.Block == null || !shlLocation.IsImmInst(InstName.Shl))
|
||||||
{
|
{
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opShl.Emitter != InstEmit.Shl || opShl.Immediate != 2)
|
GetOp<InstShlI>(shlLocation, out var opShl);
|
||||||
|
|
||||||
|
if (opShl.Imm20 != 2)
|
||||||
{
|
{
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var imnmxLocation = FindFirstRegWrite(visited, shlLocation, opShl.Ra.Index);
|
var imnmxLocation = FindFirstRegWrite(visited, shlLocation, opShl.SrcA);
|
||||||
if (imnmxLocation.Block == null || imnmxLocation.Block.OpCodes[imnmxLocation.Index] is not OpCodeAluImm opImnmx)
|
if (imnmxLocation.Block == null || !imnmxLocation.IsImmInst(InstName.Imnmx))
|
||||||
{
|
{
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isImnmxS32 = opImnmx.RawOpCode.Extract(48);
|
GetOp<InstImnmxI>(imnmxLocation, out var opImnmx);
|
||||||
|
|
||||||
if (opImnmx.Emitter != InstEmit.Imnmx || isImnmxS32 || !opImnmx.Predicate39.IsPT || opImnmx.InvertP)
|
if (opImnmx.Signed || opImnmx.SrcPred != RegisterConsts.PredicateTrueIndex || opImnmx.SrcPredInv)
|
||||||
{
|
{
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (opLdc.Offset, opImnmx.Immediate + 1);
|
return (opLdc.CbufOffset, opImnmx.Imm20 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void GetOp<T>(BlockLocation location, out T op) where T : unmanaged
|
||||||
|
{
|
||||||
|
ulong rawOp = location.Block.OpCodes[location.Index].RawOpCode;
|
||||||
|
op = Unsafe.As<ulong, T>(ref rawOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct BlockLocation
|
private struct BlockLocation
|
||||||
|
@ -416,6 +445,12 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
Block = block;
|
Block = block;
|
||||||
Index = index;
|
Index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsImmInst(InstName name)
|
||||||
|
{
|
||||||
|
InstOp op = Block.OpCodes[Index];
|
||||||
|
return op.Name == name && op.Props.HasFlag(InstProps.Ib);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BlockLocation FindFirstRegWrite(HashSet<Block> visited, BlockLocation location, int regIndex)
|
private static BlockLocation FindFirstRegWrite(HashSet<Block> visited, BlockLocation location, int regIndex)
|
||||||
|
@ -447,18 +482,20 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
return new BlockLocation(null, 0);
|
return new BlockLocation(null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool WritesToRegister(OpCode opCode, int regIndex)
|
private static bool WritesToRegister(InstOp op, int regIndex)
|
||||||
{
|
{
|
||||||
// Predicate instruction only ever writes to predicate, so we shouldn't check those.
|
// Predicate instruction only ever writes to predicate, so we shouldn't check those.
|
||||||
if (opCode.Emitter == InstEmit.Fsetp ||
|
if ((op.Props & (InstProps.Rd | InstProps.Rd2)) == 0)
|
||||||
opCode.Emitter == InstEmit.Hsetp2 ||
|
|
||||||
opCode.Emitter == InstEmit.Isetp ||
|
|
||||||
opCode.Emitter == InstEmit.R2p)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return opCode is IOpCodeRd opRd && opRd.Rd.Index == regIndex;
|
if (op.Props.HasFlag(InstProps.Rd2) && (byte)(op.RawOpCode >> 28) == regIndex)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (byte)op.RawOpCode == regIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum MergeType
|
private enum MergeType
|
||||||
|
@ -527,14 +564,13 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
|
|
||||||
private static void PropagatePushOp(Dictionary<ulong, Block> blocks, Block currBlock, int pushOpIndex)
|
private static void PropagatePushOp(Dictionary<ulong, Block> blocks, Block currBlock, int pushOpIndex)
|
||||||
{
|
{
|
||||||
OpCodePush pushOp = currBlock.PushOpCodes[pushOpIndex];
|
PushOpInfo pushOpInfo = currBlock.PushOpCodes[pushOpIndex];
|
||||||
|
InstOp pushOp = pushOpInfo.Op;
|
||||||
|
|
||||||
Block target = blocks[pushOp.GetAbsoluteAddress()];
|
Block target = blocks[pushOp.GetAbsoluteAddress()];
|
||||||
|
|
||||||
Stack<PathBlockState> workQueue = new Stack<PathBlockState>();
|
Stack<PathBlockState> workQueue = new Stack<PathBlockState>();
|
||||||
|
|
||||||
HashSet<Block> visited = new HashSet<Block>();
|
HashSet<Block> visited = new HashSet<Block>();
|
||||||
|
|
||||||
Stack<(ulong, MergeType)> branchStack = new Stack<(ulong, MergeType)>();
|
Stack<(ulong, MergeType)> branchStack = new Stack<(ulong, MergeType)>();
|
||||||
|
|
||||||
void Push(PathBlockState pbs)
|
void Push(PathBlockState pbs)
|
||||||
|
@ -574,42 +610,30 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
}
|
}
|
||||||
|
|
||||||
int pushOpsCount = current.PushOpCodes.Count;
|
int pushOpsCount = current.PushOpCodes.Count;
|
||||||
|
|
||||||
if (pushOpsCount != 0)
|
if (pushOpsCount != 0)
|
||||||
{
|
{
|
||||||
Push(new PathBlockState(branchStack.Count));
|
Push(new PathBlockState(branchStack.Count));
|
||||||
|
|
||||||
for (int index = pushOpIndex; index < pushOpsCount; index++)
|
for (int index = pushOpIndex; index < pushOpsCount; index++)
|
||||||
{
|
{
|
||||||
OpCodePush currentPushOp = current.PushOpCodes[index];
|
InstOp currentPushOp = current.PushOpCodes[index].Op;
|
||||||
MergeType pushMergeType = currentPushOp.Emitter == InstEmit.Ssy ? MergeType.Sync : MergeType.Brk;
|
MergeType pushMergeType = currentPushOp.Name == InstName.Ssy ? MergeType.Sync : MergeType.Brk;
|
||||||
branchStack.Push((currentPushOp.GetAbsoluteAddress(), pushMergeType));
|
branchStack.Push((currentPushOp.GetAbsoluteAddress(), pushMergeType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pushOpIndex = 0;
|
pushOpIndex = 0;
|
||||||
|
|
||||||
if (current.Next != null)
|
bool hasNext = current.HasNext();
|
||||||
|
if (hasNext)
|
||||||
{
|
{
|
||||||
Push(new PathBlockState(current.Next));
|
Push(new PathBlockState(current.Successors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current.Branch != null)
|
InstOp lastOp = current.GetLastOp();
|
||||||
|
if (lastOp.Name == InstName.Sync || lastOp.Name == InstName.Brk)
|
||||||
{
|
{
|
||||||
Push(new PathBlockState(current.Branch));
|
MergeType popMergeType = lastOp.Name == InstName.Sync ? MergeType.Sync : MergeType.Brk;
|
||||||
}
|
|
||||||
else if (current.GetLastOp() is OpCodeBranchIndir brIndir)
|
|
||||||
{
|
|
||||||
// By adding them in descending order (sorted by address), we process the blocks
|
|
||||||
// in order (of ascending address), since we work with a LIFO.
|
|
||||||
foreach (Block possibleTarget in brIndir.PossibleTargets.OrderByDescending(x => x.Address))
|
|
||||||
{
|
|
||||||
Push(new PathBlockState(possibleTarget));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (current.GetLastOp() is OpCodeBranchPop op)
|
|
||||||
{
|
|
||||||
MergeType popMergeType = op.Emitter == InstEmit.Sync ? MergeType.Sync : MergeType.Brk;
|
|
||||||
|
|
||||||
bool found = true;
|
bool found = true;
|
||||||
ulong targetAddress = 0UL;
|
ulong targetAddress = 0UL;
|
||||||
|
@ -641,20 +665,32 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
{
|
{
|
||||||
// If the entire stack was consumed, then the current pop instruction
|
// If the entire stack was consumed, then the current pop instruction
|
||||||
// just consumed the address from our push instruction.
|
// just consumed the address from our push instruction.
|
||||||
if (op.Targets.TryAdd(pushOp, op.Targets.Count))
|
if (current.SyncTargets.TryAdd(pushOp.Address, new SyncTarget(pushOpInfo, current.SyncTargets.Count)))
|
||||||
{
|
{
|
||||||
pushOp.PopOps.Add(op, Local());
|
pushOpInfo.Consumers.Add(current, Local());
|
||||||
target.Predecessors.Add(current);
|
target.Predecessors.Add(current);
|
||||||
|
current.Successors.Add(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Push the block itself into the work "queue" (well, it's a stack)
|
// Push the block itself into the work queue for processing.
|
||||||
// for processing.
|
|
||||||
Push(new PathBlockState(blocks[targetAddress]));
|
Push(new PathBlockState(blocks[targetAddress]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// By adding them in descending order (sorted by address), we process the blocks
|
||||||
|
// in order (of ascending address), since we work with a LIFO.
|
||||||
|
foreach (Block possibleTarget in current.Successors.OrderByDescending(x => x.Address))
|
||||||
|
{
|
||||||
|
if (!hasNext || possibleTarget != current.Successors[0])
|
||||||
|
{
|
||||||
|
Push(new PathBlockState(possibleTarget));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue