[ABI] Added the possibility to use AVX512 in Compiler and FuncFrame

This commit is contained in:
kobalicek
2021-03-14 22:06:54 +01:00
parent 7836449c30
commit e822fba53e
14 changed files with 970 additions and 716 deletions

View File

@@ -48,36 +48,36 @@ jobs:
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-4.8" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-4.8" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-4.8" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-4.8" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-4.8" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-4.8" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-4.8" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-4.8" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-5" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-5" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-5" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-5" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-6" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-6" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-6" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-6" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-7" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-7" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-8" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-8" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-9" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-9" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-9" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-9" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-10" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-10" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-10" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-10" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-10" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-10" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "gcc-10" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-10" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "clang-9" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-9" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "clang-9" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-9" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "clang-9" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-9" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "clang-9" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-9" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "clang-10", arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "clang-10", arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "clang-10", arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "linux" , os: "ubuntu-latest" , cc: "clang-10", arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" } - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { title: "macos-10.15" , os: "macos-10.15" , cc: "gcc-9" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" } - { title: "macos-10.15" , os: "macos-10.15" , cc: "gcc-9" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- { title: "macos-10.15" , os: "macos-10.15" , cc: "gcc-9" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" } - { title: "macos-10.15" , os: "macos-10.15" , cc: "gcc-9" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }

View File

@@ -257,7 +257,7 @@ ASMJIT_FAVOR_SIZE Error BaseEmitter::emitProlog(const FuncFrame& frame) {
#ifdef ASMJIT_BUILD_X86 #ifdef ASMJIT_BUILD_X86
if (environment().isFamilyX86()) { if (environment().isFamilyX86()) {
x86::EmitHelper emitHelper(this, frame.isAvxEnabled()); x86::EmitHelper emitHelper(this, frame.isAvxEnabled(), frame.isAvx512Enabled());
return emitHelper.emitProlog(frame); return emitHelper.emitProlog(frame);
} }
#endif #endif
@@ -278,7 +278,7 @@ ASMJIT_FAVOR_SIZE Error BaseEmitter::emitEpilog(const FuncFrame& frame) {
#ifdef ASMJIT_BUILD_X86 #ifdef ASMJIT_BUILD_X86
if (environment().isFamilyX86()) { if (environment().isFamilyX86()) {
x86::EmitHelper emitHelper(this, frame.isAvxEnabled()); x86::EmitHelper emitHelper(this, frame.isAvxEnabled(), frame.isAvx512Enabled());
return emitHelper.emitEpilog(frame); return emitHelper.emitEpilog(frame);
} }
#endif #endif
@@ -299,7 +299,7 @@ ASMJIT_FAVOR_SIZE Error BaseEmitter::emitArgsAssignment(const FuncFrame& frame,
#ifdef ASMJIT_BUILD_X86 #ifdef ASMJIT_BUILD_X86
if (environment().isFamilyX86()) { if (environment().isFamilyX86()) {
x86::EmitHelper emitHelper(this, frame.isAvxEnabled()); x86::EmitHelper emitHelper(this, frame.isAvxEnabled(), frame.isAvx512Enabled());
return emitHelper.emitArgsAssignment(frame, args); return emitHelper.emitArgsAssignment(frame, args);
} }
#endif #endif

View File

@@ -881,6 +881,14 @@ public:
//! prolog and epilog. Function frame calculation is based on `CallConv` and //! prolog and epilog. Function frame calculation is based on `CallConv` and
//! other function attributes. //! other function attributes.
//! //!
//! SSE vs AVX vs AVX-512
//! ---------------------
//!
//! Function frame provides a way to tell prolog/epilog inserter to use AVX
//! instructions instead of SSE. Use `setAvxEnabled()` and `setAvx512Enabled()`
//! to enable AVX and/or AVX-512, respectively. Enabling AVX-512 is mostly for
//! Compiler as it would use 32 SIMD registers instead of 16 when enabled.
//!
//! Function Frame Structure //! Function Frame Structure
//! ------------------------ //! ------------------------
//! //!
@@ -922,13 +930,23 @@ public:
//! Function calls other functions (is not leaf). //! Function calls other functions (is not leaf).
kAttrHasFuncCalls = 0x00000020u, kAttrHasFuncCalls = 0x00000020u,
//! Use AVX instead of SSE for all operations (X86). //! Function uses AVX (X86).
//!
//! This flag instructs prolog and epilog emitter to use AVX instead of SSE for manipulating
//! XMM registers.
kAttrX86AvxEnabled = 0x00010000u, kAttrX86AvxEnabled = 0x00010000u,
//! Emit VZEROUPPER instruction in epilog (X86). //! Function uses AVX-512 (X86).
kAttrX86AvxCleanup = 0x00020000u, //!
//! Emit EMMS instruction in epilog (X86). //! This flag instructs Compiler register allocator to use additional 16 registers introduced
//! by AVX-512.
kAttrX86Avx512Enabled = 0x00020000u,
//! This flag instructs epilog writer to emit EMMS instruction before RET (X86).
kAttrX86MmxCleanup = 0x00040000u, kAttrX86MmxCleanup = 0x00040000u,
//! This flag instructs epilog writer to emit VZEROUPPER instruction before RET (X86).
kAttrX86AvxCleanup = 0x00080000u,
//! Function has aligned save/restore of vector registers. //! Function has aligned save/restore of vector registers.
kAttrAlignedVecSR = 0x40000000u, kAttrAlignedVecSR = 0x40000000u,
//! FuncFrame is finalized and can be used by PEI. //! FuncFrame is finalized and can be used by PEI.
@@ -1054,27 +1072,34 @@ public:
//! Sets `kFlagHasCalls` to false. //! Sets `kFlagHasCalls` to false.
inline void resetFuncCalls() noexcept { clearAttributes(kAttrHasFuncCalls); } inline void resetFuncCalls() noexcept { clearAttributes(kAttrHasFuncCalls); }
//! Tests whether the function contains AVX cleanup - 'vzeroupper' instruction in epilog. //! Tests whether the function has AVX enabled.
inline bool hasAvxCleanup() const noexcept { return hasAttribute(kAttrX86AvxCleanup); }
//! Enables AVX cleanup.
inline void setAvxCleanup() noexcept { addAttributes(kAttrX86AvxCleanup); }
//! Disables AVX cleanup.
inline void resetAvxCleanup() noexcept { clearAttributes(kAttrX86AvxCleanup); }
//! Tests whether the function contains AVX cleanup - 'vzeroupper' instruction in epilog.
inline bool isAvxEnabled() const noexcept { return hasAttribute(kAttrX86AvxEnabled); } inline bool isAvxEnabled() const noexcept { return hasAttribute(kAttrX86AvxEnabled); }
//! Enables AVX cleanup. //! Enables AVX use.
inline void setAvxEnabled() noexcept { addAttributes(kAttrX86AvxEnabled); } inline void setAvxEnabled() noexcept { addAttributes(kAttrX86AvxEnabled); }
//! Disables AVX cleanup. //! Disables AVX use.
inline void resetAvxEnabled() noexcept { clearAttributes(kAttrX86AvxEnabled); } inline void resetAvxEnabled() noexcept { clearAttributes(kAttrX86AvxEnabled); }
//! Tests whether the function contains MMX cleanup - 'emms' instruction in epilog. //! Tests whether the function has AVX-512 enabled.
inline bool isAvx512Enabled() const noexcept { return hasAttribute(kAttrX86Avx512Enabled); }
//! Enables AVX-512 use.
inline void setAvx512Enabled() noexcept { addAttributes(kAttrX86Avx512Enabled); }
//! Disables AVX-512 use.
inline void resetAvx512Enabled() noexcept { clearAttributes(kAttrX86Avx512Enabled); }
//! Tests whether the function has MMX cleanup - 'emms' instruction in epilog.
inline bool hasMmxCleanup() const noexcept { return hasAttribute(kAttrX86MmxCleanup); } inline bool hasMmxCleanup() const noexcept { return hasAttribute(kAttrX86MmxCleanup); }
//! Enables MMX cleanup. //! Enables MMX cleanup.
inline void setMmxCleanup() noexcept { addAttributes(kAttrX86MmxCleanup); } inline void setMmxCleanup() noexcept { addAttributes(kAttrX86MmxCleanup); }
//! Disables MMX cleanup. //! Disables MMX cleanup.
inline void resetMmxCleanup() noexcept { clearAttributes(kAttrX86MmxCleanup); } inline void resetMmxCleanup() noexcept { clearAttributes(kAttrX86MmxCleanup); }
//! Tests whether the function has AVX cleanup - 'vzeroupper' instruction in epilog.
inline bool hasAvxCleanup() const noexcept { return hasAttribute(kAttrX86AvxCleanup); }
//! Enables AVX cleanup.
inline void setAvxCleanup() noexcept { addAttributes(kAttrX86AvxCleanup); }
//! Disables AVX cleanup.
inline void resetAvxCleanup() noexcept { clearAttributes(kAttrX86AvxCleanup); }
//! Tests whether the function uses call stack. //! Tests whether the function uses call stack.
inline bool hasCallStack() const noexcept { return _callStackSize != 0; } inline bool hasCallStack() const noexcept { return _callStackSize != 0; }
//! Tests whether the function uses local stack. //! Tests whether the function uses local stack.

View File

@@ -801,7 +801,7 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
uint32_t physId = tiedReg->outId(); uint32_t physId = tiedReg->outId();
if (physId == RAAssignment::kPhysNone) { if (physId == RAAssignment::kPhysNone) {
uint32_t allocableRegs = _availableRegs[group] & ~(outRegs | avoidRegs); uint32_t allocableRegs = tiedReg->_allocableRegs & ~(outRegs | avoidRegs);
if (!(allocableRegs & ~liveRegs)) { if (!(allocableRegs & ~liveRegs)) {
// There are no more registers, decide which one to spill. // There are no more registers, decide which one to spill.

View File

@@ -1737,94 +1737,6 @@ Error BaseRAPass::rewrite() noexcept {
return _rewrite(_func, _stop); return _rewrite(_func, _stop);
} }
ASMJIT_FAVOR_SPEED Error BaseRAPass::_rewrite(BaseNode* first, BaseNode* stop) noexcept {
uint32_t virtCount = cc()->_vRegArray.size();
BaseNode* node = first;
while (node != stop) {
BaseNode* next = node->next();
if (node->isInst()) {
InstNode* inst = node->as<InstNode>();
RAInst* raInst = node->passData<RAInst>();
Operand* operands = inst->operands();
uint32_t opCount = inst->opCount();
uint32_t i;
// Rewrite virtual registers into physical registers.
if (ASMJIT_LIKELY(raInst)) {
// If the instruction contains pass data (raInst) then it was a subject
// for register allocation and must be rewritten to use physical regs.
RATiedReg* tiedRegs = raInst->tiedRegs();
uint32_t tiedCount = raInst->tiedCount();
for (i = 0; i < tiedCount; i++) {
RATiedReg* tiedReg = &tiedRegs[i];
Support::BitWordIterator<uint32_t> useIt(tiedReg->useRewriteMask());
uint32_t useId = tiedReg->useId();
while (useIt.hasNext()) inst->rewriteIdAtIndex(useIt.next(), useId);
Support::BitWordIterator<uint32_t> outIt(tiedReg->outRewriteMask());
uint32_t outId = tiedReg->outId();
while (outIt.hasNext()) inst->rewriteIdAtIndex(outIt.next(), outId);
}
// This data is allocated by Zone passed to `runOnFunction()`, which
// will be reset after the RA pass finishes. So reset this data to
// prevent having a dead pointer after RA pass is complete.
node->resetPassData();
if (ASMJIT_UNLIKELY(node->type() != BaseNode::kNodeInst)) {
// FuncRet terminates the flow, it must either be removed if the exit
// label is next to it (optimization) or patched to an architecture
// dependent jump instruction that jumps to the function's exit before
// the epilog.
if (node->type() == BaseNode::kNodeFuncRet) {
RABlock* block = raInst->block();
if (!isNextTo(node, _func->exitNode())) {
cc()->_setCursor(node->prev());
ASMJIT_PROPAGATE(emitJump(_func->exitNode()->label()));
}
BaseNode* prev = node->prev();
cc()->removeNode(node);
block->setLast(prev);
}
}
}
// Rewrite stack slot addresses.
for (i = 0; i < opCount; i++) {
Operand& op = operands[i];
if (op.isMem()) {
BaseMem& mem = op.as<BaseMem>();
if (mem.isRegHome()) {
uint32_t virtIndex = Operand::virtIdToIndex(mem.baseId());
if (ASMJIT_UNLIKELY(virtIndex >= virtCount))
return DebugUtils::errored(kErrorInvalidVirtId);
VirtReg* virtReg = cc()->virtRegByIndex(virtIndex);
RAWorkReg* workReg = virtReg->workReg();
ASMJIT_ASSERT(workReg != nullptr);
RAStackSlot* slot = workReg->stackSlot();
int32_t offset = slot->offset();
mem._setBase(_sp.type(), slot->baseRegId());
mem.clearRegHome();
mem.addOffsetLo32(offset);
}
}
}
}
node = next;
}
return kErrorOk;
}
// ============================================================================ // ============================================================================
// [asmjit::BaseRAPass - Logging] // [asmjit::BaseRAPass - Logging]
// ============================================================================ // ============================================================================

View File

@@ -305,7 +305,7 @@ public:
RATiedReg _tiedRegs[1]; RATiedReg _tiedRegs[1];
enum Flags : uint32_t { enum Flags : uint32_t {
kFlagIsTerminator = 0x00000001u kFlagIsTransformable = 0x80000000u
}; };
//! \name Construction & Destruction //! \name Construction & Destruction
@@ -338,8 +338,8 @@ public:
//! Clears instruction `flags` from this RAInst. //! Clears instruction `flags` from this RAInst.
inline void clearFlags(uint32_t flags) noexcept { _flags &= ~flags; } inline void clearFlags(uint32_t flags) noexcept { _flags &= ~flags; }
//! Returns whether the RAInst represents an instruction that terminates this basic block. //! Tests whether this instruction can be transformed to another instruction if necessary.
inline bool isTerminator() const noexcept { return hasFlag(kFlagIsTerminator); } inline bool isTransformable() const noexcept { return hasFlag(kFlagIsTransformable); }
//! Returns the associated block with this RAInst. //! Returns the associated block with this RAInst.
inline RABlock* block() const noexcept { return _block; } inline RABlock* block() const noexcept { return _block; }
@@ -1125,7 +1125,7 @@ public:
//! \{ //! \{
Error rewrite() noexcept; Error rewrite() noexcept;
Error _rewrite(BaseNode* first, BaseNode* stop) noexcept; virtual Error _rewrite(BaseNode* first, BaseNode* stop) noexcept = 0;
//! \} //! \}

View File

@@ -170,6 +170,65 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! } //! }
//! ``` //! ```
//! //!
//! ### AVX and AVX-512
//!
//! AVX and AVX-512 code generation must be explicitly enabled via \ref FuncFrame
//! to work properly. If it's not setup correctly then Prolog & Epilog would use
//! SSE instead of AVX instructions to work with SIMD registers. In addition, Compiler
//! requires explicitly enable AVX-512 via \ref FuncFrame in order to use all 32 SIMD
//! registers.
//!
//! ```
//! #include <asmjit/x86.h>
//! #include <stdio.h>
//!
//! using namespace asmjit;
//!
//! // Signature of the generated function.
//! typedef void (*Func)(void*);
//!
//! int main() {
//! JitRuntime rt; // Runtime specialized for JIT code execution.
//! CodeHolder code; // Holds code and relocation information.
//!
//! code.init(rt.environment()); // Initialize code to match the JIT environment.
//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
//!
//! cc.addFunc(FuncSignatureT<void, void*>());
//!
//! // Use the following to enable AVX and/or AVX-512.
//! cc.func()->frame().setAvxEnabled();
//! cc.func()->frame().setAvx512Enabled();
//!
//! // Do something with the input pointer.
//! x86::Gp addr = cc.newIntPtr("addr");
//! x86::Zmm vreg = cc.newZmm("vreg");
//!
//! cc.setArg(0, addr);
//!
//! cc.vmovdqu32(vreg, x86::ptr(addr));
//! cc.vpaddq(vreg, vreg, vreg);
//! cc.vmovdqu32(x86::ptr(addr), vreg);
//!
//! cc.endFunc(); // End of the function body.
//! cc.finalize(); // Translate and assemble the whole 'cc' content.
//! // ----> x86::Compiler is no longer needed from here and can be destroyed <----
//!
//! Func fn;
//! Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
//! if (err) return 1; // Handle a possible error returned by AsmJit.
//! // ----> CodeHolder is no longer needed from here and can be destroyed <----
//!
//! // Execute the generated code and print some output.
//! uint64_t data[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
//! fn(data);
//! printf("%llu\n", (unsigned long long)data[0]);
//!
//! rt.release(fn); // Explicitly remove the function from the runtime.
//! return 0;
//! }
//! ```
//!
//! ### Recursive Functions //! ### Recursive Functions
//! //!
//! It's possible to create more functions by using the same \ref x86::Compiler //! It's possible to create more functions by using the same \ref x86::Compiler

View File

@@ -148,12 +148,10 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitRegMove(
instId = _avxEnabled ? Inst::kIdVmovaps : Inst::kIdMovaps; instId = _avxEnabled ? Inst::kIdVmovaps : Inst::kIdMovaps;
else if (elementTypeId == Type::kIdF64) else if (elementTypeId == Type::kIdF64)
instId = _avxEnabled ? Inst::kIdVmovapd : Inst::kIdMovapd; instId = _avxEnabled ? Inst::kIdVmovapd : Inst::kIdMovapd;
else if (typeId <= Type::_kIdVec256End) else if (!_avx512Enabled)
instId = _avxEnabled ? Inst::kIdVmovdqa : Inst::kIdMovdqa; instId = _avxEnabled ? Inst::kIdVmovdqa : Inst::kIdMovdqa;
else if (elementTypeId <= Type::kIdU32)
instId = Inst::kIdVmovdqa32;
else else
instId = Inst::kIdVmovdqa64; instId = Inst::kIdVmovdqa32;
break; break;
} }
} }

View File

@@ -49,10 +49,12 @@ static ASMJIT_INLINE uint32_t vecTypeIdToRegType(uint32_t typeId) noexcept {
class EmitHelper : public BaseEmitHelper { class EmitHelper : public BaseEmitHelper {
public: public:
bool _avxEnabled; bool _avxEnabled;
bool _avx512Enabled;
inline explicit EmitHelper(BaseEmitter* emitter = nullptr, bool avxEnabled = false) noexcept inline explicit EmitHelper(BaseEmitter* emitter = nullptr, bool avxEnabled = false, bool avx512Enabled = false) noexcept
: BaseEmitHelper(emitter), : BaseEmitHelper(emitter),
_avxEnabled(avxEnabled) {} _avxEnabled(avxEnabled || avx512Enabled),
_avx512Enabled(avx512Enabled) {}
Error emitRegMove( Error emitRegMove(
const Operand_& dst_, const Operand_& dst_,

View File

@@ -2055,427 +2055,429 @@ const uint32_t InstDB::_altOpcodeTable[] = {
// ${InstCommonTable:Begin} // ${InstCommonTable:Begin}
// ------------------- Automatically generated, do not edit ------------------- // ------------------- Automatically generated, do not edit -------------------
#define F(VAL) InstDB::kFlag##VAL #define F(VAL) InstDB::kFlag##VAL
#define X(VAL) InstDB::kAvx512Flag##VAL
#define CONTROL(VAL) Inst::kControl##VAL #define CONTROL(VAL) Inst::kControl##VAL
#define SINGLE_REG(VAL) InstDB::kSingleReg##VAL #define SINGLE_REG(VAL) InstDB::kSingleReg##VAL
const InstDB::CommonInfo InstDB::_commonInfoTable[] = { const InstDB::CommonInfo InstDB::_commonInfoTable[] = {
{ 0 , 0 , 0 , CONTROL(None) , SINGLE_REG(None), 0 }, // #0 [ref=1x] { 0 , 0 , 0 , 0 , CONTROL(None) , SINGLE_REG(None)}, // #0 [ref=1x]
{ 0 , 376, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #1 [ref=4x] { 0 , 0 , 376, 1 , CONTROL(None) , SINGLE_REG(None)}, // #1 [ref=4x]
{ 0 , 377, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #2 [ref=2x] { 0 , 0 , 377, 1 , CONTROL(None) , SINGLE_REG(None)}, // #2 [ref=2x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 16 , 12, CONTROL(None) , SINGLE_REG(None), 0 }, // #3 [ref=2x] { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 16 , 12, CONTROL(None) , SINGLE_REG(None)}, // #3 [ref=2x]
{ 0 , 180, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #4 [ref=2x] { 0 , 0 , 180, 2 , CONTROL(None) , SINGLE_REG(None)}, // #4 [ref=2x]
{ F(Vec) , 79 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #5 [ref=54x] { F(Vec) , 0 , 79 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #5 [ref=54x]
{ F(Vec) , 106, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #6 [ref=19x] { F(Vec) , 0 , 106, 1 , CONTROL(None) , SINGLE_REG(None)}, // #6 [ref=19x]
{ F(Vec) , 257, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #7 [ref=16x] { F(Vec) , 0 , 257, 1 , CONTROL(None) , SINGLE_REG(None)}, // #7 [ref=16x]
{ F(Vec) , 215, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #8 [ref=20x] { F(Vec) , 0 , 215, 1 , CONTROL(None) , SINGLE_REG(None)}, // #8 [ref=20x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 28 , 11, CONTROL(None) , SINGLE_REG(RO) , 0 }, // #9 [ref=1x] { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 28 , 11, CONTROL(None) , SINGLE_REG(RO) }, // #9 [ref=1x]
{ F(Vex) , 272, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #10 [ref=3x] { F(Vex) , 0 , 272, 2 , CONTROL(None) , SINGLE_REG(None)}, // #10 [ref=3x]
{ F(Vec) , 79 , 1 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #11 [ref=12x] { F(Vec) , 0 , 79 , 1 , CONTROL(None) , SINGLE_REG(RO) }, // #11 [ref=12x]
{ 0 , 378, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #12 [ref=1x] { 0 , 0 , 378, 1 , CONTROL(None) , SINGLE_REG(None)}, // #12 [ref=1x]
{ F(Vex) , 274, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #13 [ref=5x] { F(Vex) , 0 , 274, 2 , CONTROL(None) , SINGLE_REG(None)}, // #13 [ref=5x]
{ F(Vex) , 180, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #14 [ref=12x] { F(Vex) , 0 , 180, 2 , CONTROL(None) , SINGLE_REG(None)}, // #14 [ref=12x]
{ F(Vec) , 379, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #15 [ref=4x] { F(Vec) , 0 , 379, 1 , CONTROL(None) , SINGLE_REG(None)}, // #15 [ref=4x]
{ 0 , 276, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #16 [ref=3x] { 0 , 0 , 276, 2 , CONTROL(None) , SINGLE_REG(None)}, // #16 [ref=3x]
{ F(Mib) , 380, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #17 [ref=1x] { F(Mib) , 0 , 380, 1 , CONTROL(None) , SINGLE_REG(None)}, // #17 [ref=1x]
{ 0 , 381, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #18 [ref=1x] { 0 , 0 , 381, 1 , CONTROL(None) , SINGLE_REG(None)}, // #18 [ref=1x]
{ 0 , 278, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #19 [ref=1x] { 0 , 0 , 278, 2 , CONTROL(None) , SINGLE_REG(None)}, // #19 [ref=1x]
{ F(Mib) , 382, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #20 [ref=1x] { F(Mib) , 0 , 382, 1 , CONTROL(None) , SINGLE_REG(None)}, // #20 [ref=1x]
{ 0 , 280, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #21 [ref=1x] { 0 , 0 , 280, 2 , CONTROL(None) , SINGLE_REG(None)}, // #21 [ref=1x]
{ 0 , 179, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #22 [ref=35x] { 0 , 0 , 179, 3 , CONTROL(None) , SINGLE_REG(None)}, // #22 [ref=35x]
{ 0 , 383, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #23 [ref=3x] { 0 , 0 , 383, 1 , CONTROL(None) , SINGLE_REG(None)}, // #23 [ref=3x]
{ 0 , 123, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #24 [ref=1x] { 0 , 0 , 123, 4 , CONTROL(None) , SINGLE_REG(None)}, // #24 [ref=1x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 123, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #25 [ref=3x] { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 123, 4 , CONTROL(None) , SINGLE_REG(None)}, // #25 [ref=3x]
{ F(Rep)|F(RepIgnored) , 282, 2 , CONTROL(Call) , SINGLE_REG(None), 0 }, // #26 [ref=1x] { F(Rep)|F(RepIgnored) , 0 , 282, 2 , CONTROL(Call) , SINGLE_REG(None)}, // #26 [ref=1x]
{ 0 , 384, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #27 [ref=1x] { 0 , 0 , 384, 1 , CONTROL(None) , SINGLE_REG(None)}, // #27 [ref=1x]
{ 0 , 385, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #28 [ref=2x] { 0 , 0 , 385, 1 , CONTROL(None) , SINGLE_REG(None)}, // #28 [ref=2x]
{ 0 , 359, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #29 [ref=1x] { 0 , 0 , 359, 1 , CONTROL(None) , SINGLE_REG(None)}, // #29 [ref=1x]
{ 0 , 108, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #30 [ref=83x] { 0 , 0 , 108, 1 , CONTROL(None) , SINGLE_REG(None)}, // #30 [ref=83x]
{ 0 , 386, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #31 [ref=24x] { 0 , 0 , 386, 1 , CONTROL(None) , SINGLE_REG(None)}, // #31 [ref=24x]
{ 0 , 387, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #32 [ref=6x] { 0 , 0 , 387, 1 , CONTROL(None) , SINGLE_REG(None)}, // #32 [ref=6x]
{ 0 , 388, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #33 [ref=13x] { 0 , 0 , 388, 1 , CONTROL(None) , SINGLE_REG(None)}, // #33 [ref=13x]
{ 0 , 389, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #34 [ref=1x] { 0 , 0 , 389, 1 , CONTROL(None) , SINGLE_REG(None)}, // #34 [ref=1x]
{ 0 , 16 , 12, CONTROL(None) , SINGLE_REG(None), 0 }, // #35 [ref=1x] { 0 , 0 , 16 , 12, CONTROL(None) , SINGLE_REG(None)}, // #35 [ref=1x]
{ F(Rep) , 127, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #36 [ref=1x] { F(Rep) , 0 , 127, 4 , CONTROL(None) , SINGLE_REG(None)}, // #36 [ref=1x]
{ F(Vec) , 390, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #37 [ref=2x] { F(Vec) , 0 , 390, 1 , CONTROL(None) , SINGLE_REG(None)}, // #37 [ref=2x]
{ F(Vec) , 391, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #38 [ref=3x] { F(Vec) , 0 , 391, 1 , CONTROL(None) , SINGLE_REG(None)}, // #38 [ref=3x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 131, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #39 [ref=1x] { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 131, 4 , CONTROL(None) , SINGLE_REG(None)}, // #39 [ref=1x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 392, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #40 [ref=1x] { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 392, 1 , CONTROL(None) , SINGLE_REG(None)}, // #40 [ref=1x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 393, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #41 [ref=1x] { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 393, 1 , CONTROL(None) , SINGLE_REG(None)}, // #41 [ref=1x]
{ 0 , 394, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #42 [ref=1x] { 0 , 0 , 394, 1 , CONTROL(None) , SINGLE_REG(None)}, // #42 [ref=1x]
{ 0 , 395, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #43 [ref=1x] { 0 , 0 , 395, 1 , CONTROL(None) , SINGLE_REG(None)}, // #43 [ref=1x]
{ 0 , 284, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #44 [ref=1x] { 0 , 0 , 284, 2 , CONTROL(None) , SINGLE_REG(None)}, // #44 [ref=1x]
{ F(Mmx)|F(Vec) , 396, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #45 [ref=2x] { F(Mmx)|F(Vec) , 0 , 396, 1 , CONTROL(None) , SINGLE_REG(None)}, // #45 [ref=2x]
{ F(Mmx)|F(Vec) , 397, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #46 [ref=2x] { F(Mmx)|F(Vec) , 0 , 397, 1 , CONTROL(None) , SINGLE_REG(None)}, // #46 [ref=2x]
{ F(Mmx)|F(Vec) , 398, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #47 [ref=2x] { F(Mmx)|F(Vec) , 0 , 398, 1 , CONTROL(None) , SINGLE_REG(None)}, // #47 [ref=2x]
{ F(Vec) , 399, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #48 [ref=2x] { F(Vec) , 0 , 399, 1 , CONTROL(None) , SINGLE_REG(None)}, // #48 [ref=2x]
{ F(Vec) , 400, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #49 [ref=2x] { F(Vec) , 0 , 400, 1 , CONTROL(None) , SINGLE_REG(None)}, // #49 [ref=2x]
{ F(Vec) , 401, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #50 [ref=2x] { F(Vec) , 0 , 401, 1 , CONTROL(None) , SINGLE_REG(None)}, // #50 [ref=2x]
{ 0 , 402, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #51 [ref=1x] { 0 , 0 , 402, 1 , CONTROL(None) , SINGLE_REG(None)}, // #51 [ref=1x]
{ 0 , 403, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #52 [ref=2x] { 0 , 0 , 403, 1 , CONTROL(None) , SINGLE_REG(None)}, // #52 [ref=2x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 286, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #53 [ref=2x] { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 286, 2 , CONTROL(None) , SINGLE_REG(None)}, // #53 [ref=2x]
{ 0 , 39 , 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #54 [ref=3x] { 0 , 0 , 39 , 4 , CONTROL(None) , SINGLE_REG(None)}, // #54 [ref=3x]
{ F(Mmx) , 108, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #55 [ref=1x] { F(Mmx) , 0 , 108, 1 , CONTROL(None) , SINGLE_REG(None)}, // #55 [ref=1x]
{ 0 , 288, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #56 [ref=2x] { 0 , 0 , 288, 2 , CONTROL(None) , SINGLE_REG(None)}, // #56 [ref=2x]
{ 0 , 404, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #57 [ref=1x] { 0 , 0 , 404, 1 , CONTROL(None) , SINGLE_REG(None)}, // #57 [ref=1x]
{ F(Vec) , 405, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #58 [ref=2x] { F(Vec) , 0 , 405, 1 , CONTROL(None) , SINGLE_REG(None)}, // #58 [ref=2x]
{ F(Vec) , 290, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #59 [ref=1x] { F(Vec) , 0 , 290, 2 , CONTROL(None) , SINGLE_REG(None)}, // #59 [ref=1x]
{ F(FpuM32)|F(FpuM64) , 182, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #60 [ref=6x] { F(FpuM32)|F(FpuM64) , 0 , 182, 3 , CONTROL(None) , SINGLE_REG(None)}, // #60 [ref=6x]
{ 0 , 292, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #61 [ref=9x] { 0 , 0 , 292, 2 , CONTROL(None) , SINGLE_REG(None)}, // #61 [ref=9x]
{ F(FpuM80) , 406, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #62 [ref=2x] { F(FpuM80) , 0 , 406, 1 , CONTROL(None) , SINGLE_REG(None)}, // #62 [ref=2x]
{ 0 , 293, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #63 [ref=13x] { 0 , 0 , 293, 1 , CONTROL(None) , SINGLE_REG(None)}, // #63 [ref=13x]
{ F(FpuM32)|F(FpuM64) , 294, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #64 [ref=2x] { F(FpuM32)|F(FpuM64) , 0 , 294, 2 , CONTROL(None) , SINGLE_REG(None)}, // #64 [ref=2x]
{ F(FpuM16)|F(FpuM32) , 407, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #65 [ref=9x] { F(FpuM16)|F(FpuM32) , 0 , 407, 1 , CONTROL(None) , SINGLE_REG(None)}, // #65 [ref=9x]
{ F(FpuM16)|F(FpuM32)|F(FpuM64) , 408, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #66 [ref=3x] { F(FpuM16)|F(FpuM32)|F(FpuM64) , 0 , 408, 1 , CONTROL(None) , SINGLE_REG(None)}, // #66 [ref=3x]
{ F(FpuM32)|F(FpuM64)|F(FpuM80) , 409, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #67 [ref=2x] { F(FpuM32)|F(FpuM64)|F(FpuM80) , 0 , 409, 1 , CONTROL(None) , SINGLE_REG(None)}, // #67 [ref=2x]
{ F(FpuM16) , 410, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #68 [ref=3x] { F(FpuM16) , 0 , 410, 1 , CONTROL(None) , SINGLE_REG(None)}, // #68 [ref=3x]
{ F(FpuM16) , 411, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #69 [ref=2x] { F(FpuM16) , 0 , 411, 1 , CONTROL(None) , SINGLE_REG(None)}, // #69 [ref=2x]
{ F(FpuM32)|F(FpuM64) , 295, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #70 [ref=1x] { F(FpuM32)|F(FpuM64) , 0 , 295, 1 , CONTROL(None) , SINGLE_REG(None)}, // #70 [ref=1x]
{ 0 , 412, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #71 [ref=2x] { 0 , 0 , 412, 1 , CONTROL(None) , SINGLE_REG(None)}, // #71 [ref=2x]
{ 0 , 413, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #72 [ref=1x] { 0 , 0 , 413, 1 , CONTROL(None) , SINGLE_REG(None)}, // #72 [ref=1x]
{ 0 , 39 , 10, CONTROL(None) , SINGLE_REG(None), 0 }, // #73 [ref=1x] { 0 , 0 , 39 , 10, CONTROL(None) , SINGLE_REG(None)}, // #73 [ref=1x]
{ 0 , 414, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #74 [ref=1x] { 0 , 0 , 414, 1 , CONTROL(None) , SINGLE_REG(None)}, // #74 [ref=1x]
{ 0 , 415, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #75 [ref=2x] { 0 , 0 , 415, 1 , CONTROL(None) , SINGLE_REG(None)}, // #75 [ref=2x]
{ 0 , 343, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #76 [ref=3x] { 0 , 0 , 343, 1 , CONTROL(None) , SINGLE_REG(None)}, // #76 [ref=3x]
{ F(Rep) , 416, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #77 [ref=1x] { F(Rep) , 0 , 416, 1 , CONTROL(None) , SINGLE_REG(None)}, // #77 [ref=1x]
{ F(Vec) , 296, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #78 [ref=1x] { F(Vec) , 0 , 296, 2 , CONTROL(None) , SINGLE_REG(None)}, // #78 [ref=1x]
{ 0 , 417, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #79 [ref=2x] { 0 , 0 , 417, 1 , CONTROL(None) , SINGLE_REG(None)}, // #79 [ref=2x]
{ 0 , 418, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #80 [ref=8x] { 0 , 0 , 418, 1 , CONTROL(None) , SINGLE_REG(None)}, // #80 [ref=8x]
{ 0 , 298, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #81 [ref=3x] { 0 , 0 , 298, 2 , CONTROL(None) , SINGLE_REG(None)}, // #81 [ref=3x]
{ 0 , 300, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #82 [ref=1x] { 0 , 0 , 300, 2 , CONTROL(None) , SINGLE_REG(None)}, // #82 [ref=1x]
{ 0 , 108, 1 , CONTROL(Return) , SINGLE_REG(None), 0 }, // #83 [ref=2x] { 0 , 0 , 108, 1 , CONTROL(Return) , SINGLE_REG(None)}, // #83 [ref=2x]
{ 0 , 388, 1 , CONTROL(Return) , SINGLE_REG(None), 0 }, // #84 [ref=1x] { 0 , 0 , 388, 1 , CONTROL(Return) , SINGLE_REG(None)}, // #84 [ref=1x]
{ F(Rep)|F(RepIgnored) , 302, 2 , CONTROL(Branch) , SINGLE_REG(None), 0 }, // #85 [ref=30x] { F(Rep)|F(RepIgnored) , 0 , 302, 2 , CONTROL(Branch) , SINGLE_REG(None)}, // #85 [ref=30x]
{ F(Rep)|F(RepIgnored) , 304, 2 , CONTROL(Branch) , SINGLE_REG(None), 0 }, // #86 [ref=1x] { F(Rep)|F(RepIgnored) , 0 , 304, 2 , CONTROL(Branch) , SINGLE_REG(None)}, // #86 [ref=1x]
{ F(Rep)|F(RepIgnored) , 306, 2 , CONTROL(Jump) , SINGLE_REG(None), 0 }, // #87 [ref=1x] { F(Rep)|F(RepIgnored) , 0 , 306, 2 , CONTROL(Jump) , SINGLE_REG(None)}, // #87 [ref=1x]
{ F(Vec)|F(Vex) , 419, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #88 [ref=27x] { F(Vex) , 0 , 419, 1 , CONTROL(None) , SINGLE_REG(None)}, // #88 [ref=27x]
{ F(Vec)|F(Vex) , 308, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #89 [ref=1x] { F(Vex) , 0 , 308, 2 , CONTROL(None) , SINGLE_REG(None)}, // #89 [ref=1x]
{ F(Vec)|F(Vex) , 310, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #90 [ref=1x] { F(Vex) , 0 , 310, 2 , CONTROL(None) , SINGLE_REG(None)}, // #90 [ref=1x]
{ F(Vec)|F(Vex) , 312, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #91 [ref=1x] { F(Vex) , 0 , 312, 2 , CONTROL(None) , SINGLE_REG(None)}, // #91 [ref=1x]
{ F(Vec)|F(Vex) , 314, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #92 [ref=1x] { F(Vex) , 0 , 314, 2 , CONTROL(None) , SINGLE_REG(None)}, // #92 [ref=1x]
{ F(Vec)|F(Vex) , 420, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #93 [ref=12x] { F(Vex) , 0 , 420, 1 , CONTROL(None) , SINGLE_REG(None)}, // #93 [ref=12x]
{ F(Vec)|F(Vex) , 421, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #94 [ref=8x] { F(Vex) , 0 , 421, 1 , CONTROL(None) , SINGLE_REG(None)}, // #94 [ref=8x]
{ 0 , 422, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #95 [ref=2x] { 0 , 0 , 422, 1 , CONTROL(None) , SINGLE_REG(None)}, // #95 [ref=2x]
{ 0 , 316, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #96 [ref=1x] { 0 , 0 , 316, 2 , CONTROL(None) , SINGLE_REG(None)}, // #96 [ref=1x]
{ 0 , 318, 2 , CONTROL(Call) , SINGLE_REG(None), 0 }, // #97 [ref=1x] { 0 , 0 , 318, 2 , CONTROL(Call) , SINGLE_REG(None)}, // #97 [ref=1x]
{ F(Vec) , 224, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #98 [ref=2x] { F(Vec) , 0 , 224, 1 , CONTROL(None) , SINGLE_REG(None)}, // #98 [ref=2x]
{ 0 , 423, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #99 [ref=2x] { 0 , 0 , 423, 1 , CONTROL(None) , SINGLE_REG(None)}, // #99 [ref=2x]
{ 0 , 320, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #100 [ref=2x] { 0 , 0 , 320, 2 , CONTROL(None) , SINGLE_REG(None)}, // #100 [ref=2x]
{ F(Vex) , 424, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #101 [ref=2x] { F(Vex) , 0 , 424, 1 , CONTROL(None) , SINGLE_REG(None)}, // #101 [ref=2x]
{ 0 , 425, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #102 [ref=1x] { 0 , 0 , 425, 1 , CONTROL(None) , SINGLE_REG(None)}, // #102 [ref=1x]
{ 0 , 185, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #103 [ref=3x] { 0 , 0 , 185, 3 , CONTROL(None) , SINGLE_REG(None)}, // #103 [ref=3x]
{ 0 , 318, 2 , CONTROL(Jump) , SINGLE_REG(None), 0 }, // #104 [ref=1x] { 0 , 0 , 318, 2 , CONTROL(Jump) , SINGLE_REG(None)}, // #104 [ref=1x]
{ 0 , 426, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #105 [ref=5x] { 0 , 0 , 426, 1 , CONTROL(None) , SINGLE_REG(None)}, // #105 [ref=5x]
{ F(Vex) , 427, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #106 [ref=2x] { F(Vex) , 0 , 427, 1 , CONTROL(None) , SINGLE_REG(None)}, // #106 [ref=2x]
{ F(Rep) , 135, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #107 [ref=1x] { F(Rep) , 0 , 135, 4 , CONTROL(None) , SINGLE_REG(None)}, // #107 [ref=1x]
{ 0 , 304, 2 , CONTROL(Branch) , SINGLE_REG(None), 0 }, // #108 [ref=3x] { 0 , 0 , 304, 2 , CONTROL(Branch) , SINGLE_REG(None)}, // #108 [ref=3x]
{ 0 , 322, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #109 [ref=1x] { 0 , 0 , 322, 2 , CONTROL(None) , SINGLE_REG(None)}, // #109 [ref=1x]
{ F(Vex) , 428, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #110 [ref=2x] { F(Vex) , 0 , 428, 1 , CONTROL(None) , SINGLE_REG(None)}, // #110 [ref=2x]
{ F(Vec) , 429, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #111 [ref=1x] { F(Vec) , 0 , 429, 1 , CONTROL(None) , SINGLE_REG(None)}, // #111 [ref=1x]
{ F(Mmx) , 430, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #112 [ref=1x] { F(Mmx) , 0 , 430, 1 , CONTROL(None) , SINGLE_REG(None)}, // #112 [ref=1x]
{ 0 , 431, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #113 [ref=2x] { 0 , 0 , 431, 1 , CONTROL(None) , SINGLE_REG(None)}, // #113 [ref=2x]
{ F(XRelease) , 0 , 16, CONTROL(None) , SINGLE_REG(None), 0 }, // #114 [ref=1x] { F(XRelease) , 0 , 0 , 16, CONTROL(None) , SINGLE_REG(None)}, // #114 [ref=1x]
{ 0 , 49 , 9 , CONTROL(None) , SINGLE_REG(None), 0 }, // #115 [ref=1x] { 0 , 0 , 49 , 9 , CONTROL(None) , SINGLE_REG(None)}, // #115 [ref=1x]
{ F(Vec) , 79 , 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #116 [ref=6x] { F(Vec) , 0 , 79 , 2 , CONTROL(None) , SINGLE_REG(None)}, // #116 [ref=6x]
{ 0 , 73 , 6 , CONTROL(None) , SINGLE_REG(None), 0 }, // #117 [ref=1x] { 0 , 0 , 73 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #117 [ref=1x]
{ F(Mmx)|F(Vec) , 324, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #118 [ref=1x] { F(Mmx)|F(Vec) , 0 , 324, 2 , CONTROL(None) , SINGLE_REG(None)}, // #118 [ref=1x]
{ 0 , 432, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #119 [ref=1x] { 0 , 0 , 432, 1 , CONTROL(None) , SINGLE_REG(None)}, // #119 [ref=1x]
{ 0 , 77 , 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #120 [ref=2x] { 0 , 0 , 77 , 2 , CONTROL(None) , SINGLE_REG(None)}, // #120 [ref=2x]
{ F(Mmx)|F(Vec) , 433, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #121 [ref=1x] { F(Mmx)|F(Vec) , 0 , 433, 1 , CONTROL(None) , SINGLE_REG(None)}, // #121 [ref=1x]
{ F(Vec) , 291, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #122 [ref=2x] { F(Vec) , 0 , 291, 1 , CONTROL(None) , SINGLE_REG(None)}, // #122 [ref=2x]
{ F(Vec) , 230, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #123 [ref=4x] { F(Vec) , 0 , 230, 2 , CONTROL(None) , SINGLE_REG(None)}, // #123 [ref=4x]
{ F(Vec) , 434, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #124 [ref=2x] { F(Vec) , 0 , 434, 1 , CONTROL(None) , SINGLE_REG(None)}, // #124 [ref=2x]
{ F(Vec) , 80 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #125 [ref=3x] { F(Vec) , 0 , 80 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #125 [ref=3x]
{ F(Mmx) , 435, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #126 [ref=1x] { F(Mmx) , 0 , 435, 1 , CONTROL(None) , SINGLE_REG(None)}, // #126 [ref=1x]
{ F(Vec) , 107, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #127 [ref=1x] { F(Vec) , 0 , 107, 1 , CONTROL(None) , SINGLE_REG(None)}, // #127 [ref=1x]
{ F(Vec) , 233, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #128 [ref=1x] { F(Vec) , 0 , 233, 1 , CONTROL(None) , SINGLE_REG(None)}, // #128 [ref=1x]
{ F(Mmx)|F(Vec) , 103, 5 , CONTROL(None) , SINGLE_REG(None), 0 }, // #129 [ref=1x] { F(Mmx)|F(Vec) , 0 , 103, 5 , CONTROL(None) , SINGLE_REG(None)}, // #129 [ref=1x]
{ F(Mmx)|F(Vec) , 436, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #130 [ref=1x] { F(Mmx)|F(Vec) , 0 , 436, 1 , CONTROL(None) , SINGLE_REG(None)}, // #130 [ref=1x]
{ F(Rep) , 139, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #131 [ref=1x] { F(Rep) , 0 , 139, 4 , CONTROL(None) , SINGLE_REG(None)}, // #131 [ref=1x]
{ F(Vec) , 106, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #132 [ref=1x] { F(Vec) , 0 , 106, 2 , CONTROL(None) , SINGLE_REG(None)}, // #132 [ref=1x]
{ F(Vec) , 326, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #133 [ref=1x] { F(Vec) , 0 , 326, 2 , CONTROL(None) , SINGLE_REG(None)}, // #133 [ref=1x]
{ 0 , 328, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #134 [ref=2x] { 0 , 0 , 328, 2 , CONTROL(None) , SINGLE_REG(None)}, // #134 [ref=2x]
{ 0 , 437, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #135 [ref=1x] { 0 , 0 , 437, 1 , CONTROL(None) , SINGLE_REG(None)}, // #135 [ref=1x]
{ F(Vex) , 330, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #136 [ref=1x] { F(Vex) , 0 , 330, 2 , CONTROL(None) , SINGLE_REG(None)}, // #136 [ref=1x]
{ 0 , 438, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #137 [ref=1x] { 0 , 0 , 438, 1 , CONTROL(None) , SINGLE_REG(None)}, // #137 [ref=1x]
{ 0 , 439, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #138 [ref=1x] { 0 , 0 , 439, 1 , CONTROL(None) , SINGLE_REG(None)}, // #138 [ref=1x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 287, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #139 [ref=2x] { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 287, 1 , CONTROL(None) , SINGLE_REG(None)}, // #139 [ref=2x]
{ 0 , 108, 5 , CONTROL(None) , SINGLE_REG(None), 0 }, // #140 [ref=1x] { 0 , 0 , 108, 5 , CONTROL(None) , SINGLE_REG(None)}, // #140 [ref=1x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 16 , 12, CONTROL(None) , SINGLE_REG(RO) , 0 }, // #141 [ref=1x] { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 16 , 12, CONTROL(None) , SINGLE_REG(RO) }, // #141 [ref=1x]
{ 0 , 440, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #142 [ref=1x] { 0 , 0 , 440, 1 , CONTROL(None) , SINGLE_REG(None)}, // #142 [ref=1x]
{ F(Rep) , 441, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #143 [ref=1x] { F(Rep) , 0 , 441, 1 , CONTROL(None) , SINGLE_REG(None)}, // #143 [ref=1x]
{ F(Mmx)|F(Vec) , 332, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #144 [ref=37x] { F(Mmx)|F(Vec) , 0 , 332, 2 , CONTROL(None) , SINGLE_REG(None)}, // #144 [ref=37x]
{ F(Mmx)|F(Vec) , 334, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #145 [ref=1x] { F(Mmx)|F(Vec) , 0 , 334, 2 , CONTROL(None) , SINGLE_REG(None)}, // #145 [ref=1x]
{ F(Mmx)|F(Vec) , 332, 2 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #146 [ref=6x] { F(Mmx)|F(Vec) , 0 , 332, 2 , CONTROL(None) , SINGLE_REG(RO) }, // #146 [ref=6x]
{ F(Mmx)|F(Vec) , 332, 2 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #147 [ref=16x] { F(Mmx)|F(Vec) , 0 , 332, 2 , CONTROL(None) , SINGLE_REG(WO) }, // #147 [ref=16x]
{ F(Mmx) , 332, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #148 [ref=26x] { F(Mmx) , 0 , 332, 1 , CONTROL(None) , SINGLE_REG(None)}, // #148 [ref=26x]
{ F(Vec) , 79 , 1 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #149 [ref=4x] { F(Vec) , 0 , 79 , 1 , CONTROL(None) , SINGLE_REG(WO) }, // #149 [ref=4x]
{ F(Vec) , 442, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #150 [ref=1x] { F(Vec) , 0 , 442, 1 , CONTROL(None) , SINGLE_REG(None)}, // #150 [ref=1x]
{ F(Vec) , 443, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #151 [ref=1x] { F(Vec) , 0 , 443, 1 , CONTROL(None) , SINGLE_REG(None)}, // #151 [ref=1x]
{ F(Vec) , 444, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #152 [ref=1x] { F(Vec) , 0 , 444, 1 , CONTROL(None) , SINGLE_REG(None)}, // #152 [ref=1x]
{ F(Vec) , 445, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #153 [ref=1x] { F(Vec) , 0 , 445, 1 , CONTROL(None) , SINGLE_REG(None)}, // #153 [ref=1x]
{ F(Vec) , 446, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #154 [ref=1x] { F(Vec) , 0 , 446, 1 , CONTROL(None) , SINGLE_REG(None)}, // #154 [ref=1x]
{ F(Vec) , 447, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #155 [ref=1x] { F(Vec) , 0 , 447, 1 , CONTROL(None) , SINGLE_REG(None)}, // #155 [ref=1x]
{ F(Mmx)|F(Vec) , 336, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #156 [ref=1x] { F(Mmx)|F(Vec) , 0 , 336, 2 , CONTROL(None) , SINGLE_REG(None)}, // #156 [ref=1x]
{ F(Vec) , 448, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #157 [ref=1x] { F(Vec) , 0 , 448, 1 , CONTROL(None) , SINGLE_REG(None)}, // #157 [ref=1x]
{ F(Vec) , 449, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #158 [ref=1x] { F(Vec) , 0 , 449, 1 , CONTROL(None) , SINGLE_REG(None)}, // #158 [ref=1x]
{ F(Vec) , 450, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #159 [ref=1x] { F(Vec) , 0 , 450, 1 , CONTROL(None) , SINGLE_REG(None)}, // #159 [ref=1x]
{ F(Mmx)|F(Vec) , 451, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #160 [ref=1x] { F(Mmx)|F(Vec) , 0 , 451, 1 , CONTROL(None) , SINGLE_REG(None)}, // #160 [ref=1x]
{ F(Mmx)|F(Vec) , 452, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #161 [ref=1x] { F(Mmx)|F(Vec) , 0 , 452, 1 , CONTROL(None) , SINGLE_REG(None)}, // #161 [ref=1x]
{ F(Vec) , 260, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #162 [ref=2x] { F(Vec) , 0 , 260, 1 , CONTROL(None) , SINGLE_REG(None)}, // #162 [ref=2x]
{ 0 , 143, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #163 [ref=1x] { 0 , 0 , 143, 4 , CONTROL(None) , SINGLE_REG(None)}, // #163 [ref=1x]
{ F(Mmx) , 334, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #164 [ref=1x] { F(Mmx) , 0 , 334, 1 , CONTROL(None) , SINGLE_REG(None)}, // #164 [ref=1x]
{ F(Mmx)|F(Vec) , 338, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #165 [ref=8x] { F(Mmx)|F(Vec) , 0 , 338, 2 , CONTROL(None) , SINGLE_REG(None)}, // #165 [ref=8x]
{ F(Vec) , 453, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #166 [ref=2x] { F(Vec) , 0 , 453, 1 , CONTROL(None) , SINGLE_REG(None)}, // #166 [ref=2x]
{ 0 , 454, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #167 [ref=1x] { 0 , 0 , 454, 1 , CONTROL(None) , SINGLE_REG(None)}, // #167 [ref=1x]
{ F(Mmx)|F(Vec) , 340, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #168 [ref=3x] { F(Mmx)|F(Vec) , 0 , 340, 2 , CONTROL(None) , SINGLE_REG(None)}, // #168 [ref=3x]
{ 0 , 147, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #169 [ref=1x] { 0 , 0 , 147, 4 , CONTROL(None) , SINGLE_REG(None)}, // #169 [ref=1x]
{ 0 , 455, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #170 [ref=8x] { 0 , 0 , 455, 1 , CONTROL(None) , SINGLE_REG(None)}, // #170 [ref=8x]
{ 0 , 456, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #171 [ref=4x] { 0 , 0 , 456, 1 , CONTROL(None) , SINGLE_REG(None)}, // #171 [ref=4x]
{ 0 , 457, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #172 [ref=8x] { 0 , 0 , 457, 1 , CONTROL(None) , SINGLE_REG(None)}, // #172 [ref=8x]
{ 0 , 342, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #173 [ref=1x] { 0 , 0 , 342, 2 , CONTROL(None) , SINGLE_REG(None)}, // #173 [ref=1x]
{ F(Rep)|F(RepIgnored) , 344, 2 , CONTROL(Return) , SINGLE_REG(None), 0 }, // #174 [ref=1x] { F(Rep)|F(RepIgnored) , 0 , 344, 2 , CONTROL(Return) , SINGLE_REG(None)}, // #174 [ref=1x]
{ 0 , 344, 2 , CONTROL(Return) , SINGLE_REG(None), 0 }, // #175 [ref=1x] { 0 , 0 , 344, 2 , CONTROL(Return) , SINGLE_REG(None)}, // #175 [ref=1x]
{ F(Vex) , 346, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #176 [ref=1x] { F(Vex) , 0 , 346, 2 , CONTROL(None) , SINGLE_REG(None)}, // #176 [ref=1x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 16 , 12, CONTROL(None) , SINGLE_REG(WO) , 0 }, // #177 [ref=3x] { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 16 , 12, CONTROL(None) , SINGLE_REG(WO) }, // #177 [ref=3x]
{ F(Rep) , 151, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #178 [ref=1x] { F(Rep) , 0 , 151, 4 , CONTROL(None) , SINGLE_REG(None)}, // #178 [ref=1x]
{ 0 , 458, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #179 [ref=30x] { 0 , 0 , 458, 1 , CONTROL(None) , SINGLE_REG(None)}, // #179 [ref=30x]
{ 0 , 188, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #180 [ref=2x] { 0 , 0 , 188, 3 , CONTROL(None) , SINGLE_REG(None)}, // #180 [ref=2x]
{ 0 , 459, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #181 [ref=3x] { 0 , 0 , 459, 1 , CONTROL(None) , SINGLE_REG(None)}, // #181 [ref=3x]
{ F(Rep) , 155, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #182 [ref=1x] { F(Rep) , 0 , 155, 4 , CONTROL(None) , SINGLE_REG(None)}, // #182 [ref=1x]
{ F(Vex) , 460, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #183 [ref=5x] { F(Vex) , 0 , 460, 1 , CONTROL(None) , SINGLE_REG(None)}, // #183 [ref=5x]
{ 0 , 66 , 7 , CONTROL(None) , SINGLE_REG(None), 0 }, // #184 [ref=1x] { 0 , 0 , 66 , 7 , CONTROL(None) , SINGLE_REG(None)}, // #184 [ref=1x]
{ F(Tsib)|F(Vex) , 461, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #185 [ref=2x] { F(Tsib)|F(Vex) , 0 , 461, 1 , CONTROL(None) , SINGLE_REG(None)}, // #185 [ref=2x]
{ F(Vex) , 388, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #186 [ref=1x] { F(Vex) , 0 , 388, 1 , CONTROL(None) , SINGLE_REG(None)}, // #186 [ref=1x]
{ F(Tsib)|F(Vex) , 462, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #187 [ref=1x] { F(Tsib)|F(Vex) , 0 , 462, 1 , CONTROL(None) , SINGLE_REG(None)}, // #187 [ref=1x]
{ F(Vex) , 463, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #188 [ref=1x] { F(Vex) , 0 , 463, 1 , CONTROL(None) , SINGLE_REG(None)}, // #188 [ref=1x]
{ 0 , 464, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #189 [ref=2x] { 0 , 0 , 464, 1 , CONTROL(None) , SINGLE_REG(None)}, // #189 [ref=2x]
{ 0 , 180, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #190 [ref=2x] { 0 , 0 , 180, 1 , CONTROL(None) , SINGLE_REG(None)}, // #190 [ref=2x]
{ 0 , 465, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #191 [ref=1x] { 0 , 0 , 465, 1 , CONTROL(None) , SINGLE_REG(None)}, // #191 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512T4X)|F(Avx512KZ) , 466, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #192 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(T4X) , 466, 1 , CONTROL(None) , SINGLE_REG(None)}, // #192 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512T4X)|F(Avx512KZ) , 467, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #193 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(T4X) , 467, 1 , CONTROL(None) , SINGLE_REG(None)}, // #193 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #194 [ref=22x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64)|X(ER)|X(SAE) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #194 [ref=22x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #195 [ref=22x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32)|X(ER)|X(SAE) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #195 [ref=22x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE) , 468, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #196 [ref=18x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(ER)|X(SAE) , 468, 1 , CONTROL(None) , SINGLE_REG(None)}, // #196 [ref=18x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE) , 469, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #197 [ref=17x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(ER)|X(SAE) , 469, 1 , CONTROL(None) , SINGLE_REG(None)}, // #197 [ref=17x]
{ F(Vec)|F(Vex) , 191, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #198 [ref=15x] { F(Vec)|F(Vex) , 0 , 191, 2 , CONTROL(None) , SINGLE_REG(None)}, // #198 [ref=15x]
{ F(Vec)|F(Vex)|F(Evex) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #199 [ref=5x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #199 [ref=5x]
{ F(Vec)|F(Vex) , 79 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #200 [ref=17x] { F(Vec)|F(Vex) , 0 , 79 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #200 [ref=17x]
{ F(Vec)|F(Vex) , 215, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #201 [ref=1x] { F(Vec)|F(Vex) , 0 , 215, 1 , CONTROL(None) , SINGLE_REG(None)}, // #201 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 194, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #202 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #202 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 194, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #203 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #203 [ref=4x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #204 [ref=10x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #204 [ref=10x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #205 [ref=12x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #205 [ref=12x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #206 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) }, // #206 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #207 [ref=6x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) }, // #207 [ref=6x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #208 [ref=19x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #208 [ref=19x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #209 [ref=12x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #209 [ref=12x]
{ F(Vec)|F(Vex) , 194, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #210 [ref=6x] { F(Vec)|F(Vex) , 0 , 194, 2 , CONTROL(None) , SINGLE_REG(None)}, // #210 [ref=6x]
{ F(Vec)|F(Vex) , 348, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #211 [ref=3x] { F(Vec)|F(Vex) , 0 , 348, 2 , CONTROL(None) , SINGLE_REG(None)}, // #211 [ref=3x]
{ F(Vec)|F(Vex) , 470, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #212 [ref=2x] { F(Vec)|F(Vex)|F(EvexTransformable) , 0 , 470, 1 , CONTROL(None) , SINGLE_REG(None)}, // #212 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 471, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #213 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(Z) , 471, 1 , CONTROL(None) , SINGLE_REG(None)}, // #213 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 472, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #214 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(Z) , 472, 1 , CONTROL(None) , SINGLE_REG(None)}, // #214 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 473, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #215 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(Z) , 473, 1 , CONTROL(None) , SINGLE_REG(None)}, // #215 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 474, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #216 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(Z) , 474, 1 , CONTROL(None) , SINGLE_REG(None)}, // #216 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 471, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #217 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 471, 1 , CONTROL(None) , SINGLE_REG(None)}, // #217 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 475, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #218 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 475, 1 , CONTROL(None) , SINGLE_REG(None)}, // #218 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64) , 197, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #219 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K)|X(Z)|X(B64)|X(SAE) , 197, 3 , CONTROL(None) , SINGLE_REG(None)}, // #219 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32) , 197, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #220 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K)|X(Z)|X(B32)|X(SAE) , 197, 3 , CONTROL(None) , SINGLE_REG(None)}, // #220 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 476, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #221 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K)|X(Z)|X(SAE) , 476, 1 , CONTROL(None) , SINGLE_REG(None)}, // #221 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 477, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #222 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K)|X(Z)|X(SAE) , 477, 1 , CONTROL(None) , SINGLE_REG(None)}, // #222 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE) , 106, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #223 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(SAE) , 106, 1 , CONTROL(None) , SINGLE_REG(None)}, // #223 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE) , 257, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #224 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(SAE) , 257, 1 , CONTROL(None) , SINGLE_REG(None)}, // #224 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 200, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #225 [ref=6x] { F(Vec)|F(Evex) , X(K)|X(Z) , 200, 3 , CONTROL(None) , SINGLE_REG(None)}, // #225 [ref=6x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32) , 203, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #226 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #226 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32) , 206, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #227 [ref=3x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32)|X(ER)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #227 [ref=3x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 350, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #228 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 350, 2 , CONTROL(None) , SINGLE_REG(None)}, // #228 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 350, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #229 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64)|X(ER)|X(SAE) , 350, 2 , CONTROL(None) , SINGLE_REG(None)}, // #229 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 206, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #230 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(ER)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #230 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 350, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #231 [ref=3x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(ER)|X(SAE) , 350, 2 , CONTROL(None) , SINGLE_REG(None)}, // #231 [ref=3x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 203, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #232 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(SAE) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #232 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32) , 203, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #233 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32)|X(ER)|X(SAE) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #233 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 209, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #234 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(SAE) , 209, 3 , CONTROL(None) , SINGLE_REG(None)}, // #234 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32) , 203, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #235 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(ER)|X(SAE) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #235 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32) , 206, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #236 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(ER)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #236 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE) , 399, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #237 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(ER)|X(SAE) , 399, 1 , CONTROL(None) , SINGLE_REG(None)}, // #237 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512ER_SAE) , 399, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #238 [ref=1x] { F(Vec)|F(Evex) , X(ER)|X(SAE) , 399, 1 , CONTROL(None) , SINGLE_REG(None)}, // #238 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE) , 478, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #239 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(ER)|X(SAE) , 478, 1 , CONTROL(None) , SINGLE_REG(None)}, // #239 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 469, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #240 [ref=3x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(SAE) , 469, 1 , CONTROL(None) , SINGLE_REG(None)}, // #240 [ref=3x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE) , 401, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #241 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(ER)|X(SAE) , 401, 1 , CONTROL(None) , SINGLE_REG(None)}, // #241 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512ER_SAE) , 401, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #242 [ref=1x] { F(Vec)|F(Evex) , X(ER)|X(SAE) , 401, 1 , CONTROL(None) , SINGLE_REG(None)}, // #242 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64) , 350, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #243 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64)|X(SAE) , 350, 2 , CONTROL(None) , SINGLE_REG(None)}, // #243 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64) , 206, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #244 [ref=3x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #244 [ref=3x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64) , 350, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #245 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(SAE) , 350, 2 , CONTROL(None) , SINGLE_REG(None)}, // #245 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32) , 206, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #246 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #246 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32) , 203, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #247 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(SAE) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #247 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32) , 206, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #248 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #248 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE) , 399, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #249 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(SAE) , 399, 1 , CONTROL(None) , SINGLE_REG(None)}, // #249 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512SAE) , 399, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #250 [ref=1x] { F(Vec)|F(Evex) , X(SAE) , 399, 1 , CONTROL(None) , SINGLE_REG(None)}, // #250 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE) , 401, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #251 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(SAE) , 401, 1 , CONTROL(None) , SINGLE_REG(None)}, // #251 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512SAE) , 401, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #252 [ref=1x] { F(Vec)|F(Evex) , X(SAE) , 401, 1 , CONTROL(None) , SINGLE_REG(None)}, // #252 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 203, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #253 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #253 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512ER_SAE) , 478, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #254 [ref=2x] { F(Vec)|F(Evex) , X(ER)|X(SAE) , 478, 1 , CONTROL(None) , SINGLE_REG(None)}, // #254 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 194, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #255 [ref=3x] { F(Vec)|F(Evex) , X(K)|X(Z) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #255 [ref=3x]
{ F(Vec)|F(Vex) , 194, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #256 [ref=9x] { F(Vec)|F(Vex) , 0 , 194, 1 , CONTROL(None) , SINGLE_REG(None)}, // #256 [ref=9x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64) , 83 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #257 [ref=3x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(SAE)|X(B64) , 83 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #257 [ref=3x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32) , 83 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #258 [ref=3x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(SAE)|X(B32) , 83 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #258 [ref=3x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 206, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #259 [ref=9x] { F(Vec)|F(Evex) , X(K)|X(Z) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #259 [ref=9x]
{ F(Vec)|F(Vex) , 210, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #260 [ref=2x] { F(Vec)|F(Vex)|F(EvexTransformable) , 0 , 210, 1 , CONTROL(None) , SINGLE_REG(None)}, // #260 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 479, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #261 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(Z) , 479, 1 , CONTROL(None) , SINGLE_REG(None)}, // #261 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 211, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #262 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(Z) , 211, 1 , CONTROL(None) , SINGLE_REG(None)}, // #262 [ref=4x]
{ F(Vec)|F(Vex)|F(Evex) , 405, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #263 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 405, 1 , CONTROL(None) , SINGLE_REG(None)}, // #263 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64) , 194, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #264 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(SAE) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #264 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32) , 194, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #265 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(SAE) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #265 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE) , 480, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #266 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(SAE) , 480, 1 , CONTROL(None) , SINGLE_REG(None)}, // #266 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE) , 481, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #267 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(SAE) , 481, 1 , CONTROL(None) , SINGLE_REG(None)}, // #267 [ref=4x]
{ F(Vec)|F(Vex) , 159, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #268 [ref=13x] { F(Vec)|F(Vex) , 0 , 159, 4 , CONTROL(None) , SINGLE_REG(None)}, // #268 [ref=13x]
{ F(Vec)|F(Vex) , 352, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #269 [ref=4x] { F(Vec)|F(Vex) , 0 , 352, 2 , CONTROL(None) , SINGLE_REG(None)}, // #269 [ref=4x]
{ F(Vec)|F(Vex) , 354, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #270 [ref=4x] { F(Vec)|F(Vex) , 0 , 354, 2 , CONTROL(None) , SINGLE_REG(None)}, // #270 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512K_B64) , 482, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #271 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(B64) , 482, 1 , CONTROL(None) , SINGLE_REG(None)}, // #271 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512K_B32) , 482, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #272 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(B32) , 482, 1 , CONTROL(None) , SINGLE_REG(None)}, // #272 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512K) , 483, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #273 [ref=1x] { F(Vec)|F(Evex) , X(K) , 483, 1 , CONTROL(None) , SINGLE_REG(None)}, // #273 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512K) , 484, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #274 [ref=1x] { F(Vec)|F(Evex) , X(K) , 484, 1 , CONTROL(None) , SINGLE_REG(None)}, // #274 [ref=1x]
{ F(Vec)|F(Vex) , 206, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #275 [ref=7x] { F(Vec)|F(Vex) , 0 , 206, 2 , CONTROL(None) , SINGLE_REG(None)}, // #275 [ref=7x]
{ F(Vec)|F(Vex) , 106, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #276 [ref=1x] { F(Vec)|F(Vex) , 0 , 106, 1 , CONTROL(None) , SINGLE_REG(None)}, // #276 [ref=1x]
{ F(Vec)|F(Vex) , 257, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #277 [ref=1x] { F(Vec)|F(Vex) , 0 , 257, 1 , CONTROL(None) , SINGLE_REG(None)}, // #277 [ref=1x]
{ F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K) , 163, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #278 [ref=2x] { F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(EvexTwoOp) , X(K) , 163, 4 , CONTROL(None) , SINGLE_REG(None)}, // #278 [ref=2x]
{ F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K) , 113, 5 , CONTROL(None) , SINGLE_REG(None), 0 }, // #279 [ref=2x] { F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(EvexTwoOp) , X(K) , 113, 5 , CONTROL(None) , SINGLE_REG(None)}, // #279 [ref=2x]
{ F(Vsib)|F(Evex)|F(Avx512K) , 485, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #280 [ref=4x] { F(Vsib)|F(Evex) , X(K) , 485, 1 , CONTROL(None) , SINGLE_REG(None)}, // #280 [ref=4x]
{ F(Vsib)|F(Evex)|F(Avx512K) , 486, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #281 [ref=4x] { F(Vsib)|F(Evex) , X(K) , 486, 1 , CONTROL(None) , SINGLE_REG(None)}, // #281 [ref=4x]
{ F(Vsib)|F(Evex)|F(Avx512K) , 487, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #282 [ref=8x] { F(Vsib)|F(Evex) , X(K) , 487, 1 , CONTROL(None) , SINGLE_REG(None)}, // #282 [ref=8x]
{ F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K) , 118, 5 , CONTROL(None) , SINGLE_REG(None), 0 }, // #283 [ref=2x] { F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(EvexTwoOp) , X(K) , 118, 5 , CONTROL(None) , SINGLE_REG(None)}, // #283 [ref=2x]
{ F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K) , 212, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #284 [ref=2x] { F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(EvexTwoOp) , X(K) , 212, 3 , CONTROL(None) , SINGLE_REG(None)}, // #284 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE) , 468, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #285 [ref=3x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(SAE) , 468, 1 , CONTROL(None) , SINGLE_REG(None)}, // #285 [ref=3x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE) , 469, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #286 [ref=3x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(SAE) , 469, 1 , CONTROL(None) , SINGLE_REG(None)}, // #286 [ref=3x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64) , 215, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #287 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(SAE) , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #287 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32) , 215, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #288 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(SAE) , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #288 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 194, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #289 [ref=3x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #289 [ref=3x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #290 [ref=22x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #290 [ref=22x]
{ F(Vec)|F(Vex) , 356, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #291 [ref=2x] { F(Vec)|F(Vex)|F(EvexTransformable) , 0 , 356, 1 , CONTROL(None) , SINGLE_REG(None)}, // #291 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 356, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #292 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(Z) , 356, 2 , CONTROL(None) , SINGLE_REG(None)}, // #292 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 488, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #293 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(Z) , 488, 1 , CONTROL(None) , SINGLE_REG(None)}, // #293 [ref=4x]
{ F(Vec)|F(Vex)|F(Evex) , 481, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #294 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 481, 1 , CONTROL(None) , SINGLE_REG(None)}, // #294 [ref=1x]
{ F(Vec)|F(Vex) , 224, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #295 [ref=1x] { F(Vec)|F(Vex) , 0 , 224, 2 , CONTROL(None) , SINGLE_REG(None)}, // #295 [ref=1x]
{ F(Vex) , 423, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #296 [ref=2x] { F(Vex) , 0 , 423, 1 , CONTROL(None) , SINGLE_REG(None)}, // #296 [ref=2x]
{ F(Vec)|F(Vex) , 429, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #297 [ref=1x] { F(Vec)|F(Vex) , 0 , 429, 1 , CONTROL(None) , SINGLE_REG(None)}, // #297 [ref=1x]
{ F(Vec)|F(Vex) , 167, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #298 [ref=4x] { F(Vec)|F(Vex) , 0 , 167, 4 , CONTROL(None) , SINGLE_REG(None)}, // #298 [ref=4x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #299 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64)|X(SAE) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #299 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #300 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32)|X(SAE) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #300 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE) , 468, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #301 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(SAE) , 468, 1 , CONTROL(None) , SINGLE_REG(None)}, // #301 [ref=2x]
{ 0 , 358, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #302 [ref=3x] { 0 , 0 , 358, 2 , CONTROL(None) , SINGLE_REG(None)}, // #302 [ref=3x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 79 , 6 , CONTROL(None) , SINGLE_REG(None), 0 }, // #303 [ref=4x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 79 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #303 [ref=4x]
{ F(Vec)|F(Vex)|F(Evex) , 360, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #304 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 360, 2 , CONTROL(None) , SINGLE_REG(None)}, // #304 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 218, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #305 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 218, 3 , CONTROL(None) , SINGLE_REG(None)}, // #305 [ref=1x]
{ F(Vec)|F(Vex) , 79 , 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #306 [ref=2x] { F(Vec)|F(Vex)|F(EvexTransformable) , 0 , 79 , 4 , CONTROL(None) , SINGLE_REG(None)}, // #306 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 79 , 6 , CONTROL(None) , SINGLE_REG(None), 0 }, // #307 [ref=6x] { F(Vec)|F(Evex) , X(K)|X(Z) , 79 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #307 [ref=6x]
{ F(Vec)|F(Vex)|F(Evex) , 232, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #308 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 232, 1 , CONTROL(None) , SINGLE_REG(None)}, // #308 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex) , 362, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #309 [ref=4x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 362, 2 , CONTROL(None) , SINGLE_REG(None)}, // #309 [ref=4x]
{ F(Vec)|F(Vex) , 489, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #310 [ref=3x] { F(Vec)|F(Vex) , 0 , 489, 1 , CONTROL(None) , SINGLE_REG(None)}, // #310 [ref=3x]
{ F(Vec)|F(Vex)|F(Evex) , 221, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #311 [ref=3x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 221, 3 , CONTROL(None) , SINGLE_REG(None)}, // #311 [ref=3x]
{ F(Vec)|F(Vex)|F(Evex) , 224, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #312 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 224, 3 , CONTROL(None) , SINGLE_REG(None)}, // #312 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex) , 227, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #313 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 227, 3 , CONTROL(None) , SINGLE_REG(None)}, // #313 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 230, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #314 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 230, 3 , CONTROL(None) , SINGLE_REG(None)}, // #314 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 206, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #315 [ref=5x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #315 [ref=5x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 233, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #316 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 233, 3 , CONTROL(None) , SINGLE_REG(None)}, // #316 [ref=1x]
{ 0 , 364, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #317 [ref=1x] { 0 , 0 , 364, 2 , CONTROL(None) , SINGLE_REG(None)}, // #317 [ref=1x]
{ 0 , 366, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #318 [ref=1x] { 0 , 0 , 366, 2 , CONTROL(None) , SINGLE_REG(None)}, // #318 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512B32) , 236, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #319 [ref=1x] { F(Vec)|F(Evex) , X(B32) , 236, 3 , CONTROL(None) , SINGLE_REG(None)}, // #319 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512B64) , 236, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #320 [ref=1x] { F(Vec)|F(Evex) , X(B64) , 236, 3 , CONTROL(None) , SINGLE_REG(None)}, // #320 [ref=1x]
{ F(Vec)|F(Vex) , 191, 2 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #321 [ref=2x] { F(Vec)|F(Vex)|F(EvexTransformable) , 0 , 191, 2 , CONTROL(None) , SINGLE_REG(RO) }, // #321 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #322 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) }, // #322 [ref=2x]
{ F(Vec)|F(Vex) , 191, 2 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #323 [ref=2x] { F(Vec)|F(Vex)|F(EvexTransformable) , 0 , 191, 2 , CONTROL(None) , SINGLE_REG(WO) }, // #323 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #324 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #324 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #325 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #325 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #326 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) }, // #326 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #327 [ref=13x] { F(Vec)|F(Evex) , X(K)|X(Z) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #327 [ref=13x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 490, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #328 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 490, 1 , CONTROL(None) , SINGLE_REG(None)}, // #328 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 491, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #329 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 491, 1 , CONTROL(None) , SINGLE_REG(None)}, // #329 [ref=1x]
{ F(Vec)|F(Evex) , 492, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #330 [ref=6x] { F(Vec)|F(Evex) , 0 , 492, 1 , CONTROL(None) , SINGLE_REG(None)}, // #330 [ref=6x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 239, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #331 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 239, 3 , CONTROL(None) , SINGLE_REG(None)}, // #331 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 493, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #332 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 493, 1 , CONTROL(None) , SINGLE_REG(None)}, // #332 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex) , 194, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #333 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #333 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512K) , 242, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #334 [ref=2x] { F(Vec)|F(Evex) , X(K) , 242, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #334 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512K_B32) , 242, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #335 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(B32) , 242, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #335 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512K) , 245, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #336 [ref=4x] { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K) , 245, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #336 [ref=4x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512K_B32) , 245, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #337 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K)|X(B32) , 245, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #337 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512K_B64) , 245, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #338 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K)|X(B64) , 245, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #338 [ref=2x]
{ F(Vec)|F(Vex) , 442, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #339 [ref=1x] { F(Vec)|F(Vex) , 0 , 442, 1 , CONTROL(None) , SINGLE_REG(None)}, // #339 [ref=1x]
{ F(Vec)|F(Vex) , 443, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #340 [ref=1x] { F(Vec)|F(Vex) , 0 , 443, 1 , CONTROL(None) , SINGLE_REG(None)}, // #340 [ref=1x]
{ F(Vec)|F(Vex) , 444, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #341 [ref=1x] { F(Vec)|F(Vex) , 0 , 444, 1 , CONTROL(None) , SINGLE_REG(None)}, // #341 [ref=1x]
{ F(Vec)|F(Vex) , 445, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #342 [ref=1x] { F(Vec)|F(Vex) , 0 , 445, 1 , CONTROL(None) , SINGLE_REG(None)}, // #342 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512K_B64) , 242, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #343 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(B64) , 242, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #343 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 206, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #344 [ref=6x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #344 [ref=6x]
{ F(Vec)|F(Vex)|F(Evex)|F(PreferEvex)|F(Avx512KZ_B32) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #345 [ref=4x] { F(Vec)|F(Vex)|F(Evex)|F(PreferEvex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #345 [ref=4x]
{ F(Vec)|F(Vex) , 195, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #346 [ref=2x] { F(Vec)|F(Vex) , 0 , 195, 1 , CONTROL(None) , SINGLE_REG(None)}, // #346 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32) , 192, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #347 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 192, 2 , CONTROL(None) , SINGLE_REG(None)}, // #347 [ref=2x]
{ F(Vec)|F(Vex) , 171, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #348 [ref=2x] { F(Vec)|F(Vex) , 0 , 171, 4 , CONTROL(None) , SINGLE_REG(None)}, // #348 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64) , 85 , 6 , CONTROL(None) , SINGLE_REG(None), 0 }, // #349 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 85 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #349 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64) , 175, 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #350 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 175, 4 , CONTROL(None) , SINGLE_REG(None)}, // #350 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex) , 446, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #351 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 446, 1 , CONTROL(None) , SINGLE_REG(None)}, // #351 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex) , 447, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #352 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 447, 1 , CONTROL(None) , SINGLE_REG(None)}, // #352 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex) , 494, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #353 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 494, 1 , CONTROL(None) , SINGLE_REG(None)}, // #353 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 495, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #354 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 495, 1 , CONTROL(None) , SINGLE_REG(None)}, // #354 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 496, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #355 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 496, 1 , CONTROL(None) , SINGLE_REG(None)}, // #355 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 497, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #356 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 497, 1 , CONTROL(None) , SINGLE_REG(None)}, // #356 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 498, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #357 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 498, 1 , CONTROL(None) , SINGLE_REG(None)}, // #357 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 206, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #358 [ref=4x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #358 [ref=4x]
{ F(Vec)|F(Vex) , 348, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #359 [ref=12x] { F(Vec)|F(Vex) , 0 , 348, 1 , CONTROL(None) , SINGLE_REG(None)}, // #359 [ref=12x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #360 [ref=8x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) }, // #360 [ref=8x]
{ F(Vec)|F(Evex) , 499, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #361 [ref=4x] { F(Vec)|F(Evex) , 0 , 499, 1 , CONTROL(None) , SINGLE_REG(None)}, // #361 [ref=4x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 248, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #362 [ref=6x] { F(Vec)|F(Evex) , X(K)|X(Z) , 248, 3 , CONTROL(None) , SINGLE_REG(None)}, // #362 [ref=6x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 251, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #363 [ref=9x] { F(Vec)|F(Evex) , X(K)|X(Z) , 251, 3 , CONTROL(None) , SINGLE_REG(None)}, // #363 [ref=9x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 254, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #364 [ref=3x] { F(Vec)|F(Evex) , X(K)|X(Z) , 254, 3 , CONTROL(None) , SINGLE_REG(None)}, // #364 [ref=3x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 257, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #365 [ref=4x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 257, 3 , CONTROL(None) , SINGLE_REG(None)}, // #365 [ref=4x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 260, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #366 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 260, 3 , CONTROL(None) , SINGLE_REG(None)}, // #366 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 203, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #367 [ref=6x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #367 [ref=6x]
{ F(Vec)|F(Vex) , 159, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #368 [ref=1x] { F(Vec)|F(Vex) , 0 , 159, 2 , CONTROL(None) , SINGLE_REG(None)}, // #368 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 215, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #369 [ref=3x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #369 [ref=3x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 215, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #370 [ref=3x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #370 [ref=3x]
{ F(Vec)|F(Vex) , 368, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #371 [ref=4x] { F(Vec)|F(Vex) , 0 , 368, 2 , CONTROL(None) , SINGLE_REG(None)}, // #371 [ref=4x]
{ F(Vec)|F(Vsib)|F(Evex)|F(Avx512K) , 263, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #372 [ref=2x] { F(Vec)|F(Vsib)|F(Evex) , X(K) , 263, 3 , CONTROL(None) , SINGLE_REG(None)}, // #372 [ref=2x]
{ F(Vec)|F(Vsib)|F(Evex)|F(Avx512K) , 370, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #373 [ref=2x] { F(Vec)|F(Vsib)|F(Evex) , X(K) , 370, 2 , CONTROL(None) , SINGLE_REG(None)}, // #373 [ref=2x]
{ F(Vec)|F(Vsib)|F(Evex)|F(Avx512K) , 372, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #374 [ref=2x] { F(Vec)|F(Vsib)|F(Evex) , X(K) , 372, 2 , CONTROL(None) , SINGLE_REG(None)}, // #374 [ref=2x]
{ F(Vec)|F(Vsib)|F(Evex)|F(Avx512K) , 266, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #375 [ref=2x] { F(Vec)|F(Vsib)|F(Evex) , X(K) , 266, 3 , CONTROL(None) , SINGLE_REG(None)}, // #375 [ref=2x]
{ F(Vec)|F(Vex) , 374, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #376 [ref=8x] { F(Vec)|F(Vex) , 0 , 374, 2 , CONTROL(None) , SINGLE_REG(None)}, // #376 [ref=8x]
{ F(Vec)|F(Evex)|F(Avx512K) , 269, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #377 [ref=5x] { F(Vec)|F(Evex) , X(K) , 269, 3 , CONTROL(None) , SINGLE_REG(None)}, // #377 [ref=5x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32) , 215, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #378 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #378 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 215, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #379 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #379 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32) , 91 , 6 , CONTROL(None) , SINGLE_REG(None), 0 }, // #380 [ref=3x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 91 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #380 [ref=3x]
{ F(Vec)|F(Vex)|F(Evex) , 215, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #381 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #381 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64) , 91 , 6 , CONTROL(None) , SINGLE_REG(None), 0 }, // #382 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 91 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #382 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 91 , 6 , CONTROL(None) , SINGLE_REG(None), 0 }, // #383 [ref=3x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 91 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #383 [ref=3x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 97 , 6 , CONTROL(None) , SINGLE_REG(None), 0 }, // #384 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 97 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #384 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #385 [ref=6x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #385 [ref=6x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #386 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #386 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) , 0 }, // #387 [ref=2x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #387 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512K_B32) , 269, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #388 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(B32) , 269, 3 , CONTROL(None) , SINGLE_REG(None)}, // #388 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512K_B64) , 269, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #389 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(B64) , 269, 3 , CONTROL(None) , SINGLE_REG(None)}, // #389 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 468, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #390 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z) , 468, 1 , CONTROL(None) , SINGLE_REG(None)}, // #390 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 469, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #391 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z) , 469, 1 , CONTROL(None) , SINGLE_REG(None)}, // #391 [ref=2x]
{ F(Vec)|F(Vex) , 469, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #392 [ref=2x] { F(Vec)|F(Vex) , 0 , 469, 1 , CONTROL(None) , SINGLE_REG(None)}, // #392 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 480, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #393 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(Z) , 480, 1 , CONTROL(None) , SINGLE_REG(None)}, // #393 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ) , 481, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #394 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(Z) , 481, 1 , CONTROL(None) , SINGLE_REG(None)}, // #394 [ref=1x]
{ F(Vec)|F(Vex) , 215, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #395 [ref=2x] { F(Vec)|F(Vex) , 0 , 215, 2 , CONTROL(None) , SINGLE_REG(None)}, // #395 [ref=2x]
{ F(Vec)|F(Vex) , 480, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #396 [ref=1x] { F(Vec)|F(Vex) , 0 , 480, 1 , CONTROL(None) , SINGLE_REG(None)}, // #396 [ref=1x]
{ F(Vec)|F(Vex) , 481, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #397 [ref=1x] { F(Vec)|F(Vex) , 0 , 481, 1 , CONTROL(None) , SINGLE_REG(None)}, // #397 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #398 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(ER)|X(SAE) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #398 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32) , 191, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #399 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(ER)|X(SAE) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #399 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE) , 468, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #400 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(ER)|X(SAE) , 468, 1 , CONTROL(None) , SINGLE_REG(None)}, // #400 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE) , 469, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #401 [ref=1x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(ER)|X(SAE) , 469, 1 , CONTROL(None) , SINGLE_REG(None)}, // #401 [ref=1x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B32) , 195, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #402 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 195, 2 , CONTROL(None) , SINGLE_REG(None)}, // #402 [ref=2x]
{ F(Vec)|F(Evex)|F(Avx512KZ_B64) , 195, 2 , CONTROL(None) , SINGLE_REG(None), 0 }, // #403 [ref=2x] { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 195, 2 , CONTROL(None) , SINGLE_REG(None)}, // #403 [ref=2x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32) , 194, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #404 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #404 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64) , 194, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #405 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #405 [ref=1x]
{ F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64) , 206, 3 , CONTROL(None) , SINGLE_REG(None), 0 }, // #406 [ref=1x] { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64)|X(ER)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #406 [ref=1x]
{ F(Vec)|F(Vex) , 108, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #407 [ref=2x] { F(Vec)|F(Vex) , 0 , 108, 1 , CONTROL(None) , SINGLE_REG(None)}, // #407 [ref=2x]
{ 0 , 23 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #408 [ref=2x] { 0 , 0 , 23 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #408 [ref=2x]
{ 0 , 61 , 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #409 [ref=2x] { 0 , 0 , 61 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #409 [ref=2x]
{ F(Lock)|F(XAcquire)|F(XRelease) , 58 , 4 , CONTROL(None) , SINGLE_REG(None), 0 }, // #410 [ref=1x] { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 58 , 4 , CONTROL(None) , SINGLE_REG(None)}, // #410 [ref=1x]
{ 0 , 500, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #411 [ref=1x] { 0 , 0 , 500, 1 , CONTROL(None) , SINGLE_REG(None)}, // #411 [ref=1x]
{ F(Lock)|F(XAcquire) , 58 , 8 , CONTROL(None) , SINGLE_REG(RO) , 0 }, // #412 [ref=1x] { F(Lock)|F(XAcquire) , 0 , 58 , 8 , CONTROL(None) , SINGLE_REG(RO) }, // #412 [ref=1x]
{ 0 , 501, 1 , CONTROL(None) , SINGLE_REG(None), 0 }, // #413 [ref=6x] { 0 , 0 , 501, 1 , CONTROL(None) , SINGLE_REG(None)}, // #413 [ref=6x]
{ 0 , 502, 1 , CONTROL(None) , SINGLE_REG(None), 0 } // #414 [ref=6x] { 0 , 0 , 502, 1 , CONTROL(None) , SINGLE_REG(None)} // #414 [ref=6x]
}; };
#undef SINGLE_REG #undef SINGLE_REG
#undef CONTROL #undef CONTROL
#undef X
#undef F #undef F
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ${InstCommonTable:End} // ${InstCommonTable:End}

View File

@@ -40,10 +40,14 @@ namespace InstDB {
//! Describes which mode is supported by an instruction or instruction signature. //! Describes which mode is supported by an instruction or instruction signature.
enum Mode : uint32_t { enum Mode : uint32_t {
kModeNone = 0x00u, //!< Invalid. //! Invalid mode.
kModeX86 = 0x01u, //!< X86 mode supported. kModeNone = 0x00u,
kModeX64 = 0x02u, //!< X64 mode supported. //! X86 mode supported.
kModeAny = 0x03u //!< Both X86 and X64 modes supported. kModeX86 = 0x01u,
//! X64 mode supported.
kModeX64 = 0x02u,
//! Both X86 and X64 modes supported.
kModeAny = 0x03u
}; };
static constexpr uint32_t modeFromArch(uint32_t arch) noexcept { static constexpr uint32_t modeFromArch(uint32_t arch) noexcept {
@@ -57,45 +61,45 @@ static constexpr uint32_t modeFromArch(uint32_t arch) noexcept {
//! Operand flags (X86). //! Operand flags (X86).
enum OpFlags : uint32_t { enum OpFlags : uint32_t {
kOpNone = 0x00000000u, //!< No flags. kOpNone = 0x00000000u, //!< No flags.
kOpGpbLo = 0x00000001u, //!< Operand can be low 8-bit GPB register. kOpGpbLo = 0x00000001u, //!< Operand can be low 8-bit GPB register.
kOpGpbHi = 0x00000002u, //!< Operand can be high 8-bit GPB register. kOpGpbHi = 0x00000002u, //!< Operand can be high 8-bit GPB register.
kOpGpw = 0x00000004u, //!< Operand can be 16-bit GPW register. kOpGpw = 0x00000004u, //!< Operand can be 16-bit GPW register.
kOpGpd = 0x00000008u, //!< Operand can be 32-bit GPD register. kOpGpd = 0x00000008u, //!< Operand can be 32-bit GPD register.
kOpGpq = 0x00000010u, //!< Operand can be 64-bit GPQ register. kOpGpq = 0x00000010u, //!< Operand can be 64-bit GPQ register.
kOpXmm = 0x00000020u, //!< Operand can be 128-bit XMM register. kOpXmm = 0x00000020u, //!< Operand can be 128-bit XMM register.
kOpYmm = 0x00000040u, //!< Operand can be 256-bit YMM register. kOpYmm = 0x00000040u, //!< Operand can be 256-bit YMM register.
kOpZmm = 0x00000080u, //!< Operand can be 512-bit ZMM register. kOpZmm = 0x00000080u, //!< Operand can be 512-bit ZMM register.
kOpMm = 0x00000100u, //!< Operand can be 64-bit MM register. kOpMm = 0x00000100u, //!< Operand can be 64-bit MM register.
kOpKReg = 0x00000200u, //!< Operand can be 64-bit K register. kOpKReg = 0x00000200u, //!< Operand can be 64-bit K register.
kOpSReg = 0x00000400u, //!< Operand can be SReg (segment register). kOpSReg = 0x00000400u, //!< Operand can be SReg (segment register).
kOpCReg = 0x00000800u, //!< Operand can be CReg (control register). kOpCReg = 0x00000800u, //!< Operand can be CReg (control register).
kOpDReg = 0x00001000u, //!< Operand can be DReg (debug register). kOpDReg = 0x00001000u, //!< Operand can be DReg (debug register).
kOpSt = 0x00002000u, //!< Operand can be 80-bit ST register (X87). kOpSt = 0x00002000u, //!< Operand can be 80-bit ST register (X87).
kOpBnd = 0x00004000u, //!< Operand can be 128-bit BND register. kOpBnd = 0x00004000u, //!< Operand can be 128-bit BND register.
kOpTmm = 0x00008000u, //!< Operand can be 0..8192-bit TMM register. kOpTmm = 0x00008000u, //!< Operand can be 0..8192-bit TMM register.
kOpAllRegs = 0x0000FFFFu, //!< Combination of all possible registers. kOpAllRegs = 0x0000FFFFu, //!< Combination of all possible registers.
kOpI4 = 0x00010000u, //!< Operand can be unsigned 4-bit immediate. kOpI4 = 0x00010000u, //!< Operand can be unsigned 4-bit immediate.
kOpU4 = 0x00020000u, //!< Operand can be unsigned 4-bit immediate. kOpU4 = 0x00020000u, //!< Operand can be unsigned 4-bit immediate.
kOpI8 = 0x00040000u, //!< Operand can be signed 8-bit immediate. kOpI8 = 0x00040000u, //!< Operand can be signed 8-bit immediate.
kOpU8 = 0x00080000u, //!< Operand can be unsigned 8-bit immediate. kOpU8 = 0x00080000u, //!< Operand can be unsigned 8-bit immediate.
kOpI16 = 0x00100000u, //!< Operand can be signed 16-bit immediate. kOpI16 = 0x00100000u, //!< Operand can be signed 16-bit immediate.
kOpU16 = 0x00200000u, //!< Operand can be unsigned 16-bit immediate. kOpU16 = 0x00200000u, //!< Operand can be unsigned 16-bit immediate.
kOpI32 = 0x00400000u, //!< Operand can be signed 32-bit immediate. kOpI32 = 0x00400000u, //!< Operand can be signed 32-bit immediate.
kOpU32 = 0x00800000u, //!< Operand can be unsigned 32-bit immediate. kOpU32 = 0x00800000u, //!< Operand can be unsigned 32-bit immediate.
kOpI64 = 0x01000000u, //!< Operand can be signed 64-bit immediate. kOpI64 = 0x01000000u, //!< Operand can be signed 64-bit immediate.
kOpU64 = 0x02000000u, //!< Operand can be unsigned 64-bit immediate. kOpU64 = 0x02000000u, //!< Operand can be unsigned 64-bit immediate.
kOpAllImm = 0x03FF0000u, //!< Operand can be any immediate. kOpAllImm = 0x03FF0000u, //!< Operand can be any immediate.
kOpMem = 0x04000000u, //!< Operand can be a scalar memory pointer. kOpMem = 0x04000000u, //!< Operand can be a scalar memory pointer.
kOpVm = 0x08000000u, //!< Operand can be a vector memory pointer. kOpVm = 0x08000000u, //!< Operand can be a vector memory pointer.
kOpRel8 = 0x10000000u, //!< Operand can be relative 8-bit displacement. kOpRel8 = 0x10000000u, //!< Operand can be relative 8-bit displacement.
kOpRel32 = 0x20000000u, //!< Operand can be relative 32-bit displacement. kOpRel32 = 0x20000000u, //!< Operand can be relative 32-bit displacement.
kOpImplicit = 0x80000000u //!< Operand is implicit. kOpImplicit = 0x80000000u //!< Operand is implicit.
}; };
// ============================================================================ // ============================================================================
@@ -107,31 +111,31 @@ enum MemFlags : uint32_t {
// NOTE: Instruction uses either scalar or vector memory operands, they never // NOTE: Instruction uses either scalar or vector memory operands, they never
// collide. This allows us to share bits between "M" and "Vm" enums. // collide. This allows us to share bits between "M" and "Vm" enums.
kMemOpAny = 0x0001u, //!< Operand can be any scalar memory pointer. kMemOpAny = 0x0001u, //!< Operand can be any scalar memory pointer.
kMemOpM8 = 0x0002u, //!< Operand can be an 8-bit memory pointer. kMemOpM8 = 0x0002u, //!< Operand can be an 8-bit memory pointer.
kMemOpM16 = 0x0004u, //!< Operand can be a 16-bit memory pointer. kMemOpM16 = 0x0004u, //!< Operand can be a 16-bit memory pointer.
kMemOpM32 = 0x0008u, //!< Operand can be a 32-bit memory pointer. kMemOpM32 = 0x0008u, //!< Operand can be a 32-bit memory pointer.
kMemOpM48 = 0x0010u, //!< Operand can be a 48-bit memory pointer (FAR pointers only). kMemOpM48 = 0x0010u, //!< Operand can be a 48-bit memory pointer (FAR pointers only).
kMemOpM64 = 0x0020u, //!< Operand can be a 64-bit memory pointer. kMemOpM64 = 0x0020u, //!< Operand can be a 64-bit memory pointer.
kMemOpM80 = 0x0040u, //!< Operand can be an 80-bit memory pointer. kMemOpM80 = 0x0040u, //!< Operand can be an 80-bit memory pointer.
kMemOpM128 = 0x0080u, //!< Operand can be a 128-bit memory pointer. kMemOpM128 = 0x0080u, //!< Operand can be a 128-bit memory pointer.
kMemOpM256 = 0x0100u, //!< Operand can be a 256-bit memory pointer. kMemOpM256 = 0x0100u, //!< Operand can be a 256-bit memory pointer.
kMemOpM512 = 0x0200u, //!< Operand can be a 512-bit memory pointer. kMemOpM512 = 0x0200u, //!< Operand can be a 512-bit memory pointer.
kMemOpM1024 = 0x0400u, //!< Operand can be a 1024-bit memory pointer. kMemOpM1024 = 0x0400u, //!< Operand can be a 1024-bit memory pointer.
kMemOpVm32x = 0x0002u, //!< Operand can be a vm32x (vector) pointer. kMemOpVm32x = 0x0002u, //!< Operand can be a vm32x (vector) pointer.
kMemOpVm32y = 0x0004u, //!< Operand can be a vm32y (vector) pointer. kMemOpVm32y = 0x0004u, //!< Operand can be a vm32y (vector) pointer.
kMemOpVm32z = 0x0008u, //!< Operand can be a vm32z (vector) pointer. kMemOpVm32z = 0x0008u, //!< Operand can be a vm32z (vector) pointer.
kMemOpVm64x = 0x0020u, //!< Operand can be a vm64x (vector) pointer. kMemOpVm64x = 0x0020u, //!< Operand can be a vm64x (vector) pointer.
kMemOpVm64y = 0x0040u, //!< Operand can be a vm64y (vector) pointer. kMemOpVm64y = 0x0040u, //!< Operand can be a vm64y (vector) pointer.
kMemOpVm64z = 0x0080u, //!< Operand can be a vm64z (vector) pointer. kMemOpVm64z = 0x0080u, //!< Operand can be a vm64z (vector) pointer.
kMemOpBaseOnly = 0x0800u, //!< Only memory base is allowed (no index, no offset). kMemOpBaseOnly = 0x0800u, //!< Only memory base is allowed (no index, no offset).
kMemOpDs = 0x1000u, //!< Implicit memory operand's DS segment. kMemOpDs = 0x1000u, //!< Implicit memory operand's DS segment.
kMemOpEs = 0x2000u, //!< Implicit memory operand's ES segment. kMemOpEs = 0x2000u, //!< Implicit memory operand's ES segment.
kMemOpMib = 0x4000u, //!< Operand must be MIB (base+index) pointer. kMemOpMib = 0x4000u, //!< Operand must be MIB (base+index) pointer.
kMemOpTMem = 0x8000u //!< Operand is a sib_mem (ADX memory operand). kMemOpTMem = 0x8000u //!< Operand is a sib_mem (ADX memory operand).
}; };
// ============================================================================ // ============================================================================
@@ -142,76 +146,69 @@ enum MemFlags : uint32_t {
//! //!
//! Details about instruction encoding, operation, features, and some limitations. //! Details about instruction encoding, operation, features, and some limitations.
enum Flags : uint32_t { enum Flags : uint32_t {
kFlagNone = 0x00000000u, //!< No flags. kFlagNone = 0x00000000u, //!< No flags.
// Instruction Family // Instruction Family
// ------------------ // ------------------
// //
// Instruction family information. // Instruction family information.
kFlagFpu = 0x00000100u, //!< Instruction that accesses FPU registers. kFlagFpu = 0x00000100u, //!< Instruction that accesses FPU registers.
kFlagMmx = 0x00000200u, //!< Instruction that accesses MMX registers (including 3DNOW and GEODE) and EMMS. kFlagMmx = 0x00000200u, //!< Instruction that accesses MMX registers (including 3DNOW and GEODE) and EMMS.
kFlagVec = 0x00000400u, //!< Instruction that accesses XMM registers (SSE, AVX, AVX512). kFlagVec = 0x00000400u, //!< Instruction that accesses XMM registers (SSE, AVX, AVX512).
// Prefixes and Encoding Flags
// ---------------------------
//
// These describe optional X86 prefixes that can be used to change the instruction's operation.
kFlagTsib = 0x00000800u, //!< Instruction uses TSIB (or SIB_MEM) encoding (MODRM followed by SIB).
kFlagRep = 0x00001000u, //!< Instruction can be prefixed with using the REP(REPE) or REPNE prefix.
kFlagRepIgnored = 0x00002000u, //!< Instruction ignores REP|REPNE prefixes, but they are accepted.
kFlagLock = 0x00004000u, //!< Instruction can be prefixed with using the LOCK prefix.
kFlagXAcquire = 0x00008000u, //!< Instruction can be prefixed with using the XACQUIRE prefix.
kFlagXRelease = 0x00010000u, //!< Instruction can be prefixed with using the XRELEASE prefix.
kFlagMib = 0x00020000u, //!< Instruction uses MIB (BNDLDX|BNDSTX) to encode two registers.
kFlagVsib = 0x00040000u, //!< Instruction uses VSIB instead of legacy SIB.
kFlagVex = 0x00080000u, //!< Instruction can be encoded by VEX|XOP (AVX|AVX2|BMI|XOP|...).
kFlagEvex = 0x00100000u, //!< Instruction can be encoded by EVEX (AVX512).
kFlagPreferEvex = 0x00200000u, //!< EVEX encoding is preferred over VEX encoding (AVX515_VNNI vs AVX_VNNI).
// FPU Flags // FPU Flags
// --------- // ---------
// //
// Used to tell the encoder which memory operand sizes are encodable. // Used to tell the encoder which memory operand sizes are encodable.
kFlagFpuM16 = 0x00200000u, //!< FPU instruction can address `word_ptr` (shared with M80). kFlagFpuM16 = 0x00000800u, //!< FPU instruction can address `word_ptr` (shared with M80).
kFlagFpuM32 = 0x00400000u, //!< FPU instruction can address `dword_ptr`. kFlagFpuM32 = 0x00001000u, //!< FPU instruction can address `dword_ptr`.
kFlagFpuM64 = 0x00800000u, //!< FPU instruction can address `qword_ptr`. kFlagFpuM64 = 0x00002000u, //!< FPU instruction can address `qword_ptr`.
kFlagFpuM80 = 0x00200000u, //!< FPU instruction can address `tword_ptr` (shared with M16). kFlagFpuM80 = 0x00000800u, //!< FPU instruction can address `tword_ptr` (shared with M16).
// AVX and AVX515 Flags // Prefixes and Encoding Flags
// -------------------- // ---------------------------
// //
// These describe optional X86 prefixes that can be used to change the instruction's operation.
kFlagTsib = 0x00004000u, //!< Instruction uses TSIB (or SIB_MEM) encoding (MODRM followed by SIB).
kFlagRep = 0x00008000u, //!< Instruction can be prefixed with using the REP(REPE) or REPNE prefix.
kFlagRepIgnored = 0x00010000u, //!< Instruction ignores REP|REPNE prefixes, but they are accepted.
kFlagLock = 0x00020000u, //!< Instruction can be prefixed with using the LOCK prefix.
kFlagXAcquire = 0x00040000u, //!< Instruction can be prefixed with using the XACQUIRE prefix.
kFlagXRelease = 0x00080000u, //!< Instruction can be prefixed with using the XRELEASE prefix.
kFlagMib = 0x00100000u, //!< Instruction uses MIB (BNDLDX|BNDSTX) to encode two registers.
kFlagVsib = 0x00200000u, //!< Instruction uses VSIB instead of legacy SIB.
// If both `kFlagPrefixVex` and `kFlagPrefixEvex` flags are specified it // If both `kFlagPrefixVex` and `kFlagPrefixEvex` flags are specified it
// means that the instructions can be encoded by either VEX or EVEX prefix. // means that the instructions can be encoded by either VEX or EVEX prefix.
// In that case AsmJit checks global options and also instruction options // In that case AsmJit checks global options and also instruction options
// to decide whether to emit VEX or EVEX prefix. // to decide whether to emit VEX or EVEX prefix.
kFlagAvx512_ = 0x00000000u, //!< Internally used in tables, has no meaning. kFlagVex = 0x00400000u, //!< Instruction can be encoded by VEX|XOP (AVX|AVX2|BMI|XOP|...).
kFlagAvx512K = 0x01000000u, //!< Supports masking {k1..k7}. kFlagEvex = 0x00800000u, //!< Instruction can be encoded by EVEX (AVX512).
kFlagAvx512Z = 0x02000000u, //!< Supports zeroing {z}, must be used together with `kAvx512k`. kFlagPreferEvex = 0x01000000u, //!< EVEX encoding is preferred over VEX encoding (AVX515_VNNI vs AVX_VNNI).
kFlagAvx512ER = 0x04000000u, //!< Supports 'embedded-rounding' {er} with implicit {sae}, kFlagEvexCompat = 0x02000000u, //!< EVEX and VEX signatures are compatible.
kFlagAvx512SAE = 0x08000000u, //!< Supports 'suppress-all-exceptions' {sae}. kFlagEvexKReg = 0x04000000u, //!< EVEX instruction requires K register in the first operand (compare instructions).
kFlagAvx512B32 = 0x10000000u, //!< Supports 32-bit broadcast 'b32'. kFlagEvexTwoOp = 0x08000000u, //!< EVEX instruction requires two operands and K register as a selector (gather instructions).
kFlagAvx512B64 = 0x20000000u, //!< Supports 64-bit broadcast 'b64'. kFlagEvexTransformable = 0x10000000u //!< VEX instruction that can be transformed to a compatible EVEX instruction.
kFlagAvx512T4X = 0x80000000u, //!< Operates on a vector of consecutive registers (AVX512_4FMAPS and AVX512_4VNNIW). };
// Combinations used by instruction tables to make AVX512 definitions more compact. // ============================================================================
kFlagAvx512KZ = kFlagAvx512K | kFlagAvx512Z, // [asmjit::x86::InstDB::Avx512Flags]
kFlagAvx512ER_SAE = kFlagAvx512ER | kFlagAvx512SAE, // ============================================================================
kFlagAvx512KZ_SAE = kFlagAvx512KZ | kFlagAvx512SAE,
kFlagAvx512KZ_SAE_B32 = kFlagAvx512KZ_SAE | kFlagAvx512B32,
kFlagAvx512KZ_SAE_B64 = kFlagAvx512KZ_SAE | kFlagAvx512B64,
kFlagAvx512KZ_ER_SAE = kFlagAvx512KZ | kFlagAvx512ER_SAE, //! AVX512 flags.
kFlagAvx512KZ_ER_SAE_B32 = kFlagAvx512KZ_ER_SAE | kFlagAvx512B32, enum Avx512Flags : uint32_t {
kFlagAvx512KZ_ER_SAE_B64 = kFlagAvx512KZ_ER_SAE | kFlagAvx512B64, kAvx512Flag_ = 0x00000000u, //!< Internally used in tables, has no meaning.
kAvx512FlagK = 0x00000001u, //!< Supports masking {k1..k7}.
kFlagAvx512K_B32 = kFlagAvx512K | kFlagAvx512B32, kAvx512FlagZ = 0x00000002u, //!< Supports zeroing {z}, must be used together with `kAvx512k`.
kFlagAvx512K_B64 = kFlagAvx512K | kFlagAvx512B64, kAvx512FlagER = 0x00000004u, //!< Supports 'embedded-rounding' {er} with implicit {sae},
kFlagAvx512KZ_B32 = kFlagAvx512KZ | kFlagAvx512B32, kAvx512FlagSAE = 0x00000008u, //!< Supports 'suppress-all-exceptions' {sae}.
kFlagAvx512KZ_B64 = kFlagAvx512KZ | kFlagAvx512B64 kAvx512FlagB32 = 0x00000010u, //!< Supports 32-bit broadcast 'b32'.
kAvx512FlagB64 = 0x00000020u, //!< Supports 64-bit broadcast 'b64'.
kAvx512FlagT4X = 0x00000080u //!< Operates on a vector of consecutive registers (AVX512_4FMAPS and AVX512_4VNNIW).
}; };
// ============================================================================ // ============================================================================
@@ -277,6 +274,8 @@ ASMJIT_VARAPI const InstSignature _instSignatureTable[];
struct CommonInfo { struct CommonInfo {
//! Instruction flags. //! Instruction flags.
uint32_t _flags; uint32_t _flags;
//! Reserved for future use.
uint32_t _avx512Flags : 11;
//! First `InstSignature` entry in the database. //! First `InstSignature` entry in the database.
uint32_t _iSignatureIndex : 11; uint32_t _iSignatureIndex : 11;
//! Number of relevant `ISignature` entries. //! Number of relevant `ISignature` entries.
@@ -285,18 +284,21 @@ struct CommonInfo {
uint32_t _controlType : 3; uint32_t _controlType : 3;
//! Specifies what happens if all source operands share the same register. //! Specifies what happens if all source operands share the same register.
uint32_t _singleRegCase : 2; uint32_t _singleRegCase : 2;
//! Reserved for future use.
uint32_t _reserved : 11;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Accessors] // [Accessors]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Returns instruction flags, see `InstInfo::Flags`. //! Returns instruction flags, see \ref Flags.
inline uint32_t flags() const noexcept { return _flags; } inline uint32_t flags() const noexcept { return _flags; }
//! Tests whether the instruction has a `flag`, see `InstInfo::Flags`. //! Tests whether the instruction has a `flag`, see \ref Flags.
inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; } inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
//! Returns instruction AVX-512 flags, see \ref Avx512Flags.
inline uint32_t avx512Flags() const noexcept { return _avx512Flags; }
//! Tests whether the instruction has an AVX-512 `flag`, see \ref Avx512Flags.
inline bool hasAvx512Flag(uint32_t flag) const noexcept { return (_avx512Flags & flag) != 0; }
//! Tests whether the instruction is FPU instruction. //! Tests whether the instruction is FPU instruction.
inline bool isFpu() const noexcept { return hasFlag(kFlagFpu); } inline bool isFpu() const noexcept { return hasFlag(kFlagFpu); }
//! Tests whether the instruction is MMX/3DNOW instruction that accesses MMX registers (includes EMMS and FEMMS). //! Tests whether the instruction is MMX/3DNOW instruction that accesses MMX registers (includes EMMS and FEMMS).
@@ -335,20 +337,25 @@ struct CommonInfo {
//! Tests whether the instruction should prefer EVEX prefix instead of VEX prefix. //! Tests whether the instruction should prefer EVEX prefix instead of VEX prefix.
inline bool preferEvex() const noexcept { return hasFlag(kFlagPreferEvex); } inline bool preferEvex() const noexcept { return hasFlag(kFlagPreferEvex); }
inline bool isEvexCompatible() const noexcept { return hasFlag(kFlagEvexCompat); }
inline bool isEvexKRegOnly() const noexcept { return hasFlag(kFlagEvexKReg); }
inline bool isEvexTwoOpOnly() const noexcept { return hasFlag(kFlagEvexTwoOp); }
inline bool isEvexTransformable() const noexcept { return hasFlag(kFlagEvexTransformable); }
//! Tests whether the instruction supports AVX512 masking {k}. //! Tests whether the instruction supports AVX512 masking {k}.
inline bool hasAvx512K() const noexcept { return hasFlag(kFlagAvx512K); } inline bool hasAvx512K() const noexcept { return hasAvx512Flag(kAvx512FlagK); }
//! Tests whether the instruction supports AVX512 zeroing {k}{z}. //! Tests whether the instruction supports AVX512 zeroing {k}{z}.
inline bool hasAvx512Z() const noexcept { return hasFlag(kFlagAvx512Z); } inline bool hasAvx512Z() const noexcept { return hasAvx512Flag(kAvx512FlagZ); }
//! Tests whether the instruction supports AVX512 embedded-rounding {er}. //! Tests whether the instruction supports AVX512 embedded-rounding {er}.
inline bool hasAvx512ER() const noexcept { return hasFlag(kFlagAvx512ER); } inline bool hasAvx512ER() const noexcept { return hasAvx512Flag(kAvx512FlagER); }
//! Tests whether the instruction supports AVX512 suppress-all-exceptions {sae}. //! Tests whether the instruction supports AVX512 suppress-all-exceptions {sae}.
inline bool hasAvx512SAE() const noexcept { return hasFlag(kFlagAvx512SAE); } inline bool hasAvx512SAE() const noexcept { return hasAvx512Flag(kAvx512FlagSAE); }
//! Tests whether the instruction supports AVX512 broadcast (either 32-bit or 64-bit). //! Tests whether the instruction supports AVX512 broadcast (either 32-bit or 64-bit).
inline bool hasAvx512B() const noexcept { return hasFlag(kFlagAvx512B32 | kFlagAvx512B64); } inline bool hasAvx512B() const noexcept { return hasAvx512Flag(kAvx512FlagB32 | kAvx512FlagB64); }
//! Tests whether the instruction supports AVX512 broadcast (32-bit). //! Tests whether the instruction supports AVX512 broadcast (32-bit).
inline bool hasAvx512B32() const noexcept { return hasFlag(kFlagAvx512B32); } inline bool hasAvx512B32() const noexcept { return hasAvx512Flag(kAvx512FlagB32); }
//! Tests whether the instruction supports AVX512 broadcast (64-bit). //! Tests whether the instruction supports AVX512 broadcast (64-bit).
inline bool hasAvx512B64() const noexcept { return hasFlag(kFlagAvx512B64); } inline bool hasAvx512B64() const noexcept { return hasAvx512Flag(kAvx512FlagB64); }
inline uint32_t signatureIndex() const noexcept { return _iSignatureIndex; } inline uint32_t signatureIndex() const noexcept { return _iSignatureIndex; }
inline uint32_t signatureCount() const noexcept { return _iSignatureCount; } inline uint32_t signatureCount() const noexcept { return _iSignatureCount; }
@@ -394,10 +401,15 @@ struct InstInfo {
//! Returns common information, see `CommonInfo`. //! Returns common information, see `CommonInfo`.
inline const CommonInfo& commonInfo() const noexcept { return _commonInfoTable[_commonInfoIndex]; } inline const CommonInfo& commonInfo() const noexcept { return _commonInfoTable[_commonInfoIndex]; }
//! Tests whether the instruction has flag `flag`, see `Flags`. //! Returns instruction flags, see \ref Flags.
inline bool hasFlag(uint32_t flag) const noexcept { return commonInfo().hasFlag(flag); }
//! Returns instruction flags, see `Flags`.
inline uint32_t flags() const noexcept { return commonInfo().flags(); } inline uint32_t flags() const noexcept { return commonInfo().flags(); }
//! Tests whether the instruction has flag `flag`, see \ref Flags.
inline bool hasFlag(uint32_t flag) const noexcept { return commonInfo().hasFlag(flag); }
//! Returns instruction AVX-512 flags, see \ref Avx512Flags.
inline uint32_t avx512Flags() const noexcept { return commonInfo().avx512Flags(); }
//! Tests whether the instruction has an AVX-512 `flag`, see \ref Avx512Flags.
inline bool hasAvx512Flag(uint32_t flag) const noexcept { return commonInfo().hasAvx512Flag(flag); }
//! Tests whether the instruction is FPU instruction. //! Tests whether the instruction is FPU instruction.
inline bool isFpu() const noexcept { return commonInfo().isFpu(); } inline bool isFpu() const noexcept { return commonInfo().isFpu(); }
@@ -432,20 +444,25 @@ struct InstInfo {
//! Tests whether the instruction uses EVEX (can be set together with VEX if both are encodable). //! Tests whether the instruction uses EVEX (can be set together with VEX if both are encodable).
inline bool isVexOrEvex() const noexcept { return hasFlag(kFlagVex | kFlagEvex); } inline bool isVexOrEvex() const noexcept { return hasFlag(kFlagVex | kFlagEvex); }
inline bool isEvexCompatible() const noexcept { return hasFlag(kFlagEvexCompat); }
inline bool isEvexKRegOnly() const noexcept { return hasFlag(kFlagEvexKReg); }
inline bool isEvexTwoOpOnly() const noexcept { return hasFlag(kFlagEvexTwoOp); }
inline bool isEvexTransformable() const noexcept { return hasFlag(kFlagEvexTransformable); }
//! Tests whether the instruction supports AVX512 masking {k}. //! Tests whether the instruction supports AVX512 masking {k}.
inline bool hasAvx512K() const noexcept { return hasFlag(kFlagAvx512K); } inline bool hasAvx512K() const noexcept { return hasAvx512Flag(kAvx512FlagK); }
//! Tests whether the instruction supports AVX512 zeroing {k}{z}. //! Tests whether the instruction supports AVX512 zeroing {k}{z}.
inline bool hasAvx512Z() const noexcept { return hasFlag(kFlagAvx512Z); } inline bool hasAvx512Z() const noexcept { return hasAvx512Flag(kAvx512FlagZ); }
//! Tests whether the instruction supports AVX512 embedded-rounding {er}. //! Tests whether the instruction supports AVX512 embedded-rounding {er}.
inline bool hasAvx512ER() const noexcept { return hasFlag(kFlagAvx512ER); } inline bool hasAvx512ER() const noexcept { return hasAvx512Flag(kAvx512FlagER); }
//! Tests whether the instruction supports AVX512 suppress-all-exceptions {sae}. //! Tests whether the instruction supports AVX512 suppress-all-exceptions {sae}.
inline bool hasAvx512SAE() const noexcept { return hasFlag(kFlagAvx512SAE); } inline bool hasAvx512SAE() const noexcept { return hasAvx512Flag(kAvx512FlagSAE); }
//! Tests whether the instruction supports AVX512 broadcast (either 32-bit or 64-bit). //! Tests whether the instruction supports AVX512 broadcast (either 32-bit or 64-bit).
inline bool hasAvx512B() const noexcept { return hasFlag(kFlagAvx512B32 | kFlagAvx512B64); } inline bool hasAvx512B() const noexcept { return hasAvx512Flag(kAvx512FlagB32 | kAvx512FlagB64); }
//! Tests whether the instruction supports AVX512 broadcast (32-bit). //! Tests whether the instruction supports AVX512 broadcast (32-bit).
inline bool hasAvx512B32() const noexcept { return hasFlag(kFlagAvx512B32); } inline bool hasAvx512B32() const noexcept { return hasAvx512Flag(kAvx512FlagB32); }
//! Tests whether the instruction supports AVX512 broadcast (64-bit). //! Tests whether the instruction supports AVX512 broadcast (64-bit).
inline bool hasAvx512B64() const noexcept { return hasFlag(kFlagAvx512B64); } inline bool hasAvx512B64() const noexcept { return hasAvx512Flag(kAvx512FlagB64); }
//! Gets the control-flow type of the instruction. //! Gets the control-flow type of the instruction.
inline uint32_t controlType() const noexcept { return commonInfo().controlType(); } inline uint32_t controlType() const noexcept { return commonInfo().controlType(); }

View File

@@ -140,6 +140,39 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
uint32_t singleRegOps = 0; uint32_t singleRegOps = 0;
if (opCount) { if (opCount) {
// The mask is for all registers, but we are mostly interested in AVX-512
// registers at the moment. The mask will be combined with all available
// registers of the Compiler at the end so we it never use more registers
// than available.
uint32_t instructionAllowedRegs = 0xFFFFFFFFu;
if (instInfo.isEvex()) {
// EVEX instruction and VEX instructions that can be encoded with EVEX
// have the possibility to use 32 SIMD registers (XMM/YMM/ZMM).
if (instInfo.isVex() && !instInfo.isEvexCompatible()) {
if (instInfo.isEvexKRegOnly()) {
// EVEX encodable only if the first operand is K register (compare instructions).
if (!Reg::isKReg(opArray[0]))
instructionAllowedRegs = 0xFFFFu;
}
else if (instInfo.isEvexTwoOpOnly()) {
// EVEX encodable only if the instruction has two operands (gather instructions).
if (opCount != 2)
instructionAllowedRegs = 0xFFFFu;
}
else {
instructionAllowedRegs = 0xFFFFu;
}
}
}
else if (instInfo.isEvexTransformable()) {
ib.addAggregatedFlags(RAInst::kFlagIsTransformable);
}
else {
// Not EVEX, restrict everything to [0-15] registers.
instructionAllowedRegs = 0xFFFFu;
}
for (uint32_t i = 0; i < opCount; i++) { for (uint32_t i = 0; i < opCount; i++) {
const Operand& op = opArray[i]; const Operand& op = opArray[i];
const OpRWInfo& opRwInfo = rwInfo.operand(i); const OpRWInfo& opRwInfo = rwInfo.operand(i);
@@ -150,7 +183,7 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
const Reg& reg = op.as<Reg>(); const Reg& reg = op.as<Reg>();
uint32_t flags = raRegRwFlags(opRwInfo.opFlags()); uint32_t flags = raRegRwFlags(opRwInfo.opFlags());
uint32_t allowedRegs = 0xFFFFFFFFu; uint32_t allowedRegs = instructionAllowedRegs;
// X86-specific constraints related to LO|HI general purpose registers. // X86-specific constraints related to LO|HI general purpose registers.
// This is only required when the register is part of the encoding. If // This is only required when the register is part of the encoding. If
@@ -281,7 +314,7 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
uint32_t flags = raMemIndexRwFlags(opRwInfo.opFlags()); uint32_t flags = raMemIndexRwFlags(opRwInfo.opFlags());
uint32_t group = workReg->group(); uint32_t group = workReg->group();
uint32_t allocable = _pass->_availableRegs[group]; uint32_t allocable = _pass->_availableRegs[group] & instructionAllowedRegs;
// Index registers have never fixed id on X86/x64. // Index registers have never fixed id on X86/x64.
const uint32_t useId = BaseReg::kIdBad; const uint32_t useId = BaseReg::kIdBad;
@@ -314,7 +347,7 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
if (group == Gp::kGroupKReg) { if (group == Gp::kGroupKReg) {
// AVX-512 mask selector {k} register - read-only, allocable to any register except {k0}. // AVX-512 mask selector {k} register - read-only, allocable to any register except {k0}.
uint32_t allocableRegs= _pass->_availableRegs[group] & ~Support::bitMask(0); uint32_t allocableRegs = _pass->_availableRegs[group];
ASMJIT_PROPAGATE(ib.add(workReg, RATiedReg::kUse | RATiedReg::kRead, allocableRegs, BaseReg::kIdBad, rewriteMask, BaseReg::kIdBad, 0)); ASMJIT_PROPAGATE(ib.add(workReg, RATiedReg::kUse | RATiedReg::kRead, allocableRegs, BaseReg::kIdBad, rewriteMask, BaseReg::kIdBad, 0));
singleRegOps = 0; singleRegOps = 0;
} }
@@ -1106,13 +1139,21 @@ X86RAPass::~X86RAPass() noexcept {}
void X86RAPass::onInit() noexcept { void X86RAPass::onInit() noexcept {
uint32_t arch = cc()->arch(); uint32_t arch = cc()->arch();
uint32_t baseRegCount = Environment::is32Bit(arch) ? 8u : 16u; uint32_t baseRegCount = Environment::is32Bit(arch) ? 8u : 16u;
uint32_t simdRegCount = baseRegCount;
if (Environment::is64Bit(arch) && _func->frame().isAvx512Enabled())
simdRegCount = 32u;
bool avxEnabled = _func->frame().isAvxEnabled();
bool avx512Enabled = _func->frame().isAvx512Enabled();
_emitHelper._emitter = _cb; _emitHelper._emitter = _cb;
_emitHelper._avxEnabled = _func->frame().isAvxEnabled(); _emitHelper._avxEnabled = avxEnabled || avx512Enabled;
_emitHelper._avx512Enabled = avx512Enabled;
_archTraits = &ArchTraits::byArch(arch); _archTraits = &ArchTraits::byArch(arch);
_physRegCount.set(Reg::kGroupGp , baseRegCount); _physRegCount.set(Reg::kGroupGp , baseRegCount);
_physRegCount.set(Reg::kGroupVec , baseRegCount); _physRegCount.set(Reg::kGroupVec , simdRegCount);
_physRegCount.set(Reg::kGroupMm , 8); _physRegCount.set(Reg::kGroupMm , 8);
_physRegCount.set(Reg::kGroupKReg, 8); _physRegCount.set(Reg::kGroupKReg, 8);
_buildPhysIndex(); _buildPhysIndex();
@@ -1147,6 +1188,135 @@ Error X86RAPass::buildCFG() noexcept {
return RACFGBuilder(this).run(); return RACFGBuilder(this).run();
} }
// ============================================================================
// [asmjit::x86::X86RAPass - Rewrite]
// ============================================================================
static uint32_t transformVexToEvex(uint32_t instId) {
switch (instId) {
case Inst::kIdVbroadcastf128: return Inst::kIdVbroadcastf32x4;
case Inst::kIdVbroadcasti128: return Inst::kIdVbroadcasti32x4;
case Inst::kIdVextractf128: return Inst::kIdVextractf32x4;
case Inst::kIdVextracti128: return Inst::kIdVextracti32x4;
case Inst::kIdVinsertf128: return Inst::kIdVinsertf32x4;
case Inst::kIdVinserti128: return Inst::kIdVinserti32x4;
case Inst::kIdVmovdqa: return Inst::kIdVmovdqa32;
case Inst::kIdVmovdqu: return Inst::kIdVmovdqu32;
case Inst::kIdVpand: return Inst::kIdVpandd;
case Inst::kIdVpandn: return Inst::kIdVpandnd;
case Inst::kIdVpor: return Inst::kIdVpord;
case Inst::kIdVpxor: return Inst::kIdVpxord;
default:
// This should never happen as only transformable instructions should go this path.
ASMJIT_ASSERT(false);
return 0;
}
}
ASMJIT_FAVOR_SPEED Error X86RAPass::_rewrite(BaseNode* first, BaseNode* stop) noexcept {
uint32_t virtCount = cc()->_vRegArray.size();
BaseNode* node = first;
while (node != stop) {
BaseNode* next = node->next();
if (node->isInst()) {
InstNode* inst = node->as<InstNode>();
RAInst* raInst = node->passData<RAInst>();
Operand* operands = inst->operands();
uint32_t opCount = inst->opCount();
uint32_t maxRegId = 0;
uint32_t i;
// Rewrite virtual registers into physical registers.
if (raInst) {
// If the instruction contains pass data (raInst) then it was a subject
// for register allocation and must be rewritten to use physical regs.
RATiedReg* tiedRegs = raInst->tiedRegs();
uint32_t tiedCount = raInst->tiedCount();
for (i = 0; i < tiedCount; i++) {
RATiedReg* tiedReg = &tiedRegs[i];
Support::BitWordIterator<uint32_t> useIt(tiedReg->useRewriteMask());
uint32_t useId = tiedReg->useId();
while (useIt.hasNext()) {
maxRegId = Support::max(maxRegId, useId);
inst->rewriteIdAtIndex(useIt.next(), useId);
}
Support::BitWordIterator<uint32_t> outIt(tiedReg->outRewriteMask());
uint32_t outId = tiedReg->outId();
while (outIt.hasNext()) {
maxRegId = Support::max(maxRegId, outId);
inst->rewriteIdAtIndex(outIt.next(), outId);
}
}
if (raInst->isTransformable()) {
if (maxRegId > 15) {
// Transform VEX instruction to EVEX.
inst->setId(transformVexToEvex(inst->id()));
}
}
// This data is allocated by Zone passed to `runOnFunction()`, which
// will be reset after the RA pass finishes. So reset this data to
// prevent having a dead pointer after the RA pass is complete.
node->resetPassData();
if (ASMJIT_UNLIKELY(node->type() != BaseNode::kNodeInst)) {
// FuncRet terminates the flow, it must either be removed if the exit
// label is next to it (optimization) or patched to an architecture
// dependent jump instruction that jumps to the function's exit before
// the epilog.
if (node->type() == BaseNode::kNodeFuncRet) {
RABlock* block = raInst->block();
if (!isNextTo(node, _func->exitNode())) {
cc()->_setCursor(node->prev());
ASMJIT_PROPAGATE(emitJump(_func->exitNode()->label()));
}
BaseNode* prev = node->prev();
cc()->removeNode(node);
block->setLast(prev);
}
}
}
// Rewrite stack slot addresses.
for (i = 0; i < opCount; i++) {
Operand& op = operands[i];
if (op.isMem()) {
BaseMem& mem = op.as<BaseMem>();
if (mem.isRegHome()) {
uint32_t virtIndex = Operand::virtIdToIndex(mem.baseId());
if (ASMJIT_UNLIKELY(virtIndex >= virtCount))
return DebugUtils::errored(kErrorInvalidVirtId);
VirtReg* virtReg = cc()->virtRegByIndex(virtIndex);
RAWorkReg* workReg = virtReg->workReg();
ASMJIT_ASSERT(workReg != nullptr);
RAStackSlot* slot = workReg->stackSlot();
int32_t offset = slot->offset();
mem._setBase(_sp.type(), slot->baseRegId());
mem.clearRegHome();
mem.addOffsetLo32(offset);
}
}
}
}
node = next;
}
return kErrorOk;
}
// ============================================================================ // ============================================================================
// [asmjit::x86::X86RAPass - OnEmit] // [asmjit::x86::X86RAPass - OnEmit]
// ============================================================================ // ============================================================================

View File

@@ -77,6 +77,7 @@ public:
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
inline bool avxEnabled() const noexcept { return _emitHelper._avxEnabled; } inline bool avxEnabled() const noexcept { return _emitHelper._avxEnabled; }
inline bool avx512Enabled() const noexcept { return _emitHelper._avx512Enabled; }
inline uint32_t choose(uint32_t sseInstId, uint32_t avxInstId) noexcept { inline uint32_t choose(uint32_t sseInstId, uint32_t avxInstId) noexcept {
return avxEnabled() ? avxInstId : sseInstId; return avxEnabled() ? avxInstId : sseInstId;
@@ -95,6 +96,12 @@ public:
Error buildCFG() noexcept override; Error buildCFG() noexcept override;
// --------------------------------------------------------------------------
// [Rewrite]
// --------------------------------------------------------------------------
Error _rewrite(BaseNode* first, BaseNode* stop) noexcept override;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Emit] // [Emit]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------

View File

@@ -149,6 +149,21 @@ class Filter {
// [tablegen.x86.GenUtils] // [tablegen.x86.GenUtils]
// ============================================================================ // ============================================================================
const VexToEvexMap = {
"vbroadcastf128": "vbroadcastf32x4",
"vbroadcasti128": "vbroadcasti32x4",
"vextractf128": "vextractf32x4",
"vextracti128": "vextracti32x4",
"vinsertf128": "vinsertf32x4",
"vinserti128": "vinserti32x4",
"vmovdqa": "vmovdqa32",
"vmovdqu": "vmovdqu32",
"vpand": "vpandd",
"vpandn": "vpandnd",
"vpor": "vpord",
"vpxor": "vpxord"
};
class GenUtils { class GenUtils {
static cpuArchOf(dbInsts) { static cpuArchOf(dbInsts) {
var anyArch = false; var anyArch = false;
@@ -169,15 +184,60 @@ class GenUtils {
return ArrayUtils.sorted(dbInsts.unionCpuFeatures()); return ArrayUtils.sorted(dbInsts.unionCpuFeatures());
} }
static flagsOf(dbInsts) { static assignVexEvexCompatibilityFlags(f, dbInsts) {
function replace(map, a, b, c) { const vexInsts = dbInsts.filter((inst) => { return inst.prefix === "VEX"; });
if (map[a] && map[b]) { const evexInsts = dbInsts.filter((inst) => { return inst.prefix === "EVEX"; });
delete map[a];
delete map[b]; function isCompatible(vexInst, evexInst) {
map[c] = true; if (vexInst.operands.length !== evexInst.operands.length)
return false;
for (let i = 0; i < vexInst.operands.length; i++) {
const vexOp = vexInst.operands[i];
const evexOp = evexInst.operands[i];
if (vexOp.data === evexOp.data)
continue;
if (vexOp.reg && vexOp.reg === evexOp.reg)
continue;
if (vexOp.mem && vexOp.mem === evexOp.mem)
continue;
return false;
}
return true;
}
let compatible = 0;
for (const vexInst of vexInsts) {
for (const evexInst of evexInsts) {
if (isCompatible(vexInst, evexInst)) {
compatible++;
break;
}
} }
} }
if (compatible == vexInsts.length) {
f.EvexCompat = true;
return true;
}
if (evexInsts[0].operands[0].reg === "k") {
f.EvexKReg = true;
return true;
}
if (evexInsts[0].operands.length == 2 && vexInsts[0].operands.length === 3) {
f.EvexTwoOp = true;
return true;
}
return false;
}
static flagsOf(dbInsts) {
const f = Object.create(null); const f = Object.create(null);
var i, j; var i, j;
@@ -201,7 +261,7 @@ class GenUtils {
const op = operands[j]; const op = operands[j];
if (op.reg === "mm") if (op.reg === "mm")
mmx = true; mmx = true;
else if (/^(k|xmm|ymm|zmm)$/.test(op.reg)) { else if (/^(xmm|ymm|zmm)$/.test(op.reg)) {
vec = true; vec = true;
} }
} }
@@ -256,20 +316,14 @@ class GenUtils {
if (dbInst.broadcast) f["Avx512B" + String(dbInst.elementSize)] = true; if (dbInst.broadcast) f["Avx512B" + String(dbInst.elementSize)] = true;
if (dbInst.tupleType === "T1_4X") f.Avx512T4X = true; if (dbInst.tupleType === "T1_4X") f.Avx512T4X = true;
} }
if (VexToEvexMap[dbInst.name])
f.EvexTransformable = true;
} }
replace(f, "Avx512K" , "Avx512Z" , "Avx512KZ"); if (f.Vex && f.Evex) {
replace(f, "Avx512ER" , "Avx512SAE" , "Avx512ER_SAE"); GenUtils.assignVexEvexCompatibilityFlags(f, dbInsts)
replace(f, "Avx512KZ" , "Avx512SAE" , "Avx512KZ_SAE"); }
replace(f, "Avx512KZ" , "Avx512ER_SAE", "Avx512KZ_ER_SAE");
replace(f, "Avx512K" , "Avx512B32" , "Avx512K_B32");
replace(f, "Avx512K" , "Avx512B64" , "Avx512K_B64");
replace(f, "Avx512KZ" , "Avx512B32" , "Avx512KZ_B32");
replace(f, "Avx512KZ" , "Avx512B64" , "Avx512KZ_B64");
replace(f, "Avx512KZ_SAE" , "Avx512B32" , "Avx512KZ_SAE_B32");
replace(f, "Avx512KZ_SAE" , "Avx512B64" , "Avx512KZ_SAE_B64");
replace(f, "Avx512KZ_ER_SAE", "Avx512B32" , "Avx512KZ_ER_SAE_B32");
replace(f, "Avx512KZ_ER_SAE", "Avx512B64" , "Avx512KZ_ER_SAE_B64");
return Object.getOwnPropertyNames(f); return Object.getOwnPropertyNames(f);
} }
@@ -2382,25 +2436,33 @@ class InstCommonTable extends core.Task {
const table = new IndexedArray(); const table = new IndexedArray();
insts.forEach((inst) => { insts.forEach((inst) => {
const flags = inst.flags.map(function(flag) { return `F(${flag})`; }).join("|") || "0"; const commonFlagsArray = inst.flags.filter((flag) => { return !flag.startsWith("Avx512"); });
const avx512FlagsArray = inst.flags.filter((flag) => { return flag.startsWith("Avx512"); });
const commonFlags = commonFlagsArray.map(function(flag) { return `F(${flag })`; }).join("|") || "0";
const avx512Flags = avx512FlagsArray.map(function(flag) { return `X(${flag.substr(6)})`; }).join("|") || "0";
const singleRegCase = `SINGLE_REG(${inst.singleRegCase})`; const singleRegCase = `SINGLE_REG(${inst.singleRegCase})`;
const controlType = `CONTROL(${inst.controlType})`; const controlType = `CONTROL(${inst.controlType})`;
const row = "{ " + const row = "{ " +
String(flags ).padEnd(54) + ", " + String(commonFlags ).padEnd(50) + ", " +
String(avx512Flags ).padEnd(30) + ", " +
String(inst.signatureIndex).padEnd( 3) + ", " + String(inst.signatureIndex).padEnd( 3) + ", " +
String(inst.signatureCount).padEnd( 2) + ", " + String(inst.signatureCount).padEnd( 2) + ", " +
String(controlType ).padEnd(16) + ", " + String(controlType ).padEnd(16) + ", " +
String(singleRegCase ).padEnd(16) + ", " + "0 }"; String(singleRegCase ).padEnd(16) + "}";
inst.commonInfoIndexA = table.addIndexed(row); inst.commonInfoIndexA = table.addIndexed(row);
}); });
var s = `#define F(VAL) InstDB::kFlag##VAL\n` + var s = `#define F(VAL) InstDB::kFlag##VAL\n` +
`#define X(VAL) InstDB::kAvx512Flag##VAL\n` +
`#define CONTROL(VAL) Inst::kControl##VAL\n` + `#define CONTROL(VAL) Inst::kControl##VAL\n` +
`#define SINGLE_REG(VAL) InstDB::kSingleReg##VAL\n` + `#define SINGLE_REG(VAL) InstDB::kSingleReg##VAL\n` +
`const InstDB::CommonInfo InstDB::_commonInfoTable[] = {\n${StringUtils.format(table, kIndent, true)}\n};\n` + `const InstDB::CommonInfo InstDB::_commonInfoTable[] = {\n${StringUtils.format(table, kIndent, true)}\n};\n` +
`#undef SINGLE_REG\n` + `#undef SINGLE_REG\n` +
`#undef CONTROL\n` + `#undef CONTROL\n` +
`#undef X\n` +
`#undef F\n`; `#undef F\n`;
this.inject("InstCommonTable", disclaimer(s), table.length * 8); this.inject("InstCommonTable", disclaimer(s), table.length * 8);
} }