Move solution and projects to src
This commit is contained in:
parent
cd124bda58
commit
cee7121058
3466 changed files with 55 additions and 55 deletions
168
src/Ryujinx.Graphics.Shader/Decoders/Block.cs
Normal file
168
src/Ryujinx.Graphics.Shader/Decoders/Block.cs
Normal file
|
@ -0,0 +1,168 @@
|
|||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
class PushOpInfo
|
||||
{
|
||||
public InstOp Op { get; }
|
||||
public Dictionary<Block, Operand> Consumers;
|
||||
|
||||
public PushOpInfo(InstOp op)
|
||||
{
|
||||
Op = op;
|
||||
Consumers = new Dictionary<Block, Operand>();
|
||||
}
|
||||
}
|
||||
|
||||
readonly struct SyncTarget
|
||||
{
|
||||
public PushOpInfo PushOpInfo { get; }
|
||||
public int PushOpId { get; }
|
||||
|
||||
public SyncTarget(PushOpInfo pushOpInfo, int pushOpId)
|
||||
{
|
||||
PushOpInfo = pushOpInfo;
|
||||
PushOpId = pushOpId;
|
||||
}
|
||||
}
|
||||
|
||||
class Block
|
||||
{
|
||||
public ulong Address { get; set; }
|
||||
public ulong EndAddress { get; set; }
|
||||
|
||||
public List<Block> Predecessors { get; }
|
||||
public List<Block> Successors { get; }
|
||||
|
||||
public List<InstOp> OpCodes { get; }
|
||||
public List<PushOpInfo> PushOpCodes { get; }
|
||||
public Dictionary<ulong, SyncTarget> SyncTargets { get; }
|
||||
|
||||
public Block(ulong address)
|
||||
{
|
||||
Address = address;
|
||||
|
||||
Predecessors = new List<Block>();
|
||||
Successors = new List<Block>();
|
||||
|
||||
OpCodes = new List<InstOp>();
|
||||
PushOpCodes = new List<PushOpInfo>();
|
||||
SyncTargets = new Dictionary<ulong, SyncTarget>();
|
||||
}
|
||||
|
||||
public void Split(Block rightBlock)
|
||||
{
|
||||
int splitIndex = BinarySearch(OpCodes, rightBlock.Address);
|
||||
|
||||
if (OpCodes[splitIndex].Address < rightBlock.Address)
|
||||
{
|
||||
splitIndex++;
|
||||
}
|
||||
|
||||
int splitCount = OpCodes.Count - splitIndex;
|
||||
if (splitCount <= 0)
|
||||
{
|
||||
throw new ArgumentException("Can't split at right block address.");
|
||||
}
|
||||
|
||||
rightBlock.EndAddress = EndAddress;
|
||||
rightBlock.Successors.AddRange(Successors);
|
||||
rightBlock.Predecessors.Add(this);
|
||||
|
||||
EndAddress = rightBlock.Address;
|
||||
|
||||
Successors.Clear();
|
||||
Successors.Add(rightBlock);
|
||||
|
||||
// Move ops.
|
||||
rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount));
|
||||
|
||||
OpCodes.RemoveRange(splitIndex, splitCount);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
foreach ((ulong key, SyncTarget value) in SyncTargets)
|
||||
{
|
||||
rightBlock.SyncTargets.Add(key, value);
|
||||
}
|
||||
|
||||
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<InstOp> opCodes, ulong address)
|
||||
{
|
||||
int left = 0;
|
||||
int middle = 0;
|
||||
int right = opCodes.Count - 1;
|
||||
|
||||
while (left <= right)
|
||||
{
|
||||
int size = right - left;
|
||||
|
||||
middle = left + (size >> 1);
|
||||
|
||||
InstOp opCode = opCodes[middle];
|
||||
|
||||
if (address == opCode.Address)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (address < opCode.Address)
|
||||
{
|
||||
right = middle - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
left = middle + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return middle;
|
||||
}
|
||||
|
||||
public InstOp GetLastOp()
|
||||
{
|
||||
if (OpCodes.Count != 0)
|
||||
{
|
||||
return OpCodes[OpCodes.Count - 1];
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public bool HasNext()
|
||||
{
|
||||
InstOp lastOp = GetLastOp();
|
||||
return OpCodes.Count != 0 && !Decoder.IsUnconditionalBranch(ref lastOp);
|
||||
}
|
||||
|
||||
public void AddPushOp(InstOp op)
|
||||
{
|
||||
PushOpCodes.Add(new PushOpInfo(op));
|
||||
}
|
||||
}
|
||||
}
|
48
src/Ryujinx.Graphics.Shader/Decoders/DecodedFunction.cs
Normal file
48
src/Ryujinx.Graphics.Shader/Decoders/DecodedFunction.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
class DecodedFunction
|
||||
{
|
||||
private readonly HashSet<DecodedFunction> _callers;
|
||||
|
||||
public bool IsCompilerGenerated => Type != FunctionType.User;
|
||||
public FunctionType Type { get; set; }
|
||||
public int Id { get; set; }
|
||||
|
||||
public ulong Address { get; }
|
||||
public Block[] Blocks { get; private set; }
|
||||
|
||||
public DecodedFunction(ulong address)
|
||||
{
|
||||
Address = address;
|
||||
_callers = new HashSet<DecodedFunction>();
|
||||
Type = FunctionType.User;
|
||||
Id = -1;
|
||||
}
|
||||
|
||||
public void SetBlocks(Block[] blocks)
|
||||
{
|
||||
if (Blocks != null)
|
||||
{
|
||||
throw new InvalidOperationException("Blocks have already been set.");
|
||||
}
|
||||
|
||||
Blocks = blocks;
|
||||
}
|
||||
|
||||
public void AddCaller(DecodedFunction caller)
|
||||
{
|
||||
_callers.Add(caller);
|
||||
}
|
||||
|
||||
public void RemoveCaller(DecodedFunction caller)
|
||||
{
|
||||
if (_callers.Remove(caller) && _callers.Count == 0)
|
||||
{
|
||||
Type = FunctionType.Unused;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
57
src/Ryujinx.Graphics.Shader/Decoders/DecodedProgram.cs
Normal file
57
src/Ryujinx.Graphics.Shader/Decoders/DecodedProgram.cs
Normal file
|
@ -0,0 +1,57 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
readonly struct DecodedProgram : IEnumerable<DecodedFunction>
|
||||
{
|
||||
public DecodedFunction MainFunction { get; }
|
||||
private readonly IReadOnlyDictionary<ulong, DecodedFunction> _functions;
|
||||
private readonly List<DecodedFunction> _functionsWithId;
|
||||
public int FunctionsWithIdCount => _functionsWithId.Count;
|
||||
|
||||
public DecodedProgram(DecodedFunction mainFunction, IReadOnlyDictionary<ulong, DecodedFunction> functions)
|
||||
{
|
||||
MainFunction = mainFunction;
|
||||
_functions = functions;
|
||||
_functionsWithId = new List<DecodedFunction>();
|
||||
}
|
||||
|
||||
public DecodedFunction GetFunctionByAddress(ulong address)
|
||||
{
|
||||
if (_functions.TryGetValue(address, out DecodedFunction function))
|
||||
{
|
||||
return function;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public DecodedFunction GetFunctionById(int id)
|
||||
{
|
||||
if ((uint)id >= (uint)_functionsWithId.Count)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(id));
|
||||
}
|
||||
|
||||
return _functionsWithId[id];
|
||||
}
|
||||
|
||||
public void AddFunctionAndSetId(DecodedFunction function)
|
||||
{
|
||||
function.Id = _functionsWithId.Count;
|
||||
_functionsWithId.Add(function);
|
||||
}
|
||||
|
||||
public IEnumerator<DecodedFunction> GetEnumerator()
|
||||
{
|
||||
return _functions.Values.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
765
src/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
Normal file
765
src/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
Normal file
|
@ -0,0 +1,765 @@
|
|||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
static class Decoder
|
||||
{
|
||||
public static DecodedProgram Decode(ShaderConfig config, ulong startAddress)
|
||||
{
|
||||
Queue<DecodedFunction> functionsQueue = new Queue<DecodedFunction>();
|
||||
Dictionary<ulong, DecodedFunction> functionsVisited = new Dictionary<ulong, DecodedFunction>();
|
||||
|
||||
DecodedFunction EnqueueFunction(ulong address)
|
||||
{
|
||||
if (!functionsVisited.TryGetValue(address, out DecodedFunction function))
|
||||
{
|
||||
functionsVisited.Add(address, function = new DecodedFunction(address));
|
||||
functionsQueue.Enqueue(function);
|
||||
}
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
DecodedFunction mainFunction = EnqueueFunction(0);
|
||||
|
||||
while (functionsQueue.TryDequeue(out DecodedFunction currentFunction))
|
||||
{
|
||||
List<Block> blocks = new List<Block>();
|
||||
Queue<Block> workQueue = new Queue<Block>();
|
||||
Dictionary<ulong, Block> visited = new Dictionary<ulong, Block>();
|
||||
|
||||
Block GetBlock(ulong blkAddress)
|
||||
{
|
||||
if (!visited.TryGetValue(blkAddress, out Block block))
|
||||
{
|
||||
block = new Block(blkAddress);
|
||||
|
||||
workQueue.Enqueue(block);
|
||||
visited.Add(blkAddress, block);
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
GetBlock(currentFunction.Address);
|
||||
|
||||
bool hasNewTarget;
|
||||
|
||||
do
|
||||
{
|
||||
while (workQueue.TryDequeue(out Block currBlock))
|
||||
{
|
||||
// Check if the current block is inside another block.
|
||||
if (BinarySearch(blocks, currBlock.Address, out int nBlkIndex))
|
||||
{
|
||||
Block nBlock = blocks[nBlkIndex];
|
||||
|
||||
if (nBlock.Address == currBlock.Address)
|
||||
{
|
||||
throw new InvalidOperationException("Found duplicate block address on the list.");
|
||||
}
|
||||
|
||||
nBlock.Split(currBlock);
|
||||
blocks.Insert(nBlkIndex + 1, currBlock);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we have a block after the current one, set the limit address.
|
||||
ulong limitAddress = ulong.MaxValue;
|
||||
|
||||
if (nBlkIndex != blocks.Count)
|
||||
{
|
||||
Block nBlock = blocks[nBlkIndex];
|
||||
|
||||
int nextIndex = nBlkIndex + 1;
|
||||
|
||||
if (nBlock.Address < currBlock.Address && nextIndex < blocks.Count)
|
||||
{
|
||||
limitAddress = blocks[nextIndex].Address;
|
||||
}
|
||||
else if (nBlock.Address > currBlock.Address)
|
||||
{
|
||||
limitAddress = blocks[nBlkIndex].Address;
|
||||
}
|
||||
}
|
||||
|
||||
FillBlock(config, currBlock, limitAddress, startAddress);
|
||||
|
||||
if (currBlock.OpCodes.Count != 0)
|
||||
{
|
||||
// We should have blocks for all possible branch targets,
|
||||
// including those from PBK/PCNT/SSY instructions.
|
||||
foreach (PushOpInfo pushOp in currBlock.PushOpCodes)
|
||||
{
|
||||
GetBlock(pushOp.Op.GetAbsoluteAddress());
|
||||
}
|
||||
|
||||
// Set child blocks. "Branch" is the block the branch instruction
|
||||
// points to (when taken), "Next" is the block at the next address,
|
||||
// executed when the branch is not taken. For Unconditional Branches
|
||||
// or end of program, Next is null.
|
||||
InstOp lastOp = currBlock.GetLastOp();
|
||||
|
||||
if (lastOp.Name == InstName.Cal)
|
||||
{
|
||||
EnqueueFunction(lastOp.GetAbsoluteAddress()).AddCaller(currentFunction);
|
||||
}
|
||||
else if (lastOp.Name == InstName.Bra)
|
||||
{
|
||||
Block succBlock = GetBlock(lastOp.GetAbsoluteAddress());
|
||||
currBlock.Successors.Add(succBlock);
|
||||
succBlock.Predecessors.Add(currBlock);
|
||||
}
|
||||
|
||||
if (!IsUnconditionalBranch(ref lastOp))
|
||||
{
|
||||
Block succBlock = GetBlock(currBlock.EndAddress);
|
||||
currBlock.Successors.Insert(0, succBlock);
|
||||
succBlock.Predecessors.Add(currBlock);
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the new block on the list (sorted by address).
|
||||
if (blocks.Count != 0)
|
||||
{
|
||||
Block nBlock = blocks[nBlkIndex];
|
||||
|
||||
blocks.Insert(nBlkIndex + (nBlock.Address < currBlock.Address ? 1 : 0), currBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
blocks.Add(currBlock);
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate SSY/PBK addresses into their uses (SYNC/BRK).
|
||||
foreach (Block block in blocks.Where(x => x.PushOpCodes.Count != 0))
|
||||
{
|
||||
for (int pushOpIndex = 0; pushOpIndex < block.PushOpCodes.Count; pushOpIndex++)
|
||||
{
|
||||
PropagatePushOp(visited, block, pushOpIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to find targets for BRX (indirect branch) instructions.
|
||||
hasNewTarget = FindBrxTargets(config, blocks, GetBlock);
|
||||
|
||||
// If we discovered new branch targets from the BRX instruction,
|
||||
// we need another round of decoding to decode the new blocks.
|
||||
// Additionally, we may have more SSY/PBK targets to propagate,
|
||||
// and new BRX instructions.
|
||||
}
|
||||
while (hasNewTarget);
|
||||
|
||||
currentFunction.SetBlocks(blocks.ToArray());
|
||||
}
|
||||
|
||||
return new DecodedProgram(mainFunction, functionsVisited);
|
||||
}
|
||||
|
||||
private static bool BinarySearch(List<Block> blocks, ulong address, out int index)
|
||||
{
|
||||
index = 0;
|
||||
|
||||
int left = 0;
|
||||
int right = blocks.Count - 1;
|
||||
|
||||
while (left <= right)
|
||||
{
|
||||
int size = right - left;
|
||||
|
||||
int middle = left + (size >> 1);
|
||||
|
||||
Block block = blocks[middle];
|
||||
|
||||
index = middle;
|
||||
|
||||
if (address >= block.Address && address < block.EndAddress)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (address < block.Address)
|
||||
{
|
||||
right = middle - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
left = middle + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void FillBlock(ShaderConfig config, Block block, ulong limitAddress, ulong startAddress)
|
||||
{
|
||||
IGpuAccessor gpuAccessor = config.GpuAccessor;
|
||||
|
||||
ulong address = block.Address;
|
||||
int bufferOffset = 0;
|
||||
ReadOnlySpan<ulong> buffer = ReadOnlySpan<ulong>.Empty;
|
||||
|
||||
InstOp op = default;
|
||||
|
||||
do
|
||||
{
|
||||
if (address + 7 >= limitAddress)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Ignore scheduling instructions, which are written every 32 bytes.
|
||||
if ((address & 0x1f) == 0)
|
||||
{
|
||||
address += 8;
|
||||
bufferOffset++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bufferOffset >= buffer.Length)
|
||||
{
|
||||
buffer = gpuAccessor.GetCode(startAddress + address, 8);
|
||||
bufferOffset = 0;
|
||||
}
|
||||
|
||||
ulong opCode = buffer[bufferOffset++];
|
||||
|
||||
op = InstTable.GetOp(address, opCode);
|
||||
|
||||
if (op.Props.HasFlag(InstProps.TexB))
|
||||
{
|
||||
config.SetUsedFeature(FeatureFlags.Bindless);
|
||||
}
|
||||
|
||||
if (op.Name == InstName.Ald || op.Name == InstName.Ast || op.Name == InstName.Ipa)
|
||||
{
|
||||
SetUserAttributeUses(config, op.Name, opCode);
|
||||
}
|
||||
else if (op.Name == InstName.Pbk || op.Name == InstName.Pcnt || op.Name == InstName.Ssy)
|
||||
{
|
||||
block.AddPushOp(op);
|
||||
}
|
||||
|
||||
block.OpCodes.Add(op);
|
||||
|
||||
address += 8;
|
||||
}
|
||||
while (!op.Props.HasFlag(InstProps.Bra));
|
||||
|
||||
block.EndAddress = address;
|
||||
}
|
||||
|
||||
private static void SetUserAttributeUses(ShaderConfig config, InstName name, ulong opCode)
|
||||
{
|
||||
int offset;
|
||||
int count = 1;
|
||||
bool isStore = false;
|
||||
bool indexed = false;
|
||||
bool perPatch = false;
|
||||
|
||||
if (name == InstName.Ast)
|
||||
{
|
||||
InstAst opAst = new InstAst(opCode);
|
||||
count = (int)opAst.AlSize + 1;
|
||||
offset = opAst.Imm11;
|
||||
indexed = opAst.Phys;
|
||||
perPatch = opAst.P;
|
||||
isStore = true;
|
||||
}
|
||||
else if (name == InstName.Ald)
|
||||
{
|
||||
InstAld opAld = new InstAld(opCode);
|
||||
count = (int)opAld.AlSize + 1;
|
||||
offset = opAld.Imm11;
|
||||
indexed = opAld.Phys;
|
||||
perPatch = opAld.P;
|
||||
isStore = opAld.O;
|
||||
}
|
||||
else /* if (name == InstName.Ipa) */
|
||||
{
|
||||
InstIpa opIpa = new InstIpa(opCode);
|
||||
offset = opIpa.Imm10;
|
||||
indexed = opIpa.Idx;
|
||||
}
|
||||
|
||||
if (indexed)
|
||||
{
|
||||
if (isStore)
|
||||
{
|
||||
config.SetAllOutputUserAttributes();
|
||||
config.SetUsedFeature(FeatureFlags.OaIndexing);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.SetAllInputUserAttributes();
|
||||
config.SetUsedFeature(FeatureFlags.IaIndexing);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int elemIndex = 0; elemIndex < count; elemIndex++)
|
||||
{
|
||||
int attr = offset + elemIndex * 4;
|
||||
|
||||
if (perPatch)
|
||||
{
|
||||
if (attr >= AttributeConsts.UserAttributePerPatchBase && attr < AttributeConsts.UserAttributePerPatchEnd)
|
||||
{
|
||||
int userAttr = attr - AttributeConsts.UserAttributePerPatchBase;
|
||||
int index = userAttr / 16;
|
||||
|
||||
if (isStore)
|
||||
{
|
||||
config.SetOutputUserAttributePerPatch(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.SetInputUserAttributePerPatch(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd)
|
||||
{
|
||||
int userAttr = attr - AttributeConsts.UserAttributeBase;
|
||||
int index = userAttr / 16;
|
||||
|
||||
if (isStore)
|
||||
{
|
||||
config.SetOutputUserAttribute(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.SetInputUserAttribute(index, (userAttr >> 2) & 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isStore &&
|
||||
(attr == AttributeConsts.FogCoord ||
|
||||
(attr >= AttributeConsts.FrontColorDiffuseR && attr < AttributeConsts.ClipDistance0) ||
|
||||
(attr >= AttributeConsts.TexCoordBase && attr < AttributeConsts.TexCoordEnd)))
|
||||
{
|
||||
config.SetUsedFeature(FeatureFlags.FixedFuncAttr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsUnconditionalBranch(ref InstOp op)
|
||||
{
|
||||
return IsUnconditional(ref op) && op.Props.HasFlag(InstProps.Bra);
|
||||
}
|
||||
|
||||
private static bool IsUnconditional(ref InstOp op)
|
||||
{
|
||||
InstConditional condOp = new InstConditional(op.RawOpCode);
|
||||
|
||||
if ((op.Name == InstName.Bra || op.Name == InstName.Exit) && condOp.Ccc != Ccc.T)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return condOp.Pred == RegisterConsts.PredicateTrueIndex && !condOp.PredInv;
|
||||
}
|
||||
|
||||
private static bool FindBrxTargets(ShaderConfig config, IEnumerable<Block> blocks, Func<ulong, Block> getBlock)
|
||||
{
|
||||
bool hasNewTarget = false;
|
||||
|
||||
foreach (Block block in blocks)
|
||||
{
|
||||
InstOp lastOp = block.GetLastOp();
|
||||
bool hasNext = block.HasNext();
|
||||
|
||||
if (lastOp.Name == InstName.Brx && block.Successors.Count == (hasNext ? 1 : 0))
|
||||
{
|
||||
HashSet<ulong> visited = new HashSet<ulong>();
|
||||
|
||||
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.ConstantBuffer1Read(cbBaseOffset + i * 4);
|
||||
ulong targetAddress = baseOffset + targetOffset;
|
||||
|
||||
if (visited.Add(targetAddress))
|
||||
{
|
||||
Block target = getBlock(targetAddress);
|
||||
target.Predecessors.Add(block);
|
||||
block.Successors.Add(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasNewTarget;
|
||||
}
|
||||
|
||||
private static (int, int) FindBrxTargetRange(Block block, int brxReg)
|
||||
{
|
||||
// Try to match the following pattern:
|
||||
//
|
||||
// IMNMX.U32 Rx, Rx, UpperBound, PT
|
||||
// SHL Rx, Rx, 0x2
|
||||
// LDC Rx, c[0x1][Rx+BaseOffset]
|
||||
//
|
||||
// Here, Rx is an arbitrary register, "UpperBound" and "BaseOffset" are constants.
|
||||
// The above pattern is assumed to be generated by the compiler before BRX,
|
||||
// as the instruction is usually used to implement jump tables for switch statement optimizations.
|
||||
// On a successful match, "BaseOffset" is the offset in bytes where the jump offsets are
|
||||
// located on the constant buffer, and "UpperBound" is the total number of offsets for the BRX, minus 1.
|
||||
|
||||
HashSet<Block> visited = new HashSet<Block>();
|
||||
|
||||
var ldcLocation = FindFirstRegWrite(visited, new BlockLocation(block, block.OpCodes.Count - 1), brxReg);
|
||||
if (ldcLocation.Block == null || ldcLocation.Block.OpCodes[ldcLocation.Index].Name != InstName.Ldc)
|
||||
{
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
GetOp<InstLdc>(ldcLocation, out var opLdc);
|
||||
|
||||
if (opLdc.CbufSlot != 1 || opLdc.AddressMode != 0)
|
||||
{
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
var shlLocation = FindFirstRegWrite(visited, ldcLocation, opLdc.SrcA);
|
||||
if (shlLocation.Block == null || !shlLocation.IsImmInst(InstName.Shl))
|
||||
{
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
GetOp<InstShlI>(shlLocation, out var opShl);
|
||||
|
||||
if (opShl.Imm20 != 2)
|
||||
{
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
var imnmxLocation = FindFirstRegWrite(visited, shlLocation, opShl.SrcA);
|
||||
if (imnmxLocation.Block == null || !imnmxLocation.IsImmInst(InstName.Imnmx))
|
||||
{
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
GetOp<InstImnmxI>(imnmxLocation, out var opImnmx);
|
||||
|
||||
if (opImnmx.Signed || opImnmx.SrcPred != RegisterConsts.PredicateTrueIndex || opImnmx.SrcPredInv)
|
||||
{
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
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 readonly struct BlockLocation
|
||||
{
|
||||
public Block Block { get; }
|
||||
public int Index { get; }
|
||||
|
||||
public BlockLocation(Block block, int index)
|
||||
{
|
||||
Block = block;
|
||||
Index = index;
|
||||
}
|
||||
|
||||
public bool IsImmInst(InstName name)
|
||||
{
|
||||
InstOp op = Block.OpCodes[Index];
|
||||
return op.Name == name && op.Props.HasFlag(InstProps.Ib);
|
||||
}
|
||||
}
|
||||
|
||||
private static BlockLocation FindFirstRegWrite(HashSet<Block> visited, BlockLocation location, int regIndex)
|
||||
{
|
||||
Queue<BlockLocation> toVisit = new Queue<BlockLocation>();
|
||||
toVisit.Enqueue(location);
|
||||
visited.Add(location.Block);
|
||||
|
||||
while (toVisit.TryDequeue(out var currentLocation))
|
||||
{
|
||||
Block block = currentLocation.Block;
|
||||
for (int i = currentLocation.Index - 1; i >= 0; i--)
|
||||
{
|
||||
if (WritesToRegister(block.OpCodes[i], regIndex))
|
||||
{
|
||||
return new BlockLocation(block, i);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Block predecessor in block.Predecessors)
|
||||
{
|
||||
if (visited.Add(predecessor))
|
||||
{
|
||||
toVisit.Enqueue(new BlockLocation(predecessor, predecessor.OpCodes.Count));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new BlockLocation(null, 0);
|
||||
}
|
||||
|
||||
private static bool WritesToRegister(InstOp op, int regIndex)
|
||||
{
|
||||
// Predicate instruction only ever writes to predicate, so we shouldn't check those.
|
||||
if ((op.Props & (InstProps.Rd | InstProps.Rd2)) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (op.Props.HasFlag(InstProps.Rd2) && (byte)(op.RawOpCode >> 28) == regIndex)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return (byte)op.RawOpCode == regIndex;
|
||||
}
|
||||
|
||||
private enum MergeType
|
||||
{
|
||||
Brk,
|
||||
Cont,
|
||||
Sync
|
||||
}
|
||||
|
||||
private struct PathBlockState
|
||||
{
|
||||
public Block Block { get; }
|
||||
|
||||
private enum RestoreType
|
||||
{
|
||||
None,
|
||||
PopPushOp,
|
||||
PushBranchOp
|
||||
}
|
||||
|
||||
private RestoreType _restoreType;
|
||||
|
||||
private ulong _restoreValue;
|
||||
private MergeType _restoreMergeType;
|
||||
|
||||
public bool ReturningFromVisit => _restoreType != RestoreType.None;
|
||||
|
||||
public PathBlockState(Block block)
|
||||
{
|
||||
Block = block;
|
||||
_restoreType = RestoreType.None;
|
||||
_restoreValue = 0;
|
||||
_restoreMergeType = default;
|
||||
}
|
||||
|
||||
public PathBlockState(int oldStackSize)
|
||||
{
|
||||
Block = null;
|
||||
_restoreType = RestoreType.PopPushOp;
|
||||
_restoreValue = (ulong)oldStackSize;
|
||||
_restoreMergeType = default;
|
||||
}
|
||||
|
||||
public PathBlockState(ulong syncAddress, MergeType mergeType)
|
||||
{
|
||||
Block = null;
|
||||
_restoreType = RestoreType.PushBranchOp;
|
||||
_restoreValue = syncAddress;
|
||||
_restoreMergeType = mergeType;
|
||||
}
|
||||
|
||||
public void RestoreStackState(Stack<(ulong, MergeType)> branchStack)
|
||||
{
|
||||
if (_restoreType == RestoreType.PushBranchOp)
|
||||
{
|
||||
branchStack.Push((_restoreValue, _restoreMergeType));
|
||||
}
|
||||
else if (_restoreType == RestoreType.PopPushOp)
|
||||
{
|
||||
while (branchStack.Count > (uint)_restoreValue)
|
||||
{
|
||||
branchStack.Pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void PropagatePushOp(Dictionary<ulong, Block> blocks, Block currBlock, int pushOpIndex)
|
||||
{
|
||||
PushOpInfo pushOpInfo = currBlock.PushOpCodes[pushOpIndex];
|
||||
InstOp pushOp = pushOpInfo.Op;
|
||||
|
||||
Block target = blocks[pushOp.GetAbsoluteAddress()];
|
||||
|
||||
Stack<PathBlockState> workQueue = new Stack<PathBlockState>();
|
||||
HashSet<Block> visited = new HashSet<Block>();
|
||||
Stack<(ulong, MergeType)> branchStack = new Stack<(ulong, MergeType)>();
|
||||
|
||||
void Push(PathBlockState pbs)
|
||||
{
|
||||
// When block is null, this means we are pushing a restore operation.
|
||||
// Restore operations are used to undo the work done inside a block
|
||||
// when we return from it, for example it pops addresses pushed by
|
||||
// SSY/PBK instructions inside the block, and pushes addresses poped
|
||||
// by SYNC/BRK.
|
||||
// For blocks, if it's already visited, we just ignore to avoid going
|
||||
// around in circles and getting stuck here.
|
||||
if (pbs.Block == null || !visited.Contains(pbs.Block))
|
||||
{
|
||||
workQueue.Push(pbs);
|
||||
}
|
||||
}
|
||||
|
||||
Push(new PathBlockState(currBlock));
|
||||
|
||||
while (workQueue.TryPop(out PathBlockState pbs))
|
||||
{
|
||||
if (pbs.ReturningFromVisit)
|
||||
{
|
||||
pbs.RestoreStackState(branchStack);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
Block current = pbs.Block;
|
||||
|
||||
// If the block was already processed, we just ignore it, otherwise
|
||||
// we would push the same child blocks of an already processed block,
|
||||
// and go around in circles until memory is exhausted.
|
||||
if (!visited.Add(current))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int pushOpsCount = current.PushOpCodes.Count;
|
||||
if (pushOpsCount != 0)
|
||||
{
|
||||
Push(new PathBlockState(branchStack.Count));
|
||||
|
||||
for (int index = pushOpIndex; index < pushOpsCount; index++)
|
||||
{
|
||||
InstOp currentPushOp = current.PushOpCodes[index].Op;
|
||||
MergeType pushMergeType = GetMergeTypeFromPush(currentPushOp.Name);
|
||||
branchStack.Push((currentPushOp.GetAbsoluteAddress(), pushMergeType));
|
||||
}
|
||||
}
|
||||
|
||||
pushOpIndex = 0;
|
||||
|
||||
bool hasNext = current.HasNext();
|
||||
if (hasNext)
|
||||
{
|
||||
Push(new PathBlockState(current.Successors[0]));
|
||||
}
|
||||
|
||||
InstOp lastOp = current.GetLastOp();
|
||||
if (IsPopBranch(lastOp.Name))
|
||||
{
|
||||
MergeType popMergeType = GetMergeTypeFromPop(lastOp.Name);
|
||||
|
||||
bool found = true;
|
||||
ulong targetAddress = 0UL;
|
||||
MergeType mergeType;
|
||||
|
||||
do
|
||||
{
|
||||
if (branchStack.Count == 0)
|
||||
{
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
|
||||
(targetAddress, mergeType) = branchStack.Pop();
|
||||
|
||||
// Push the target address (this will be used to push the address
|
||||
// back into the PBK/PCNT/SSY stack when we return from that block),
|
||||
Push(new PathBlockState(targetAddress, mergeType));
|
||||
}
|
||||
while (mergeType != popMergeType);
|
||||
|
||||
// Make sure we found the correct address,
|
||||
// the push and pop instruction types must match, so:
|
||||
// - BRK can only consume addresses pushed by PBK.
|
||||
// - CONT can only consume addresses pushed by PCNT.
|
||||
// - SYNC can only consume addresses pushed by SSY.
|
||||
if (found)
|
||||
{
|
||||
if (branchStack.Count == 0)
|
||||
{
|
||||
// If the entire stack was consumed, then the current pop instruction
|
||||
// just consumed the address from our push instruction.
|
||||
if (current.SyncTargets.TryAdd(pushOp.Address, new SyncTarget(pushOpInfo, current.SyncTargets.Count)))
|
||||
{
|
||||
pushOpInfo.Consumers.Add(current, Local());
|
||||
target.Predecessors.Add(current);
|
||||
current.Successors.Add(target);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Push the block itself into the work queue for processing.
|
||||
Push(new PathBlockState(blocks[targetAddress]));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// By adding them in descending order (sorted by address), we process the blocks
|
||||
// in order (of ascending address), since we work with a LIFO.
|
||||
foreach (Block possibleTarget in current.Successors.OrderByDescending(x => x.Address))
|
||||
{
|
||||
if (!hasNext || possibleTarget != current.Successors[0])
|
||||
{
|
||||
Push(new PathBlockState(possibleTarget));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsPopBranch(InstName name)
|
||||
{
|
||||
return name == InstName.Brk || name == InstName.Cont || name == InstName.Sync;
|
||||
}
|
||||
|
||||
private static MergeType GetMergeTypeFromPush(InstName name)
|
||||
{
|
||||
return name switch
|
||||
{
|
||||
InstName.Pbk => MergeType.Brk,
|
||||
InstName.Pcnt => MergeType.Cont,
|
||||
_ => MergeType.Sync
|
||||
};
|
||||
}
|
||||
|
||||
private static MergeType GetMergeTypeFromPop(InstName name)
|
||||
{
|
||||
return name switch
|
||||
{
|
||||
InstName.Brk => MergeType.Brk,
|
||||
InstName.Cont => MergeType.Cont,
|
||||
_ => MergeType.Sync
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
10
src/Ryujinx.Graphics.Shader/Decoders/FunctionType.cs
Normal file
10
src/Ryujinx.Graphics.Shader/Decoders/FunctionType.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum FunctionType : byte
|
||||
{
|
||||
User,
|
||||
Unused,
|
||||
BuiltInFSIBegin,
|
||||
BuiltInFSIEnd
|
||||
}
|
||||
}
|
5383
src/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
Normal file
5383
src/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
Normal file
File diff suppressed because it is too large
Load diff
188
src/Ryujinx.Graphics.Shader/Decoders/InstName.cs
Normal file
188
src/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
src/Ryujinx.Graphics.Shader/Decoders/InstOp.cs
Normal file
27
src/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);
|
||||
}
|
||||
}
|
||||
}
|
28
src/Ryujinx.Graphics.Shader/Decoders/InstProps.cs
Normal file
28
src/Ryujinx.Graphics.Shader/Decoders/InstProps.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum InstProps : ushort
|
||||
{
|
||||
None = 0,
|
||||
Rd = 1 << 0,
|
||||
Rd2 = 1 << 1,
|
||||
Ra = 1 << 2,
|
||||
Rb = 1 << 3,
|
||||
Rb2 = 1 << 4,
|
||||
Ib = 1 << 5,
|
||||
Rc = 1 << 6,
|
||||
|
||||
Pd = 1 << 7,
|
||||
LPd = 2 << 7,
|
||||
SPd = 3 << 7,
|
||||
TPd = 4 << 7,
|
||||
VPd = 5 << 7,
|
||||
PdMask = 7 << 7,
|
||||
|
||||
Pdn = 1 << 10,
|
||||
Ps = 1 << 11,
|
||||
Tex = 1 << 12,
|
||||
TexB = 1 << 13,
|
||||
Bra = 1 << 14,
|
||||
NoPred = 1 << 15
|
||||
}
|
||||
}
|
390
src/Ryujinx.Graphics.Shader/Decoders/InstTable.cs
Normal file
390
src/Ryujinx.Graphics.Shader/Decoders/InstTable.cs
Normal file
|
@ -0,0 +1,390 @@
|
|||
using Ryujinx.Graphics.Shader.Instructions;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
static class InstTable
|
||||
{
|
||||
private const int EncodingBits = 14;
|
||||
|
||||
private readonly 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.Rb2 | 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 | InstProps.VPd);
|
||||
Add("1111000010101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bar, InstEmit.Bar, InstProps.Ra | InstProps.Ps);
|
||||
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, InstProps.Bra);
|
||||
Add("0101000010011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cset, InstEmit.Cset, InstProps.Rd | InstProps.Ps);
|
||||
Add("0101000010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Csetp, InstEmit.Csetp, InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
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 | InstProps.Ps);
|
||||
Add("0011100x01010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmnmx, InstEmit.DmnmxI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Ps);
|
||||
Add("0100110001010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmnmx, InstEmit.DmnmxC, InstProps.Rd | InstProps.Ra | InstProps.Ps);
|
||||
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 | InstProps.Ps);
|
||||
Add("0011001x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dset, InstEmit.DsetI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Ps);
|
||||
Add("010010010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dset, InstEmit.DsetC, InstProps.Rd | InstProps.Ra | InstProps.Ps);
|
||||
Add("010110111000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dsetp, InstEmit.DsetpR, InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
Add("0011011x1000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dsetp, InstEmit.DsetpI, InstProps.Ra | InstProps.Ib | InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
Add("010010111000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dsetp, InstEmit.DsetpC, InstProps.Ra | InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
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);
|
||||
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 | InstProps.Ps);
|
||||
Add("0011100x01100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmnmx, InstEmit.FmnmxI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Ps);
|
||||
Add("0100110001100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmnmx, InstEmit.FmnmxC, InstProps.Rd | InstProps.Ra | InstProps.Ps);
|
||||
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 | InstProps.Ps);
|
||||
Add("0011000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fset, InstEmit.FsetI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Ps);
|
||||
Add("01001000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fset, InstEmit.FsetC, InstProps.Rd | InstProps.Ra | InstProps.Ps);
|
||||
Add("010110111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fsetp, InstEmit.FsetpR, InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
Add("0011011x1011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fsetp, InstEmit.FsetpI, InstProps.Ra | InstProps.Ib | InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
Add("010010111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fsetp, InstEmit.FsetpC, InstProps.Ra | InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
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("0010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hfma2, InstEmit.Hfma232i, InstProps.Rd | InstProps.Ra);
|
||||
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 | InstProps.Ps);
|
||||
Add("0111110x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hset2, InstEmit.Hset2I, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Ps);
|
||||
Add("0111110x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hset2, InstEmit.Hset2C, InstProps.Rd | InstProps.Ra | InstProps.Ps);
|
||||
Add("0101110100100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hsetp2, InstEmit.Hsetp2R, InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
Add("0111111x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hsetp2, InstEmit.Hsetp2I, InstProps.Ra | InstProps.Ib | InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
Add("0111111x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hsetp2, InstEmit.Hsetp2C, InstProps.Ra | InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
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 | InstProps.Ps);
|
||||
Add("0011100x00100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imnmx, InstEmit.ImnmxI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Ps);
|
||||
Add("0100110000100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imnmx, InstEmit.ImnmxC, InstProps.Rd | InstProps.Ra | InstProps.Ps);
|
||||
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 | InstProps.Ps);
|
||||
Add("0011011x0101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iset, InstEmit.IsetI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Ps);
|
||||
Add("010010110101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iset, InstEmit.IsetC, InstProps.Rd | InstProps.Ra | InstProps.Ps);
|
||||
Add("010110110110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Isetp, InstEmit.IsetpR, InstProps.Ra | InstProps.Rb | InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
Add("0011011x0110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Isetp, InstEmit.IsetpI, InstProps.Ra | InstProps.Ib | InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
Add("010010110110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Isetp, InstEmit.IsetpC, InstProps.Ra | InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
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.LPd);
|
||||
Add("0011011x11010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lea, InstEmit.LeaI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.LPd);
|
||||
Add("0100101111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lea, InstEmit.LeaC, InstProps.Rd | InstProps.Ra | InstProps.LPd);
|
||||
Add("0101101111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.LeaHi, InstEmit.LeaHiR, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc | InstProps.LPd);
|
||||
Add("000110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.LeaHi, InstEmit.LeaHiC, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.LPd);
|
||||
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.LPd);
|
||||
Add("0011100x01000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop, InstEmit.LopI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.LPd);
|
||||
Add("0100110001000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop, InstEmit.LopC, InstProps.Rd | InstProps.Ra | InstProps.LPd);
|
||||
Add("0101101111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop3, InstEmit.Lop3R, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc | InstProps.LPd);
|
||||
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 | InstProps.VPd);
|
||||
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 | InstProps.Ps);
|
||||
Add("0101000010010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Psetp, InstEmit.Psetp, InstProps.Pd | InstProps.Pdn | InstProps.Ps);
|
||||
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 | InstProps.Rb2);
|
||||
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 | InstProps.Ps);
|
||||
Add("0011100x10100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sel, InstEmit.SelI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Ps);
|
||||
Add("0100110010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sel, InstEmit.SelC, InstProps.Rd | InstProps.Ra | InstProps.Ps);
|
||||
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.LPd);
|
||||
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.SPd);
|
||||
Add("1110101x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuatomCas, InstEmit.SuatomCas, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.SPd);
|
||||
Add("1110101100010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldDB, InstEmit.SuldDB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.SPd | InstProps.TexB);
|
||||
Add("1110101100011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldD, InstEmit.SuldD, InstProps.Rd | InstProps.Ra | InstProps.SPd | InstProps.Tex);
|
||||
Add("1110101100000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldB, InstEmit.SuldB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.SPd | InstProps.TexB);
|
||||
Add("1110101100001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Suld, InstEmit.Suld, InstProps.Rd | InstProps.Ra | InstProps.SPd | InstProps.Tex);
|
||||
Add("1110101101010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuredB, InstEmit.SuredB, InstProps.Rd | InstProps.Ra | InstProps.Rc);
|
||||
Add("1110101101011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sured, InstEmit.Sured, InstProps.Rd | InstProps.Ra);
|
||||
Add("1110101100110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 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("1110101100100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SustB, InstEmit.SustB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.TexB);
|
||||
Add("1110101100101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 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.TPd | InstProps.Tex);
|
||||
Add("1101111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TexB, InstEmit.TexB, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.TPd | 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.TPd | InstProps.Tex);
|
||||
Add("11011101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TldB, InstEmit.TldB, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.TPd | 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.TPd | InstProps.Tex);
|
||||
Add("1101111011xxxxxxxxxxxxx0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tld4B, InstEmit.Tld4B, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.TPd | 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.TPd | InstProps.Tex);
|
||||
Add("1101111001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TxdB, InstEmit.TxdB, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.TPd | 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 | InstProps.VPd | InstProps.Ps);
|
||||
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 | InstProps.Ps);
|
||||
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)
|
||||
{
|
||||
ReadOnlySpan<char> encodingPart = encoding.AsSpan(0, EncodingBits);
|
||||
|
||||
int bit = encodingPart.Length - 1;
|
||||
int value = 0;
|
||||
int xMask = 0;
|
||||
int xBits = 0;
|
||||
|
||||
int[] xPos = new int[encodingPart.Length];
|
||||
|
||||
for (int index = 0; index < encodingPart.Length; index++, bit--)
|
||||
{
|
||||
char chr = encodingPart[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);
|
||||
}
|
||||
}
|
||||
}
|
36
src/Ryujinx.Graphics.Shader/Decoders/Register.cs
Normal file
36
src/Ryujinx.Graphics.Shader/Decoders/Register.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
readonly struct Register : IEquatable<Register>
|
||||
{
|
||||
public int Index { get; }
|
||||
|
||||
public RegisterType Type { get; }
|
||||
|
||||
public bool IsRZ => Type == RegisterType.Gpr && Index == RegisterConsts.RegisterZeroIndex;
|
||||
public bool IsPT => Type == RegisterType.Predicate && Index == RegisterConsts.PredicateTrueIndex;
|
||||
|
||||
public Register(int index, RegisterType type)
|
||||
{
|
||||
Index = index;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (ushort)Index | ((ushort)Type << 16);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is Register reg && Equals(reg);
|
||||
}
|
||||
|
||||
public bool Equals(Register other)
|
||||
{
|
||||
return other.Index == Index &&
|
||||
other.Type == Type;
|
||||
}
|
||||
}
|
||||
}
|
13
src/Ryujinx.Graphics.Shader/Decoders/RegisterConsts.cs
Normal file
13
src/Ryujinx.Graphics.Shader/Decoders/RegisterConsts.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
static class RegisterConsts
|
||||
{
|
||||
public const int GprsCount = 255;
|
||||
public const int PredsCount = 7;
|
||||
public const int FlagsCount = 4;
|
||||
public const int TotalCount = GprsCount + PredsCount + FlagsCount;
|
||||
|
||||
public const int RegisterZeroIndex = GprsCount;
|
||||
public const int PredicateTrueIndex = PredsCount;
|
||||
}
|
||||
}
|
9
src/Ryujinx.Graphics.Shader/Decoders/RegisterType.cs
Normal file
9
src/Ryujinx.Graphics.Shader/Decoders/RegisterType.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum RegisterType
|
||||
{
|
||||
Flag,
|
||||
Gpr,
|
||||
Predicate,
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue