mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 04:24:37 +03:00
Added ADX, TBM, CLFLUSH_OPT, PREFETCHW, and SHA instruction sets to Assembler and Compiler\nAdded initial support for AVX/AVX2 instructions into X86Compiler\nRenamed oword to dqword (intel convention)\nFixed incorrect XOP and FMA4 detection\nCosmetic changes in documentation\nFixed unused typedef warnings (clang) (related to #132)
This commit is contained in:
@@ -252,17 +252,17 @@
|
||||
//! be used directly (like `eax`, `mm`, `xmm`, ...) or created through
|
||||
//! these functions:
|
||||
//!
|
||||
//! - `asmjit::x86::gpb_lo()` - Get an 8-bit Gpb low register.
|
||||
//! - `asmjit::x86::gpb_hi()` - Get an 8-hi Gpb hugh register.
|
||||
//! - `asmjit::x86::gpw()` - Get a 16-bit Gpw register.
|
||||
//! - `asmjit::x86::gpd()` - Get a 32-bit Gpd register.
|
||||
//! - `asmjit::x86::gpq()` - Get a 64-bit Gpq Gp register.
|
||||
//! - `asmjit::x86::gpz()` - Get a 32-bit or 64-bit Gpd/Gpq register.
|
||||
//! - `asmjit::x86::fp()` - Get a 80-bit Fp register.
|
||||
//! - `asmjit::x86::mm()` - Get a 64-bit Mm register.
|
||||
//! - `asmjit::x86::xmm()` - Get a 128-bit Xmm register.
|
||||
//! - `asmjit::x86::ymm()` - Get a 256-bit Ymm register.
|
||||
//! - `asmjit::x86::amm()` - Get a 512-bit Zmm register.
|
||||
//! - `asmjit::x86::gpb_lo()` - Get an 8-bit low GPB register.
|
||||
//! - `asmjit::x86::gpb_hi()` - Get an 8-bit high GPB register.
|
||||
//! - `asmjit::x86::gpw()` - Get a 16-bit GPW register.
|
||||
//! - `asmjit::x86::gpd()` - Get a 32-bit GPD register.
|
||||
//! - `asmjit::x86::gpq()` - Get a 64-bit GPQ Gp register.
|
||||
//! - `asmjit::x86::gpz()` - Get a 32-bit or 64-bit GPD/GPQ register.
|
||||
//! - `asmjit::x86::fp()` - Get a 80-bit FPU register.
|
||||
//! - `asmjit::x86::mm()` - Get a 64-bit MMX register.
|
||||
//! - `asmjit::x86::xmm()` - Get a 128-bit XMM register.
|
||||
//! - `asmjit::x86::ymm()` - Get a 256-bit YMM register.
|
||||
//! - `asmjit::x86::amm()` - Get a 512-bit ZMM register.
|
||||
//!
|
||||
//! X86/X64 Addressing
|
||||
//! ------------------
|
||||
@@ -272,15 +272,15 @@
|
||||
//! `BaseMem` class. These functions are used to make operands that represents
|
||||
//! memory addresses:
|
||||
//!
|
||||
//! - `asmjit::x86::ptr()` - Address size not specified.
|
||||
//! - `asmjit::x86::byte_ptr()` - 1 byte.
|
||||
//! - `asmjit::x86::word_ptr()` - 2 bytes (Gpw size).
|
||||
//! - `asmjit::x86::dword_ptr()` - 4 bytes (Gpd size).
|
||||
//! - `asmjit::x86::qword_ptr()` - 8 bytes (Gpq/Mm size).
|
||||
//! - `asmjit::x86::tword_ptr()` - 10 bytes (FPU size).
|
||||
//! - `asmjit::x86::oword_ptr()` - 16 bytes (Xmm size).
|
||||
//! - `asmjit::x86::yword_ptr()` - 32 bytes (Ymm size).
|
||||
//! - `asmjit::x86::zword_ptr()` - 64 bytes (Zmm size).
|
||||
//! - `asmjit::x86::ptr()` - Address size not specified.
|
||||
//! - `asmjit::x86::byte_ptr()` - 1 byte.
|
||||
//! - `asmjit::x86::word_ptr()` - 2 bytes (GPW size).
|
||||
//! - `asmjit::x86::dword_ptr()` - 4 bytes (GPD size).
|
||||
//! - `asmjit::x86::qword_ptr()` - 8 bytes (GPQ/MMX size).
|
||||
//! - `asmjit::x86::tword_ptr()` - 10 bytes (FPU size).
|
||||
//! - `asmjit::x86::dqword_ptr()` - 16 bytes (XMM size).
|
||||
//! - `asmjit::x86::yword_ptr()` - 32 bytes (YMM size).
|
||||
//! - `asmjit::x86::zword_ptr()` - 64 bytes (ZMM size).
|
||||
//!
|
||||
//! Most useful function to make pointer should be `asmjit::x86::ptr()`. It
|
||||
//! creates a pointer to the target with an unspecified size. Unspecified size
|
||||
|
||||
@@ -252,7 +252,7 @@ class ASMJIT_VIRTAPI ErrorHandler {
|
||||
|
||||
//! Reference this error handler.
|
||||
//!
|
||||
//! \note This member function is provided for convenience. The default
|
||||
//! NOTE: This member function is provided for convenience. The default
|
||||
//! implementation does nothing. If you are working in environment where
|
||||
//! multiple `ErrorHandler` instances are used by a different code generators
|
||||
//! you may provide your own functionality for reference counting. In that
|
||||
@@ -261,7 +261,7 @@ class ASMJIT_VIRTAPI ErrorHandler {
|
||||
|
||||
//! Release this error handler.
|
||||
//!
|
||||
//! \note This member function is provided for convenience. See `addRef()`
|
||||
//! NOTE: This member function is provided for convenience. See `addRef()`
|
||||
//! for more detailed information related to reference counting.
|
||||
ASMJIT_API virtual void release() noexcept;
|
||||
|
||||
@@ -817,7 +817,7 @@ class ASMJIT_VIRTAPI Assembler {
|
||||
|
||||
//! Get whether the `label` is bound.
|
||||
//!
|
||||
//! \note It's an error to pass label that is not valid. Check the validity
|
||||
//! NOTE: It's an error to pass label that is not valid. Check the validity
|
||||
//! of the label by using `isLabelValid()` method before the bound check if
|
||||
//! you are not sure about its validity, otherwise you may hit an assertion
|
||||
//! failure in debug mode, and undefined behavior in release mode.
|
||||
@@ -865,7 +865,7 @@ class ASMJIT_VIRTAPI Assembler {
|
||||
|
||||
//! Bind the `label` to the current offset.
|
||||
//!
|
||||
//! \note Label can be bound only once!
|
||||
//! NOTE: Label can be bound only once!
|
||||
ASMJIT_API virtual Error bind(const Label& label) noexcept;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
@@ -373,7 +373,7 @@ class ASMJIT_VIRTAPI Compiler : public ExternalTool {
|
||||
|
||||
//! Bind label to the current offset.
|
||||
//!
|
||||
//! \note Label can be bound only once!
|
||||
//! NOTE: Label can be bound only once!
|
||||
ASMJIT_API Error bind(const Label& label) noexcept;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -466,7 +466,7 @@ class ASMJIT_VIRTAPI Compiler : public ExternalTool {
|
||||
|
||||
//! Rename variable `var` to `name`.
|
||||
//!
|
||||
//! \note Only new name will appear in the logger.
|
||||
//! NOTE: Only new name will appear in the logger.
|
||||
ASMJIT_API void rename(Var& var, const char* fmt, ...) noexcept;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
@@ -120,7 +120,7 @@ ASMJIT_ENUM(VarHint) {
|
||||
//!
|
||||
//! State of variable.
|
||||
//!
|
||||
//! \note Variable states are used only during register allocation.
|
||||
//! NOTE: Variable states are used only during register allocation.
|
||||
ASMJIT_ENUM(kVarState) {
|
||||
//! Variable is currently not used.
|
||||
kVarStateNone = 0,
|
||||
|
||||
@@ -579,7 +579,7 @@ struct FuncDecl {
|
||||
//!
|
||||
//! Direction should be always `kFuncDirRTL`.
|
||||
//!
|
||||
//! \note This is related to used calling convention, it's not affected by
|
||||
//! NOTE: This is related to used calling convention, it's not affected by
|
||||
//! number of function arguments or their types.
|
||||
ASMJIT_INLINE uint32_t getArgsDirection() const noexcept { return _argsDirection; }
|
||||
|
||||
@@ -652,12 +652,12 @@ struct FuncDecl {
|
||||
|
||||
//! Size of "Red Zone".
|
||||
//!
|
||||
//! \note Used by AMD64-ABI (128 bytes).
|
||||
//! NOTE: Used by AMD64-ABI (128 bytes).
|
||||
uint16_t _redZoneSize;
|
||||
|
||||
//! Size of "Spill Zone".
|
||||
//!
|
||||
//! \note Used by WIN64-ABI (32 bytes).
|
||||
//! NOTE: Used by WIN64-ABI (32 bytes).
|
||||
uint16_t _spillZoneSize;
|
||||
|
||||
//! Function arguments (LO & HI) mapped to physical registers and stack.
|
||||
|
||||
@@ -431,7 +431,6 @@ static void x86DetectCpuInfo(CpuInfo* cpuInfo) noexcept {
|
||||
if (regs.ecx & 0x04000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureXSAVE);
|
||||
if (regs.ecx & 0x08000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureXSAVE_OS);
|
||||
if (regs.ecx & 0x40000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureRDRAND);
|
||||
|
||||
if (regs.edx & 0x00000010U) cpuInfo->addFeature(CpuInfo::kX86FeatureRDTSC);
|
||||
if (regs.edx & 0x00000100U) cpuInfo->addFeature(CpuInfo::kX86FeatureCMPXCHG8B);
|
||||
if (regs.edx & 0x00008000U) cpuInfo->addFeature(CpuInfo::kX86FeatureCMOV);
|
||||
@@ -444,15 +443,13 @@ static void x86DetectCpuInfo(CpuInfo* cpuInfo) noexcept {
|
||||
.addFeature(CpuInfo::kX86FeatureSSE2);
|
||||
if (regs.edx & 0x10000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureMT);
|
||||
|
||||
// AMD sets Multithreading to ON if it has two or more cores.
|
||||
if (cpuInfo->_hwThreadsCount == 1 && cpuInfo->_vendorId == CpuInfo::kVendorAMD && (regs.edx & 0x10000000U)) {
|
||||
// AMD sets multi-threading ON if it has two or more cores.
|
||||
if (cpuInfo->_hwThreadsCount == 1 && cpuInfo->_vendorId == CpuInfo::kVendorAMD && (regs.edx & 0x10000000U))
|
||||
cpuInfo->_hwThreadsCount = 2;
|
||||
}
|
||||
|
||||
// Get the content of XCR0 if supported by CPU and enabled by OS.
|
||||
if ((regs.ecx & 0x0C000000U) == 0x0C000000U) {
|
||||
if ((regs.ecx & 0x0C000000U) == 0x0C000000U)
|
||||
x86CallXGetBV(&xcr0, 0);
|
||||
}
|
||||
|
||||
// Detect AVX+.
|
||||
if (regs.ecx & 0x10000000U) {
|
||||
@@ -461,9 +458,7 @@ static void x86DetectCpuInfo(CpuInfo* cpuInfo) noexcept {
|
||||
if ((xcr0.eax & 0x00000006U) == 0x00000006U) {
|
||||
cpuInfo->addFeature(CpuInfo::kX86FeatureAVX);
|
||||
|
||||
if (regs.ecx & 0x00000800U) cpuInfo->addFeature(CpuInfo::kX86FeatureXOP);
|
||||
if (regs.ecx & 0x00004000U) cpuInfo->addFeature(CpuInfo::kX86FeatureFMA3);
|
||||
if (regs.ecx & 0x00010000U) cpuInfo->addFeature(CpuInfo::kX86FeatureFMA4);
|
||||
if (regs.ecx & 0x20000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureF16C);
|
||||
}
|
||||
}
|
||||
@@ -475,43 +470,48 @@ static void x86DetectCpuInfo(CpuInfo* cpuInfo) noexcept {
|
||||
|
||||
// Detect new features if the processor supports CPUID-07.
|
||||
bool maybeMPX = false;
|
||||
|
||||
if (maxId >= 0x7) {
|
||||
x86CallCpuId(®s, 0x7);
|
||||
|
||||
if (regs.ebx & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeatureFSGSBASE);
|
||||
if (regs.ebx & 0x00000008U) cpuInfo->addFeature(CpuInfo::kX86FeatureBMI);
|
||||
if (regs.ebx & 0x00000010U) cpuInfo->addFeature(CpuInfo::kX86FeatureHLE);
|
||||
if (regs.ebx & 0x00000080U) cpuInfo->addFeature(CpuInfo::kX86FeatureSMEP);
|
||||
if (regs.ebx & 0x00000100U) cpuInfo->addFeature(CpuInfo::kX86FeatureBMI2);
|
||||
if (regs.ebx & 0x00000200U) cpuInfo->addFeature(CpuInfo::kX86FeatureMOVSBSTOSB_OPT);
|
||||
if (regs.ebx & 0x00000200U) cpuInfo->addFeature(CpuInfo::kX86FeatureERMS);
|
||||
if (regs.ebx & 0x00000800U) cpuInfo->addFeature(CpuInfo::kX86FeatureRTM);
|
||||
if (regs.ebx & 0x00004000U) maybeMPX = true;
|
||||
if (regs.ebx & 0x00040000U) cpuInfo->addFeature(CpuInfo::kX86FeatureRDSEED);
|
||||
if (regs.ebx & 0x00080000U) cpuInfo->addFeature(CpuInfo::kX86FeatureADX);
|
||||
if (regs.ebx & 0x00100000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSMAP);
|
||||
if (regs.ebx & 0x00400000U) cpuInfo->addFeature(CpuInfo::kX86FeaturePCOMMIT);
|
||||
if (regs.ebx & 0x00800000U) cpuInfo->addFeature(CpuInfo::kX86FeatureCLFLUSH_OPT);
|
||||
if (regs.ebx & 0x01000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureCLWB);
|
||||
if (regs.ebx & 0x20000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSHA);
|
||||
|
||||
if (regs.ecx & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeaturePREFETCHWT1);
|
||||
|
||||
// Detect AVX2.
|
||||
if (cpuInfo->hasFeature(CpuInfo::kX86FeatureAVX)) {
|
||||
if (cpuInfo->hasFeature(CpuInfo::kX86FeatureAVX))
|
||||
if (regs.ebx & 0x00000020U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX2);
|
||||
}
|
||||
|
||||
// Detect AVX-512+.
|
||||
if (regs.ebx & 0x00010000U) {
|
||||
// - XCR0[2:1] == 11b
|
||||
// XMM/YMM states need to be enabled by OS.
|
||||
// - XCR0[7:5] == 111b
|
||||
// Upper 256-bit of ZMM0-XMM15 and ZMM16-ZMM31 need to be enabled by OS.
|
||||
// Upper 256-bit of ZMM0-XMM15 and ZMM16-ZMM31 need to be enabled by the OS.
|
||||
if ((xcr0.eax & 0x00000076U) == 0x00000076U) {
|
||||
cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512F);
|
||||
|
||||
if (regs.ebx & 0x00020000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512DQ);
|
||||
if (regs.ebx & 0x00200000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512IFMA);
|
||||
if (regs.ebx & 0x04000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512PF);
|
||||
if (regs.ebx & 0x08000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512ER);
|
||||
if (regs.ebx & 0x10000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512CD);
|
||||
if (regs.ebx & 0x40000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512BW);
|
||||
if (regs.ebx & 0x80000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512VL);
|
||||
if (regs.ecx & 0x00000002U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512VBMI);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -551,7 +551,7 @@ static void x86DetectCpuInfo(CpuInfo* cpuInfo) noexcept {
|
||||
if (regs.ecx & 0x00000040U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSE4A);
|
||||
if (regs.ecx & 0x00000080U) cpuInfo->addFeature(CpuInfo::kX86FeatureMSSE);
|
||||
if (regs.ecx & 0x00000100U) cpuInfo->addFeature(CpuInfo::kX86FeaturePREFETCH);
|
||||
|
||||
if (regs.ecx & 0x00200000U) cpuInfo->addFeature(CpuInfo::kX86FeatureTBM);
|
||||
if (regs.edx & 0x00100000U) cpuInfo->addFeature(CpuInfo::kX86FeatureNX);
|
||||
if (regs.edx & 0x00200000U) cpuInfo->addFeature(CpuInfo::kX86FeatureFXSR_OPT);
|
||||
if (regs.edx & 0x00400000U) cpuInfo->addFeature(CpuInfo::kX86FeatureMMX2);
|
||||
@@ -559,6 +559,11 @@ static void x86DetectCpuInfo(CpuInfo* cpuInfo) noexcept {
|
||||
if (regs.edx & 0x40000000U) cpuInfo->addFeature(CpuInfo::kX86Feature3DNOW2)
|
||||
.addFeature(CpuInfo::kX86FeatureMMX2);
|
||||
if (regs.edx & 0x80000000U) cpuInfo->addFeature(CpuInfo::kX86Feature3DNOW);
|
||||
|
||||
if (cpuInfo->hasFeature(CpuInfo::kX86FeatureAVX)) {
|
||||
if (regs.ecx & 0x00000800U) cpuInfo->addFeature(CpuInfo::kX86FeatureXOP);
|
||||
if (regs.ecx & 0x00010000U) cpuInfo->addFeature(CpuInfo::kX86FeatureFMA4);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x80000002U:
|
||||
|
||||
@@ -32,15 +32,10 @@ class CpuInfo {
|
||||
|
||||
//! CPU vendor ID.
|
||||
ASMJIT_ENUM(Vendor) {
|
||||
//! Generic or unknown.
|
||||
kVendorNone = 0,
|
||||
|
||||
//! Intel vendor.
|
||||
kVendorIntel = 1,
|
||||
//! AMD vendor.
|
||||
kVendorAMD = 2,
|
||||
//! VIA vendor.
|
||||
kVendorVIA = 3
|
||||
kVendorNone = 0, //!< Generic or unknown.
|
||||
kVendorIntel = 1, //!< Intel vendor.
|
||||
kVendorAMD = 2, //!< AMD vendor.
|
||||
kVendorVIA = 3 //!< VIA vendor.
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -49,50 +44,26 @@ class CpuInfo {
|
||||
|
||||
//! ARM/ARM64 CPU features.
|
||||
ASMJIT_ENUM(ArmFeatures) {
|
||||
//! ARMv6 instruction set.
|
||||
kArmFeatureV6,
|
||||
//! ARMv7 instruction set.
|
||||
kArmFeatureV7,
|
||||
//! ARMv8 instruction set.
|
||||
kArmFeatureV8,
|
||||
kArmFeatureV6, //!< ARMv6 instruction set.
|
||||
kArmFeatureV7, //!< ARMv7 instruction set.
|
||||
kArmFeatureV8, //!< ARMv8 instruction set.
|
||||
kArmFeatureTHUMB, //!< CPU provides THUMB v1 instruction set (ARM only).
|
||||
kArmFeatureTHUMB2, //!< CPU provides THUMB v2 instruction set (ARM only).
|
||||
kArmFeatureVFP2, //!< CPU provides VFPv2 instruction set.
|
||||
kArmFeatureVFP3, //!< CPU provides VFPv3 instruction set.
|
||||
kArmFeatureVFP4, //!< CPU provides VFPv4 instruction set.
|
||||
kArmFeatureVFP_D32, //!< CPU provides 32 VFP-D (64-bit) registers.
|
||||
kArmFeatureNEON, //!< CPU provides NEON instruction set.
|
||||
kArmFeatureDSP, //!< CPU provides DSP extensions.
|
||||
kArmFeatureIDIV, //!< CPU provides hardware support for SDIV and UDIV.
|
||||
kArmFeatureAES, //!< CPU provides AES instructions (ARM64 only).
|
||||
kArmFeatureCRC32, //!< CPU provides CRC32 instructions (ARM64 only).
|
||||
kArmFeaturePMULL, //!< CPU provides PMULL instructions (ARM64 only).
|
||||
kArmFeatureSHA1, //!< CPU provides SHA1 instructions (ARM64 only).
|
||||
kArmFeatureSHA256, //!< CPU provides SHA256 instructions (ARM64 only).
|
||||
kArmFeatureAtomics64, //!< CPU provides 64-bit load/store atomics (ARM64 only).
|
||||
|
||||
//! CPU provides THUMB v1 instruction set (ARM only).
|
||||
kArmFeatureTHUMB,
|
||||
//! CPU provides THUMB v2 instruction set (ARM only).
|
||||
kArmFeatureTHUMB2,
|
||||
|
||||
//! CPU provides VFPv2 instruction set.
|
||||
kArmFeatureVFP2,
|
||||
//! CPU provides VFPv3 instruction set.
|
||||
kArmFeatureVFP3,
|
||||
//! CPU provides VFPv4 instruction set.
|
||||
kArmFeatureVFP4,
|
||||
//! CPU provides 32 VFP-D (64-bit) registers.
|
||||
kArmFeatureVFP_D32,
|
||||
|
||||
//! CPU provides NEON instruction set.
|
||||
kArmFeatureNEON,
|
||||
|
||||
//! CPU provides DSP extensions.
|
||||
kArmFeatureDSP,
|
||||
//! CPU provides hardware support for SDIV and UDIV.
|
||||
kArmFeatureIDIV,
|
||||
|
||||
//! CPU provides AES instructions (ARM64 only).
|
||||
kArmFeatureAES,
|
||||
//! CPU provides CRC32 instructions (ARM64 only).
|
||||
kArmFeatureCRC32,
|
||||
//! CPU provides PMULL instructions (ARM64 only).
|
||||
kArmFeaturePMULL,
|
||||
//! CPU provides SHA1 instructions (ARM64 only).
|
||||
kArmFeatureSHA1,
|
||||
//! CPU provides SHA256 instructions (ARM64 only).
|
||||
kArmFeatureSHA256,
|
||||
//! CPU provides 64-bit load/store atomics (ARM64 only).
|
||||
kArmFeatureAtomics64,
|
||||
|
||||
//! Count of ARM/ARM64 CPU features.
|
||||
kArmFeaturesCount
|
||||
kArmFeaturesCount //!< Count of ARM/ARM64 CPU features.
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -101,126 +72,73 @@ class CpuInfo {
|
||||
|
||||
//! X86/X64 CPU features.
|
||||
ASMJIT_ENUM(X86Features) {
|
||||
//! Cpu has Not-Execute-Bit.
|
||||
kX86FeatureNX = 0,
|
||||
//! Cpu has multithreading.
|
||||
kX86FeatureMT,
|
||||
//! Cpu has RDTSC.
|
||||
kX86FeatureRDTSC,
|
||||
//! Cpu has RDTSCP.
|
||||
kX86FeatureRDTSCP,
|
||||
//! Cpu has CMOV.
|
||||
kX86FeatureCMOV,
|
||||
//! Cpu has CMPXCHG8B.
|
||||
kX86FeatureCMPXCHG8B,
|
||||
//! Cpu has CMPXCHG16B (X64).
|
||||
kX86FeatureCMPXCHG16B,
|
||||
//! Cpu has CLFUSH.
|
||||
kX86FeatureCLFLUSH,
|
||||
//! Cpu has CLFUSH (Optimized).
|
||||
kX86FeatureCLFLUSH_OPT,
|
||||
//! Cpu has PREFETCH.
|
||||
kX86FeaturePREFETCH,
|
||||
//! Cpu has PREFETCHWT1.
|
||||
kX86FeaturePREFETCHWT1,
|
||||
//! Cpu has LAHF/SAHF.
|
||||
kX86FeatureLAHF_SAHF,
|
||||
//! Cpu has FXSAVE/FXRSTOR.
|
||||
kX86FeatureFXSR,
|
||||
//! Cpu has FXSAVE/FXRSTOR (Optimized).
|
||||
kX86FeatureFXSR_OPT,
|
||||
//! Cpu has MMX.
|
||||
kX86FeatureMMX,
|
||||
//! Cpu has extended MMX.
|
||||
kX86FeatureMMX2,
|
||||
//! Cpu has 3dNow!
|
||||
kX86Feature3DNOW,
|
||||
//! Cpu has enchanced 3dNow!
|
||||
kX86Feature3DNOW2,
|
||||
//! Cpu has SSE.
|
||||
kX86FeatureSSE,
|
||||
//! Cpu has SSE2.
|
||||
kX86FeatureSSE2,
|
||||
//! Cpu has SSE3.
|
||||
kX86FeatureSSE3,
|
||||
//! Cpu has SSSE3.
|
||||
kX86FeatureSSSE3,
|
||||
//! Cpu has SSE4.A.
|
||||
kX86FeatureSSE4A,
|
||||
//! Cpu has SSE4.1.
|
||||
kX86FeatureSSE4_1,
|
||||
//! Cpu has SSE4.2.
|
||||
kX86FeatureSSE4_2,
|
||||
//! Cpu has Misaligned SSE (MSSE).
|
||||
kX86FeatureMSSE,
|
||||
//! Cpu has MONITOR and MWAIT.
|
||||
kX86FeatureMONITOR,
|
||||
//! Cpu has MOVBE.
|
||||
kX86FeatureMOVBE,
|
||||
//! Cpu has POPCNT.
|
||||
kX86FeaturePOPCNT,
|
||||
//! Cpu has LZCNT.
|
||||
kX86FeatureLZCNT,
|
||||
//! Cpu has AESNI.
|
||||
kX86FeatureAESNI,
|
||||
//! Cpu has PCLMULQDQ.
|
||||
kX86FeaturePCLMULQDQ,
|
||||
//! Cpu has RDRAND.
|
||||
kX86FeatureRDRAND,
|
||||
//! Cpu has RDSEED.
|
||||
kX86FeatureRDSEED,
|
||||
//! Cpu has SHA-1 and SHA-256.
|
||||
kX86FeatureSHA,
|
||||
//! Cpu has XSAVE support - XSAVE/XRSTOR, XSETBV/XGETBV, and XCR0.
|
||||
kX86FeatureXSAVE,
|
||||
//! OS has enabled XSAVE, you can call XGETBV to get value of XCR0.
|
||||
kX86FeatureXSAVE_OS,
|
||||
//! Cpu has AVX.
|
||||
kX86FeatureAVX,
|
||||
//! Cpu has AVX2.
|
||||
kX86FeatureAVX2,
|
||||
//! Cpu has F16C.
|
||||
kX86FeatureF16C,
|
||||
//! Cpu has FMA3.
|
||||
kX86FeatureFMA3,
|
||||
//! Cpu has FMA4.
|
||||
kX86FeatureFMA4,
|
||||
//! Cpu has XOP.
|
||||
kX86FeatureXOP,
|
||||
//! Cpu has BMI.
|
||||
kX86FeatureBMI,
|
||||
//! Cpu has BMI2.
|
||||
kX86FeatureBMI2,
|
||||
//! Cpu has HLE.
|
||||
kX86FeatureHLE,
|
||||
//! Cpu has RTM.
|
||||
kX86FeatureRTM,
|
||||
//! Cpu has ADX.
|
||||
kX86FeatureADX,
|
||||
//! Cpu has MPX (Memory Protection Extensions).
|
||||
kX86FeatureMPX,
|
||||
//! Cpu has FSGSBASE.
|
||||
kX86FeatureFSGSBASE,
|
||||
//! Cpu has optimized REP MOVSB/STOSB.
|
||||
kX86FeatureMOVSBSTOSB_OPT,
|
||||
kX86FeatureNX = 0, //!< CPU has Not-Execute-Bit.
|
||||
kX86FeatureMT, //!< CPU has multi-threading.
|
||||
kX86FeatureRDTSC, //!< CPU has RDTSC.
|
||||
kX86FeatureRDTSCP, //!< CPU has RDTSCP.
|
||||
kX86FeatureCMOV, //!< CPU has CMOV.
|
||||
kX86FeatureCMPXCHG8B, //!< CPU has CMPXCHG8B.
|
||||
kX86FeatureCMPXCHG16B, //!< CPU has CMPXCHG16B (x64).
|
||||
kX86FeatureCLFLUSH, //!< CPU has CLFUSH.
|
||||
kX86FeatureCLFLUSH_OPT, //!< CPU has CLFUSH (optimized).
|
||||
kX86FeatureCLWB, //!< CPU has CLWB.
|
||||
kX86FeaturePCOMMIT, //!< CPU has PCOMMIT.
|
||||
kX86FeaturePREFETCH, //!< CPU has PREFETCH.
|
||||
kX86FeaturePREFETCHWT1, //!< CPU has PREFETCHWT1.
|
||||
kX86FeatureLAHF_SAHF, //!< CPU has LAHF/SAHF.
|
||||
kX86FeatureFXSR, //!< CPU has FXSAVE/FXRSTOR.
|
||||
kX86FeatureFXSR_OPT, //!< CPU has FXSAVE/FXRSTOR (optimized).
|
||||
kX86FeatureMMX, //!< CPU has MMX.
|
||||
kX86FeatureMMX2, //!< CPU has extended MMX.
|
||||
kX86Feature3DNOW, //!< CPU has 3dNow!
|
||||
kX86Feature3DNOW2, //!< CPU has enhanced 3dNow!
|
||||
kX86FeatureSSE, //!< CPU has SSE.
|
||||
kX86FeatureSSE2, //!< CPU has SSE2.
|
||||
kX86FeatureSSE3, //!< CPU has SSE3.
|
||||
kX86FeatureSSSE3, //!< CPU has SSSE3.
|
||||
kX86FeatureSSE4A, //!< CPU has SSE4.A.
|
||||
kX86FeatureSSE4_1, //!< CPU has SSE4.1.
|
||||
kX86FeatureSSE4_2, //!< CPU has SSE4.2.
|
||||
kX86FeatureMSSE, //!< CPU has Misaligned SSE (MSSE).
|
||||
kX86FeatureMONITOR, //!< CPU has MONITOR and MWAIT.
|
||||
kX86FeatureMOVBE, //!< CPU has MOVBE.
|
||||
kX86FeaturePOPCNT, //!< CPU has POPCNT.
|
||||
kX86FeatureLZCNT, //!< CPU has LZCNT.
|
||||
kX86FeatureAESNI, //!< CPU has AESNI.
|
||||
kX86FeaturePCLMULQDQ, //!< CPU has PCLMULQDQ.
|
||||
kX86FeatureRDRAND, //!< CPU has RDRAND.
|
||||
kX86FeatureRDSEED, //!< CPU has RDSEED.
|
||||
kX86FeatureSMAP, //!< CPU has SMAP (supervisor-mode access prevention).
|
||||
kX86FeatureSMEP, //!< CPU has SMEP (supervisor-mode execution prevention).
|
||||
kX86FeatureSHA, //!< CPU has SHA-1 and SHA-256.
|
||||
kX86FeatureXSAVE, //!< CPU has XSAVE support - XSAVE/XRSTOR, XSETBV/XGETBV, and XCR0.
|
||||
kX86FeatureXSAVE_OS, //!< OS has enabled XSAVE, you can call XGETBV to get value of XCR0.
|
||||
kX86FeatureAVX, //!< CPU has AVX.
|
||||
kX86FeatureAVX2, //!< CPU has AVX2.
|
||||
kX86FeatureF16C, //!< CPU has F16C.
|
||||
kX86FeatureFMA3, //!< CPU has FMA3.
|
||||
kX86FeatureFMA4, //!< CPU has FMA4.
|
||||
kX86FeatureXOP, //!< CPU has XOP.
|
||||
kX86FeatureBMI, //!< CPU has BMI (bit manipulation instructions #1).
|
||||
kX86FeatureBMI2, //!< CPU has BMI2 (bit manipulation instructions #2).
|
||||
kX86FeatureADX, //!< CPU has ADX (multi-precision add-carry instruction extensions).
|
||||
kX86FeatureTBM, //!< CPU has TBM (trailing bit manipulation).
|
||||
kX86FeatureMPX, //!< CPU has MPX (memory protection extensions).
|
||||
kX86FeatureHLE, //!< CPU has HLE.
|
||||
kX86FeatureRTM, //!< CPU has RTM.
|
||||
kX86FeatureERMS, //!< CPU has ERMS (enhanced REP MOVSB/STOSB).
|
||||
kX86FeatureFSGSBASE, //!< CPU has FSGSBASE.
|
||||
kX86FeatureAVX512F, //!< CPU has AVX-512F (foundation).
|
||||
kX86FeatureAVX512CD, //!< CPU has AVX-512CD (conflict detection).
|
||||
kX86FeatureAVX512PF, //!< CPU has AVX-512PF (prefetch instructions).
|
||||
kX86FeatureAVX512ER, //!< CPU has AVX-512ER (exponential and reciprocal instructions).
|
||||
kX86FeatureAVX512DQ, //!< CPU has AVX-512DQ (DWORD/QWORD).
|
||||
kX86FeatureAVX512BW, //!< CPU has AVX-512BW (BYTE/WORD).
|
||||
kX86FeatureAVX512VL, //!< CPU has AVX VL (vector length extensions).
|
||||
kX86FeatureAVX512IFMA, //!< CPU has AVX IFMA (integer fused multiply add using 52-bit precision).
|
||||
kX86FeatureAVX512VBMI, //!< CPU has AVX VBMI (vector byte manipulation instructions).
|
||||
|
||||
//! Cpu has AVX-512F (Foundation).
|
||||
kX86FeatureAVX512F,
|
||||
//! Cpu has AVX-512CD (Conflict Detection).
|
||||
kX86FeatureAVX512CD,
|
||||
//! Cpu has AVX-512PF (Prefetch Instructions).
|
||||
kX86FeatureAVX512PF,
|
||||
//! Cpu has AVX-512ER (Exponential and Reciprocal Instructions).
|
||||
kX86FeatureAVX512ER,
|
||||
//! Cpu has AVX-512DQ (DWord/QWord).
|
||||
kX86FeatureAVX512DQ,
|
||||
//! Cpu has AVX-512BW (Byte/Word).
|
||||
kX86FeatureAVX512BW,
|
||||
//! Cpu has AVX VL (Vector Length Excensions).
|
||||
kX86FeatureAVX512VL,
|
||||
|
||||
//! Count of X86/X64 CPU features.
|
||||
kX86FeaturesCount
|
||||
kX86FeaturesCount //!< Count of X86/X64 CPU features.
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -244,14 +162,10 @@ class CpuInfo {
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
struct X86Data {
|
||||
//! Processor type.
|
||||
uint32_t _processorType;
|
||||
//! Brand index.
|
||||
uint32_t _brandIndex;
|
||||
//! Flush cache line size in bytes.
|
||||
uint32_t _flushCacheLineSize;
|
||||
//! Maximum number of addressable IDs for logical processors.
|
||||
uint32_t _maxLogicalProcessors;
|
||||
uint32_t _processorType; //!< Processor type.
|
||||
uint32_t _brandIndex; //!< Brand index.
|
||||
uint32_t _flushCacheLineSize; //!< Flush cache line size (in bytes).
|
||||
uint32_t _maxLogicalProcessors; //!< Maximum number of addressable IDs for logical processors.
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -264,9 +178,7 @@ class CpuInfo {
|
||||
// [Reset]
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
ASMJIT_INLINE void reset() noexcept {
|
||||
::memset(this, 0, sizeof(CpuInfo));
|
||||
}
|
||||
ASMJIT_INLINE void reset() noexcept { ::memset(this, 0, sizeof(CpuInfo)); }
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// [Detect]
|
||||
@@ -355,36 +267,36 @@ class CpuInfo {
|
||||
// [Statics]
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//! Get host cpu.
|
||||
//! Get the host CPU information.
|
||||
static ASMJIT_API const CpuInfo& getHost() noexcept;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// [Members]
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//! Cpu vendor string.
|
||||
//! CPU vendor string.
|
||||
char _vendorString[16];
|
||||
//! Cpu brand string.
|
||||
//! CPU brand string.
|
||||
char _brandString[64];
|
||||
|
||||
//! CPU architecture, see \ref Arch.
|
||||
uint8_t _arch;
|
||||
//! \internal
|
||||
uint8_t _reserved[3];
|
||||
//! Cpu vendor id, see \ref CpuVendor.
|
||||
//! CPU vendor id, see \ref CpuVendor.
|
||||
uint32_t _vendorId;
|
||||
//! Cpu family ID.
|
||||
//! CPU family ID.
|
||||
uint32_t _family;
|
||||
//! Cpu model ID.
|
||||
//! CPU model ID.
|
||||
uint32_t _model;
|
||||
//! Cpu stepping.
|
||||
//! CPU stepping.
|
||||
uint32_t _stepping;
|
||||
|
||||
//! Number of hardware threads.
|
||||
uint32_t _hwThreadsCount;
|
||||
|
||||
//! Cpu features bitfield.
|
||||
uint32_t _features[4];
|
||||
//! CPU features (bit-array).
|
||||
uint32_t _features[8];
|
||||
|
||||
// Architecture specific data.
|
||||
union {
|
||||
|
||||
@@ -534,7 +534,7 @@ ASMJIT_ENUM(ErrorCode) {
|
||||
//! a.mov(byte_ptr(r10), ah);
|
||||
//! ~~~
|
||||
//!
|
||||
//! \note In debug mode assertion is raised instead of returning an error.
|
||||
//! NOTE: In debug mode assertion is raised instead of returning an error.
|
||||
kErrorIllegalInst,
|
||||
|
||||
//! Illegal (unencodable) addressing used.
|
||||
|
||||
@@ -140,7 +140,7 @@ class HLNode {
|
||||
|
||||
//! Create a new `HLNode`.
|
||||
//!
|
||||
//! \note Always use compiler to create nodes.
|
||||
//! NOTE: Always use compiler to create nodes.
|
||||
ASMJIT_INLINE HLNode(Compiler* compiler, uint32_t type) noexcept; // Defined-Later.
|
||||
|
||||
//! Destroy the `HLNode`.
|
||||
@@ -961,7 +961,7 @@ class HLFunc : public HLNode {
|
||||
|
||||
//! Expected stack alignment (we depend on this value).
|
||||
//!
|
||||
//! \note It can be global alignment given by the OS or described by the
|
||||
//! NOTE: It can be global alignment given by the OS or described by the
|
||||
//! target platform ABI.
|
||||
uint32_t _expectedStackAlignment;
|
||||
//! Required stack alignment (required by SIMD instructions).
|
||||
|
||||
@@ -175,7 +175,7 @@ class ASMJIT_VIRTAPI FileLogger : public Logger {
|
||||
|
||||
//! Get `FILE*` stream.
|
||||
//!
|
||||
//! \note Return value can be `nullptr`.
|
||||
//! NOTE: Return value can be `nullptr`.
|
||||
ASMJIT_INLINE FILE* getStream() const noexcept {
|
||||
return _stream;
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ ASMJIT_ENUM(SizeDefs) {
|
||||
kSizeQWord = 8,
|
||||
//! 10 bytes size (TWORD).
|
||||
kSizeTWord = 10,
|
||||
//! 16 bytes size (OWORD / DQWORD).
|
||||
kSizeOWord = 16,
|
||||
//! 16 bytes size (DQWORD).
|
||||
kSizeDQWord = 16,
|
||||
//! 32 bytes size (YWORD / QQWORD).
|
||||
kSizeYWord = 32,
|
||||
//! 64 bytes size (ZWORD / DQQWORD).
|
||||
@@ -198,7 +198,7 @@ class Operand {
|
||||
|
||||
//! Operand id, identifier used by `Assembler` and `Compiler`.
|
||||
//!
|
||||
//! \note Uninitialized operand has always set id to `kInvalidValue`.
|
||||
//! NOTE: Uninitialized operand has always set id to `kInvalidValue`.
|
||||
uint32_t id;
|
||||
|
||||
//! \internal
|
||||
@@ -544,7 +544,7 @@ struct OperandUtil {
|
||||
|
||||
//! Get whether the id refers to `Var`.
|
||||
//!
|
||||
//! \note The function will never return `true` if the id is `kInvalidValue`.
|
||||
//! NOTE: The function will never return `true` if the id is `kInvalidValue`.
|
||||
//! The trick is to compare a given id to -1 (kInvalidValue) so we check both
|
||||
//! using only one comparison.
|
||||
static ASMJIT_INLINE bool isVarId(uint32_t id) noexcept {
|
||||
@@ -553,7 +553,7 @@ struct OperandUtil {
|
||||
|
||||
//! Get whether the id refers to `Label`.
|
||||
//!
|
||||
//! \note The function will never return `true` if the id is `kInvalidValue`.
|
||||
//! NOTE: The function will never return `true` if the id is `kInvalidValue`.
|
||||
static ASMJIT_INLINE bool isLabelId(uint32_t id) noexcept {
|
||||
return static_cast<int32_t>(id) >= 0;
|
||||
}
|
||||
|
||||
@@ -231,7 +231,6 @@ struct Utils {
|
||||
//! Get whether the given integer `x` can be casted to an 8-bit unsigned integer.
|
||||
template<typename T>
|
||||
static ASMJIT_INLINE bool isUInt8(T x) noexcept {
|
||||
typedef typename IntTraits<T>::SignedType SignedType;
|
||||
typedef typename IntTraits<T>::UnsignedType UnsignedType;
|
||||
|
||||
if (IntTraits<T>::kIsSigned)
|
||||
@@ -243,7 +242,6 @@ struct Utils {
|
||||
//! Get whether the given integer `x` can be casted to a 12-bit unsigned integer (ARM specific).
|
||||
template<typename T>
|
||||
static ASMJIT_INLINE bool isUInt12(T x) noexcept {
|
||||
typedef typename IntTraits<T>::SignedType SignedType;
|
||||
typedef typename IntTraits<T>::UnsignedType UnsignedType;
|
||||
|
||||
if (IntTraits<T>::kIsSigned)
|
||||
@@ -255,7 +253,6 @@ struct Utils {
|
||||
//! Get whether the given integer `x` can be casted to a 16-bit unsigned integer.
|
||||
template<typename T>
|
||||
static ASMJIT_INLINE bool isUInt16(T x) noexcept {
|
||||
typedef typename IntTraits<T>::SignedType SignedType;
|
||||
typedef typename IntTraits<T>::UnsignedType UnsignedType;
|
||||
|
||||
if (IntTraits<T>::kIsSigned)
|
||||
@@ -267,7 +264,6 @@ struct Utils {
|
||||
//! Get whether the given integer `x` can be casted to a 32-bit unsigned integer.
|
||||
template<typename T>
|
||||
static ASMJIT_INLINE bool isUInt32(T x) noexcept {
|
||||
typedef typename IntTraits<T>::SignedType SignedType;
|
||||
typedef typename IntTraits<T>::UnsignedType UnsignedType;
|
||||
|
||||
if (IntTraits<T>::kIsSigned)
|
||||
|
||||
@@ -101,7 +101,7 @@ class VMemMgr {
|
||||
#else
|
||||
//! Create a `VMemMgr` instance.
|
||||
//!
|
||||
//! \note When running on Windows it's possible to specify a `hProcess` to
|
||||
//! NOTE: When running on Windows it's possible to specify a `hProcess` to
|
||||
//! be used for memory allocation. Using `hProcess` allows to allocate memory
|
||||
//! of a remote process.
|
||||
ASMJIT_API VMemMgr(HANDLE hProcess = static_cast<HANDLE>(0)) noexcept;
|
||||
@@ -154,7 +154,7 @@ class VMemMgr {
|
||||
//! VMemMgr destructor. After destruction all internal
|
||||
//! structures are freed, only the process virtual memory remains.
|
||||
//!
|
||||
//! \note Memory allocated with kVMemAllocPermanent is always kept.
|
||||
//! NOTE: Memory allocated with kVMemAllocPermanent is always kept.
|
||||
//!
|
||||
//! \sa \ref getKeepVirtualMemory.
|
||||
ASMJIT_INLINE void setKeepVirtualMemory(bool keepVirtualMemory) noexcept {
|
||||
|
||||
@@ -35,7 +35,7 @@ enum { kX86RexNoRexMask = kX86InstOptionRex | _kX86InstOptionNoRex };
|
||||
//!
|
||||
//! X86/X64 bytes used to encode important prefixes.
|
||||
enum X86Byte {
|
||||
//! 1-byte REX prefix
|
||||
//! 1-byte REX prefix mask.
|
||||
kX86ByteRex = 0x40,
|
||||
|
||||
//! 1-byte REX.W component.
|
||||
@@ -75,12 +75,12 @@ enum X86Byte {
|
||||
//! - `P[ 10]` - ___: Must be 1.
|
||||
//! - `P[14:11]` - REG: 2nd SRC vector register (4 bits).
|
||||
//! - `P[ 15]` - EXT: VEX.W.
|
||||
//! - `P[18:16]` - REG: K registers k0...k7 (Merging/Zeroing Vector Ops.).
|
||||
//! - `P[18:16]` - REG: K registers k0...k7 (Merging/Zeroing Vector Ops).
|
||||
//! - `P[ 19]` - REG: 2nd SRC vector register (Hi bit).
|
||||
//! - `P[ 20]` - EXT: Broadcast/Static-Rounding/SAE bit.
|
||||
//! - `P[22.21]` - EXT: Vector Length/Rounding Control.
|
||||
//! - `P[ 23]` - EXT: Destination result behavior (Merging/Zeroing Vector Ops.).
|
||||
kX86ByteEvex4 = 0x62
|
||||
//! - `P[ 23]` - EXT: Destination result behavior (Merging/Zeroing Vector Ops).
|
||||
kX86ByteEvex = 0x62
|
||||
};
|
||||
|
||||
// AsmJit specific (used to encode VVVV field in XOP/VEX).
|
||||
@@ -99,8 +99,7 @@ struct X86OpCodeMM {
|
||||
|
||||
//! \internal
|
||||
//!
|
||||
//! Mandatory prefixes encoded in 'asmjit' opcode [66, F3, F2] and AsmJit
|
||||
//! extensions
|
||||
//! Mandatory prefixes used to encode [66, F3, F2] and [9B].
|
||||
static const uint8_t x86OpCodePP[8] = {
|
||||
0x00, 0x66, 0xF3, 0xF2, 0x00, 0x00, 0x00, 0x9B
|
||||
};
|
||||
@@ -162,7 +161,7 @@ static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) {
|
||||
return (s << 6) + (i << 3) + b;
|
||||
}
|
||||
|
||||
//! Get whether the two pointers `a` and `b` can be encoded by using relative
|
||||
//! Get if the given pointers `a` and `b` can be encoded by using relative
|
||||
//! displacement, which fits into a signed 32-bit integer.
|
||||
static ASMJIT_INLINE bool x64IsRelative(Ptr a, Ptr b) {
|
||||
SignedPtr diff = static_cast<SignedPtr>(a) - static_cast<SignedPtr>(b);
|
||||
@@ -198,6 +197,9 @@ static ASMJIT_INLINE bool x86IsXmm(const X86Reg* reg) { return reg->isXmm(); }
|
||||
static ASMJIT_INLINE bool x86IsYmm(const Operand* op) { return op->isRegType(kX86RegTypeYmm); }
|
||||
static ASMJIT_INLINE bool x86IsYmm(const X86Reg* reg) { return reg->isYmm(); }
|
||||
|
||||
static ASMJIT_INLINE bool x86IsZmm(const Operand* op) { return op->isRegType(kX86RegTypeZmm); }
|
||||
static ASMJIT_INLINE bool x86IsZmm(const X86Reg* reg) { return reg->isZmm(); }
|
||||
|
||||
// ============================================================================
|
||||
// [Macros]
|
||||
// ============================================================================
|
||||
@@ -609,7 +611,7 @@ static const char* AssemblerX86_getAddressSizeString(uint32_t size) noexcept {
|
||||
case 4 : return "dword ptr ";
|
||||
case 8 : return "qword ptr ";
|
||||
case 10: return "tword ptr ";
|
||||
case 16: return "oword ptr ";
|
||||
case 16: return "dqword ptr ";
|
||||
case 32: return "yword ptr ";
|
||||
case 64: return "zword ptr ";
|
||||
default: return "";
|
||||
@@ -866,7 +868,7 @@ static bool X86Assembler_dumpInstruction(StringBuilder& sb,
|
||||
sb._appendString("short ", 6);
|
||||
|
||||
// Dump instruction name.
|
||||
sb._appendString(_x86InstInfo[code].getInstName());
|
||||
sb._appendString(X86Util::getInstNameById(code));
|
||||
|
||||
// Dump operands.
|
||||
if (!o0->isNone()) {
|
||||
@@ -971,9 +973,7 @@ static ASMJIT_INLINE Error X86Assembler_emit(Assembler* self_, uint32_t code, co
|
||||
// Displacement relocation id.
|
||||
intptr_t relocId;
|
||||
|
||||
#if defined(ASMJIT_DEBUG)
|
||||
bool assertIllegal = false;
|
||||
#endif // ASMJIT_DEBUG
|
||||
|
||||
const X86InstInfo& info = _x86InstInfo[code];
|
||||
const X86InstExtendedInfo& extendedInfo = info.getExtendedInfo();
|
||||
@@ -1749,7 +1749,7 @@ static ASMJIT_INLINE Error X86Assembler_emit(Assembler* self_, uint32_t code, co
|
||||
}
|
||||
break;
|
||||
|
||||
case kX86InstEncodingX86MovSxZx:
|
||||
case kX86InstEncodingX86MovsxMovzx:
|
||||
if (encoded == ENC_OPS(Reg, Reg, None)) {
|
||||
opCode += o1->getSize() != 1;
|
||||
ADD_66H_P_BY_SIZE(o0->getSize());
|
||||
@@ -1771,7 +1771,7 @@ static ASMJIT_INLINE Error X86Assembler_emit(Assembler* self_, uint32_t code, co
|
||||
}
|
||||
break;
|
||||
|
||||
case kX86InstEncodingX86MovSxd:
|
||||
case kX86InstEncodingX86Movsxd:
|
||||
if (encoded == ENC_OPS(Reg, Reg, None)) {
|
||||
ADD_REX_W(true);
|
||||
|
||||
@@ -1968,7 +1968,7 @@ _GroupPop_Gp:
|
||||
}
|
||||
break;
|
||||
|
||||
case kX86InstEncodingX86Shlrd:
|
||||
case kX86InstEncodingX86ShldShrd:
|
||||
if (encoded == ENC_OPS(Reg, Reg, Imm)) {
|
||||
ASMJIT_ASSERT(o0->getSize() == o1->getSize());
|
||||
|
||||
@@ -2227,16 +2227,16 @@ _EmitFpArith_Mem:
|
||||
if (encoded == ENC_OPS(Mem, None, None)) {
|
||||
rmMem = x86OpMem(o0);
|
||||
|
||||
if (o0->getSize() == 4 && info.hasInstFlag(kX86InstFlagMem4)) {
|
||||
if (o0->getSize() == 4 && info.hasFlag(kX86InstFlagMem4)) {
|
||||
goto _EmitX86M;
|
||||
}
|
||||
|
||||
if (o0->getSize() == 8 && info.hasInstFlag(kX86InstFlagMem8)) {
|
||||
if (o0->getSize() == 8 && info.hasFlag(kX86InstFlagMem8)) {
|
||||
opCode += 4;
|
||||
goto _EmitX86M;
|
||||
}
|
||||
|
||||
if (o0->getSize() == 10 && info.hasInstFlag(kX86InstFlagMem10)) {
|
||||
if (o0->getSize() == 10 && info.hasFlag(kX86InstFlagMem10)) {
|
||||
opCode = extendedInfo.getSecondaryOpCode();
|
||||
opReg = x86ExtractO(opCode);
|
||||
goto _EmitX86M;
|
||||
@@ -2266,16 +2266,16 @@ _EmitFpArith_Mem:
|
||||
if (encoded == ENC_OPS(Mem, None, None)) {
|
||||
rmMem = x86OpMem(o0);
|
||||
|
||||
if (o0->getSize() == 2 && info.hasInstFlag(kX86InstFlagMem2)) {
|
||||
if (o0->getSize() == 2 && info.hasFlag(kX86InstFlagMem2)) {
|
||||
opCode += 4;
|
||||
goto _EmitX86M;
|
||||
}
|
||||
|
||||
if (o0->getSize() == 4 && info.hasInstFlag(kX86InstFlagMem4)) {
|
||||
if (o0->getSize() == 4 && info.hasFlag(kX86InstFlagMem4)) {
|
||||
goto _EmitX86M;
|
||||
}
|
||||
|
||||
if (o0->getSize() == 8 && info.hasInstFlag(kX86InstFlagMem8)) {
|
||||
if (o0->getSize() == 8 && info.hasFlag(kX86InstFlagMem8)) {
|
||||
opCode = extendedInfo.getSecondaryOpCode();
|
||||
opReg = x86ExtractO(opCode);
|
||||
goto _EmitX86M;
|
||||
@@ -2371,7 +2371,7 @@ _EmitFpArith_Mem:
|
||||
ASMJIT_ASSERT(extendedInfo._opFlags[0] != 0);
|
||||
ASMJIT_ASSERT(extendedInfo._opFlags[1] != 0);
|
||||
|
||||
// Check parameters Gpd|Gpq|Mm|Xmm <- Gpd|Gpq|Mm|Xmm|X86Mem|Imm.
|
||||
// Check parameters GPD|GPQ|MMX|XMM <- GPD|GPQ|MMX|XMM|Mem|Imm.
|
||||
ASMJIT_ASSERT(!((o0->isMem() && (extendedInfo._opFlags[0] & kX86InstOpMem) == 0) ||
|
||||
(o0->isRegType(kX86RegTypeMm ) && (extendedInfo._opFlags[0] & kX86InstOpMm ) == 0) ||
|
||||
(o0->isRegType(kX86RegTypeXmm) && (extendedInfo._opFlags[0] & kX86InstOpXmm) == 0) ||
|
||||
@@ -2383,7 +2383,7 @@ _EmitFpArith_Mem:
|
||||
(o1->isRegType(kX86RegTypeGpd) && (extendedInfo._opFlags[1] & kX86InstOpGd ) == 0) ||
|
||||
(o1->isRegType(kX86RegTypeGpq) && (extendedInfo._opFlags[1] & kX86InstOpGq ) == 0) ));
|
||||
|
||||
// Gp|Mm|Xmm <- Gp|Mm|Xmm
|
||||
// GP|MMX|XMM <- GP|MMX|XMM
|
||||
if (encoded == ENC_OPS(Reg, Reg, None)) {
|
||||
ADD_REX_W(x86IsGpq(static_cast<const X86Reg*>(o0)) && (info.getEncoding() != kX86InstEncodingSimdMovNoRexW));
|
||||
ADD_REX_W(x86IsGpq(static_cast<const X86Reg*>(o1)) && (info.getEncoding() != kX86InstEncodingSimdMovNoRexW));
|
||||
@@ -2393,7 +2393,7 @@ _EmitFpArith_Mem:
|
||||
goto _EmitX86R;
|
||||
}
|
||||
|
||||
// Gp|Mm|Xmm <- Mem
|
||||
// GP|MMX|XMM <- Mem
|
||||
if (encoded == ENC_OPS(Reg, Mem, None)) {
|
||||
ADD_REX_W(x86IsGpq(static_cast<const X86Reg*>(o0)) && (info.getEncoding() != kX86InstEncodingSimdMovNoRexW));
|
||||
|
||||
@@ -2405,7 +2405,7 @@ _EmitFpArith_Mem:
|
||||
// The following instruction uses opCode[1].
|
||||
opCode = extendedInfo.getSecondaryOpCode();
|
||||
|
||||
// X86Mem <- Gp|Mm|Xmm
|
||||
// X86Mem <- GP|MMX|XMM
|
||||
if (encoded == ENC_OPS(Mem, Reg, None)) {
|
||||
ADD_REX_W(x86IsGpq(static_cast<const X86Reg*>(o1)) && (info.getEncoding() != kX86InstEncodingSimdMovNoRexW));
|
||||
|
||||
@@ -2449,13 +2449,13 @@ _EmitMmMovD:
|
||||
opReg = x86OpReg(o0);
|
||||
ADD_66H_P(x86IsXmm(static_cast<const X86Reg*>(o0)));
|
||||
|
||||
// Mm/Xmm <- Gp
|
||||
// MMX/XMM <- Gp
|
||||
if (encoded == ENC_OPS(Reg, Reg, None) && static_cast<const X86Reg*>(o1)->isGp()) {
|
||||
rmReg = x86OpReg(o1);
|
||||
goto _EmitX86R;
|
||||
}
|
||||
|
||||
// Mm/Xmm <- Mem
|
||||
// MMX/XMM <- Mem
|
||||
if (encoded == ENC_OPS(Reg, Mem, None)) {
|
||||
rmMem = x86OpMem(o1);
|
||||
goto _EmitX86M;
|
||||
@@ -2466,13 +2466,13 @@ _EmitMmMovD:
|
||||
opReg = x86OpReg(o1);
|
||||
ADD_66H_P(x86IsXmm(static_cast<const X86Reg*>(o1)));
|
||||
|
||||
// Gp <- Mm/Xmm
|
||||
// GP <- MMX/XMM
|
||||
if (encoded == ENC_OPS(Reg, Reg, None) && static_cast<const X86Reg*>(o0)->isGp()) {
|
||||
rmReg = x86OpReg(o0);
|
||||
goto _EmitX86R;
|
||||
}
|
||||
|
||||
// X86Mem <- Mm/Xmm
|
||||
// Mem <- MMX/XMM
|
||||
if (encoded == ENC_OPS(Mem, Reg, None)) {
|
||||
rmMem = x86OpMem(o0);
|
||||
goto _EmitX86M;
|
||||
@@ -2484,25 +2484,25 @@ _EmitMmMovD:
|
||||
opReg = x86OpReg(o0);
|
||||
rmReg = x86OpReg(o1);
|
||||
|
||||
// Mm <- Mm
|
||||
// MMX <- MMX
|
||||
if (static_cast<const X86Reg*>(o0)->isMm() && static_cast<const X86Reg*>(o1)->isMm()) {
|
||||
opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x6F;
|
||||
goto _EmitX86R;
|
||||
}
|
||||
|
||||
// Xmm <- Xmm
|
||||
// XMM <- XMM
|
||||
if (static_cast<const X86Reg*>(o0)->isXmm() && static_cast<const X86Reg*>(o1)->isXmm()) {
|
||||
opCode = kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | 0x7E;
|
||||
goto _EmitX86R;
|
||||
}
|
||||
|
||||
// Mm <- Xmm (Movdq2q)
|
||||
// MMX <- XMM (MOVDQ2Q)
|
||||
if (static_cast<const X86Reg*>(o0)->isMm() && static_cast<const X86Reg*>(o1)->isXmm()) {
|
||||
opCode = kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F | 0xD6;
|
||||
goto _EmitX86R;
|
||||
}
|
||||
|
||||
// Xmm <- Mm (Movq2dq)
|
||||
// XMM <- MMX (MOVQ2DQ)
|
||||
if (static_cast<const X86Reg*>(o0)->isXmm() && static_cast<const X86Reg*>(o1)->isMm()) {
|
||||
opCode = kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | 0xD6;
|
||||
goto _EmitX86R;
|
||||
@@ -2513,13 +2513,13 @@ _EmitMmMovD:
|
||||
opReg = x86OpReg(o0);
|
||||
rmMem = x86OpMem(o1);
|
||||
|
||||
// Mm <- Mem
|
||||
// MMX <- Mem
|
||||
if (static_cast<const X86Reg*>(o0)->isMm()) {
|
||||
opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x6F;
|
||||
goto _EmitX86M;
|
||||
}
|
||||
|
||||
// Xmm <- Mem
|
||||
// XMM <- Mem
|
||||
if (static_cast<const X86Reg*>(o0)->isXmm()) {
|
||||
opCode = kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | 0x7E;
|
||||
goto _EmitX86M;
|
||||
@@ -2530,13 +2530,13 @@ _EmitMmMovD:
|
||||
opReg = x86OpReg(o1);
|
||||
rmMem = x86OpMem(o0);
|
||||
|
||||
// X86Mem <- Mm
|
||||
// Mem <- MMX
|
||||
if (static_cast<const X86Reg*>(o1)->isMm()) {
|
||||
opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x7F;
|
||||
goto _EmitX86M;
|
||||
}
|
||||
|
||||
// X86Mem <- Xmm
|
||||
// Mem <- XMM
|
||||
if (static_cast<const X86Reg*>(o1)->isXmm()) {
|
||||
opCode = kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F | 0xD6;
|
||||
goto _EmitX86M;
|
||||
@@ -2544,7 +2544,7 @@ _EmitMmMovD:
|
||||
}
|
||||
|
||||
if (Arch == kArchX64) {
|
||||
// Movq in other case is simply a MOVD instruction promoted to 64-bit.
|
||||
// MOVQ in other case is simply a MOVD instruction promoted to 64-bit.
|
||||
opCode |= kX86InstOpCode_W;
|
||||
goto _EmitMmMovD;
|
||||
}
|
||||
@@ -3477,6 +3477,22 @@ CaseAvxVm:
|
||||
goto _EmitXopM;
|
||||
}
|
||||
break;
|
||||
|
||||
case kX86InstEncodingXopVm_OptW:
|
||||
ADD_REX_W(x86IsGpq(static_cast<const X86Reg*>(o0)) | x86IsGpq(o1));
|
||||
|
||||
if (encoded == ENC_OPS(Reg, Reg, None)) {
|
||||
opReg = x86RegAndVvvv(opReg, x86OpReg(o0));
|
||||
rmReg = x86OpReg(o1);
|
||||
goto _EmitXopR;
|
||||
}
|
||||
|
||||
if (encoded == ENC_OPS(Reg, Mem, None)) {
|
||||
opReg = x86RegAndVvvv(opReg, x86OpReg(o0));
|
||||
rmMem = x86OpMem(o1);
|
||||
goto _EmitXopM;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -4227,11 +4243,7 @@ _EmitDisplacement:
|
||||
|
||||
_EmitDone:
|
||||
#if !defined(ASMJIT_DISABLE_LOGGER)
|
||||
# if defined(ASMJIT_DEBUG)
|
||||
if (self->_logger || assertIllegal) {
|
||||
# else
|
||||
if (self->_logger) {
|
||||
# endif // ASMJIT_DEBUG
|
||||
StringBuilderTmp<512> sb;
|
||||
uint32_t loggerOptions = 0;
|
||||
|
||||
@@ -4259,9 +4271,7 @@ _EmitDone:
|
||||
# endif // ASMJIT_DEBUG
|
||||
}
|
||||
#else
|
||||
# if defined(ASMJIT_DEBUG)
|
||||
ASMJIT_ASSERT(!assertIllegal);
|
||||
# endif // ASMJIT_DEBUG
|
||||
#endif // !ASMJIT_DISABLE_LOGGER
|
||||
|
||||
self->_comment = nullptr;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -143,7 +143,7 @@ static void X86Context_annotateOperand(X86Context* self,
|
||||
static bool X86Context_annotateInstruction(X86Context* self,
|
||||
StringBuilder& sb, uint32_t instId, const Operand* opList, uint32_t opCount) {
|
||||
|
||||
sb.appendString(_x86InstInfo[instId].getInstName());
|
||||
sb.appendString(X86Util::getInstNameById(instId));
|
||||
for (uint32_t i = 0; i < opCount; i++) {
|
||||
if (i == 0)
|
||||
sb.appendChar(' ');
|
||||
@@ -409,7 +409,7 @@ static const X86SpecialInst x86SpecialInstScas[] = {
|
||||
{ kX86RegIndexCx, kX86RegIndexCx, kVarAttrXReg }
|
||||
};
|
||||
|
||||
static const X86SpecialInst x86SpecialInstShlrd[] = {
|
||||
static const X86SpecialInst x86SpecialInstShldShrd[] = {
|
||||
{ kInvalidReg , kInvalidReg , kVarAttrXReg },
|
||||
{ kInvalidReg , kInvalidReg , kVarAttrRReg },
|
||||
{ kX86RegIndexCx, kInvalidReg , kVarAttrRReg }
|
||||
@@ -421,12 +421,23 @@ static const X86SpecialInst x86SpecialInstStos[] = {
|
||||
{ kX86RegIndexCx, kX86RegIndexCx, kVarAttrXReg }
|
||||
};
|
||||
|
||||
static const X86SpecialInst x86SpecialInstBlend[] = {
|
||||
static const X86SpecialInst x86SpecialInstThirdXMM0[] = {
|
||||
{ kInvalidReg , kInvalidReg , kVarAttrWReg },
|
||||
{ kInvalidReg , kInvalidReg , kVarAttrRReg },
|
||||
{ 0 , kInvalidReg , kVarAttrRReg }
|
||||
};
|
||||
|
||||
static const X86SpecialInst x86SpecialInstPcmpistri[] = {
|
||||
{ kInvalidReg , kX86RegIndexCx, kVarAttrWReg },
|
||||
{ kInvalidReg , kInvalidReg , kVarAttrRReg },
|
||||
{ kInvalidReg , kInvalidReg , kVarAttrRReg }
|
||||
};
|
||||
static const X86SpecialInst x86SpecialInstPcmpistrm[] = {
|
||||
{ kInvalidReg , 0 , kVarAttrWReg },
|
||||
{ kInvalidReg , kInvalidReg , kVarAttrRReg },
|
||||
{ kInvalidReg , kInvalidReg , kVarAttrRReg }
|
||||
};
|
||||
|
||||
static const X86SpecialInst x86SpecialInstXsaveXrstor[] = {
|
||||
{ kInvalidReg , kInvalidReg , 0 },
|
||||
{ kX86RegIndexDx, kInvalidReg , kVarAttrRReg },
|
||||
@@ -533,6 +544,7 @@ static ASMJIT_INLINE const X86SpecialInst* X86SpecialInst_get(uint32_t instId, c
|
||||
|
||||
case kX86InstIdMaskmovq:
|
||||
case kX86InstIdMaskmovdqu:
|
||||
case kX86InstIdVmaskmovdqu:
|
||||
return x86SpecialInstMaskmovqMaskmovdqu;
|
||||
|
||||
// Not supported.
|
||||
@@ -585,7 +597,7 @@ static ASMJIT_INLINE const X86SpecialInst* X86SpecialInst_get(uint32_t instId, c
|
||||
case kX86InstIdShrd:
|
||||
if (!opList[2].isVar())
|
||||
return nullptr;
|
||||
return x86SpecialInstShlrd;
|
||||
return x86SpecialInstShldShrd;
|
||||
|
||||
case kX86InstIdRdtsc:
|
||||
case kX86InstIdRdtscp:
|
||||
@@ -618,7 +630,20 @@ static ASMJIT_INLINE const X86SpecialInst* X86SpecialInst_get(uint32_t instId, c
|
||||
case kX86InstIdBlendvpd:
|
||||
case kX86InstIdBlendvps:
|
||||
case kX86InstIdPblendvb:
|
||||
return x86SpecialInstBlend;
|
||||
case kX86InstIdSha256rnds2:
|
||||
return x86SpecialInstThirdXMM0;
|
||||
|
||||
case kX86InstIdPcmpestri:
|
||||
case kX86InstIdPcmpistri:
|
||||
case kX86InstIdVpcmpestri:
|
||||
case kX86InstIdVpcmpistri:
|
||||
return x86SpecialInstPcmpistri;
|
||||
|
||||
case kX86InstIdPcmpestrm:
|
||||
case kX86InstIdPcmpistrm:
|
||||
case kX86InstIdVpcmpestrm:
|
||||
case kX86InstIdVpcmpistrm:
|
||||
return x86SpecialInstPcmpistrm;
|
||||
|
||||
case kX86InstIdXrstor:
|
||||
case kX86InstIdXrstor64:
|
||||
@@ -985,22 +1010,22 @@ void X86Context::emitMoveVarOnStack(
|
||||
switch (dstType) {
|
||||
case kVarTypeInt8:
|
||||
case kVarTypeUInt8:
|
||||
// Move DWORD (Gp).
|
||||
// Move DWORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt8, kVarTypeUInt64))
|
||||
goto _MovGpD;
|
||||
|
||||
// Move DWORD (Mm).
|
||||
// Move DWORD (MMX).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kX86VarTypeMm, kX86VarTypeMm))
|
||||
goto _MovMmD;
|
||||
|
||||
// Move DWORD (Xmm).
|
||||
// Move DWORD (XMM).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd))
|
||||
goto _MovXmmD;
|
||||
break;
|
||||
|
||||
case kVarTypeInt16:
|
||||
case kVarTypeUInt16:
|
||||
// Extend BYTE->WORD (Gp).
|
||||
// Extend BYTE->WORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt8, kVarTypeUInt8)) {
|
||||
r1.setSize(1);
|
||||
r1.setCode(kX86RegTypeGpbLo, srcIndex);
|
||||
@@ -1009,22 +1034,22 @@ void X86Context::emitMoveVarOnStack(
|
||||
goto _ExtendMovGpD;
|
||||
}
|
||||
|
||||
// Move DWORD (Gp).
|
||||
// Move DWORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt16, kVarTypeUInt64))
|
||||
goto _MovGpD;
|
||||
|
||||
// Move DWORD (Mm).
|
||||
// Move DWORD (MMX).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kX86VarTypeMm, kX86VarTypeMm))
|
||||
goto _MovMmD;
|
||||
|
||||
// Move DWORD (Xmm).
|
||||
// Move DWORD (XMM).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd))
|
||||
goto _MovXmmD;
|
||||
break;
|
||||
|
||||
case kVarTypeInt32:
|
||||
case kVarTypeUInt32:
|
||||
// Extend BYTE->DWORD (Gp).
|
||||
// Extend BYTE->DWORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt8, kVarTypeUInt8)) {
|
||||
r1.setSize(1);
|
||||
r1.setCode(kX86RegTypeGpbLo, srcIndex);
|
||||
@@ -1033,7 +1058,7 @@ void X86Context::emitMoveVarOnStack(
|
||||
goto _ExtendMovGpD;
|
||||
}
|
||||
|
||||
// Extend WORD->DWORD (Gp).
|
||||
// Extend WORD->DWORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt16, kVarTypeUInt16)) {
|
||||
r1.setSize(2);
|
||||
r1.setCode(kX86RegTypeGpw, srcIndex);
|
||||
@@ -1042,22 +1067,22 @@ void X86Context::emitMoveVarOnStack(
|
||||
goto _ExtendMovGpD;
|
||||
}
|
||||
|
||||
// Move DWORD (Gp).
|
||||
// Move DWORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt32, kVarTypeUInt64))
|
||||
goto _MovGpD;
|
||||
|
||||
// Move DWORD (Mm).
|
||||
// Move DWORD (MMX).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kX86VarTypeMm, kX86VarTypeMm))
|
||||
goto _MovMmD;
|
||||
|
||||
// Move DWORD (Xmm).
|
||||
// Move DWORD (XMM).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd))
|
||||
goto _MovXmmD;
|
||||
break;
|
||||
|
||||
case kVarTypeInt64:
|
||||
case kVarTypeUInt64:
|
||||
// Extend BYTE->QWORD (Gp).
|
||||
// Extend BYTE->QWORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt8, kVarTypeUInt8)) {
|
||||
r1.setSize(1);
|
||||
r1.setCode(kX86RegTypeGpbLo, srcIndex);
|
||||
@@ -1066,7 +1091,7 @@ void X86Context::emitMoveVarOnStack(
|
||||
goto _ExtendMovGpXQ;
|
||||
}
|
||||
|
||||
// Extend WORD->QWORD (Gp).
|
||||
// Extend WORD->QWORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt16, kVarTypeUInt16)) {
|
||||
r1.setSize(2);
|
||||
r1.setCode(kX86RegTypeGpw, srcIndex);
|
||||
@@ -1075,7 +1100,7 @@ void X86Context::emitMoveVarOnStack(
|
||||
goto _ExtendMovGpXQ;
|
||||
}
|
||||
|
||||
// Extend DWORD->QWORD (Gp).
|
||||
// Extend DWORD->QWORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt32, kVarTypeUInt32)) {
|
||||
r1.setSize(4);
|
||||
r1.setCode(kX86RegTypeGpd, srcIndex);
|
||||
@@ -1087,21 +1112,21 @@ void X86Context::emitMoveVarOnStack(
|
||||
goto _ZeroExtendGpDQ;
|
||||
}
|
||||
|
||||
// Move QWORD (Gp).
|
||||
// Move QWORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt64, kVarTypeUInt64))
|
||||
goto _MovGpQ;
|
||||
|
||||
// Move QWORD (Mm).
|
||||
// Move QWORD (MMX).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kX86VarTypeMm, kX86VarTypeMm))
|
||||
goto _MovMmQ;
|
||||
|
||||
// Move QWORD (Xmm).
|
||||
// Move QWORD (XMM).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd))
|
||||
goto _MovXmmQ;
|
||||
break;
|
||||
|
||||
case kX86VarTypeMm:
|
||||
// Extend BYTE->QWORD (Gp).
|
||||
// Extend BYTE->QWORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt8, kVarTypeUInt8)) {
|
||||
r1.setSize(1);
|
||||
r1.setCode(kX86RegTypeGpbLo, srcIndex);
|
||||
@@ -1110,7 +1135,7 @@ void X86Context::emitMoveVarOnStack(
|
||||
goto _ExtendMovGpXQ;
|
||||
}
|
||||
|
||||
// Extend WORD->QWORD (Gp).
|
||||
// Extend WORD->QWORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt16, kVarTypeUInt16)) {
|
||||
r1.setSize(2);
|
||||
r1.setCode(kX86RegTypeGpw, srcIndex);
|
||||
@@ -1119,19 +1144,19 @@ void X86Context::emitMoveVarOnStack(
|
||||
goto _ExtendMovGpXQ;
|
||||
}
|
||||
|
||||
// Extend DWORD->QWORD (Gp).
|
||||
// Extend DWORD->QWORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt32, kVarTypeUInt32))
|
||||
goto _ExtendMovGpDQ;
|
||||
|
||||
// Move QWORD (Gp).
|
||||
// Move QWORD (GP).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kVarTypeInt64, kVarTypeUInt64))
|
||||
goto _MovGpQ;
|
||||
|
||||
// Move QWORD (Mm).
|
||||
// Move QWORD (MMX).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kX86VarTypeMm, kX86VarTypeMm))
|
||||
goto _MovMmQ;
|
||||
|
||||
// Move QWORD (Xmm).
|
||||
// Move QWORD (XMM).
|
||||
if (Utils::inInterval<uint32_t>(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd))
|
||||
goto _MovXmmQ;
|
||||
break;
|
||||
@@ -1240,7 +1265,7 @@ _MovMmQ:
|
||||
compiler->emit(kX86InstIdMovq, m0, r0);
|
||||
return;
|
||||
|
||||
// Move Xmm.
|
||||
// Move XMM.
|
||||
_MovXmmD:
|
||||
m0.setSize(4);
|
||||
r0.setSize(16);
|
||||
@@ -1385,7 +1410,7 @@ _Move32:
|
||||
|
||||
case kVarTypeInt64:
|
||||
case kVarTypeUInt64:
|
||||
// Move to Gpd register will also clear high DWORD of Gpq register in
|
||||
// Move to GPD register will also clear high DWORD of GPQ register in
|
||||
// 64-bit mode.
|
||||
if (imm.isUInt32())
|
||||
goto _Move32Truncate;
|
||||
@@ -2161,7 +2186,7 @@ Error X86Context::fetch() {
|
||||
if (!func->hasFuncFlag(kFuncFlagIsNaked))
|
||||
gaRegs[kX86RegClassGp] &= ~Utils::mask(kX86RegIndexBp);
|
||||
|
||||
// Allowed index registers (Gp/Xmm/Ymm).
|
||||
// Allowed index registers (GP/XMM/YMM).
|
||||
const uint32_t indexMask = Utils::bits(_regCount.getGp()) & ~(Utils::mask(4, 12));
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -2446,7 +2471,7 @@ _NextGroup:
|
||||
else {
|
||||
// It's fine if lo-byte register is accessed in 64-bit mode;
|
||||
// however, hi-byte has to be checked and if it's used all
|
||||
// registers (Gp/Xmm) could be only allocated in the lower eight
|
||||
// registers (GP/XMM) could be only allocated in the lower eight
|
||||
// half. To do that, we patch 'allocableRegs' of all variables
|
||||
// we collected until now and change the allocable restriction
|
||||
// for variables that come after.
|
||||
@@ -2492,17 +2517,15 @@ _NextGroup:
|
||||
uint32_t combinedFlags;
|
||||
|
||||
if (i == 0) {
|
||||
// Read/Write is usualy the combination of the first operand.
|
||||
// Read/Write is usually the combination of the first operand.
|
||||
combinedFlags = inFlags | outFlags;
|
||||
|
||||
// Handle overwrite option.
|
||||
if (node->getOptions() & kInstOptionOverwrite) {
|
||||
// Manually forcing write-only.
|
||||
combinedFlags = outFlags;
|
||||
}
|
||||
// Move instructions typically overwrite the first operand,
|
||||
// but there are some exceptions based on the operands' size
|
||||
// and type.
|
||||
else if (extendedInfo.isMove()) {
|
||||
else if (extendedInfo.isWO()) {
|
||||
// Write-only instruction.
|
||||
uint32_t movSize = extendedInfo.getWriteSize();
|
||||
uint32_t varSize = vd->getSize();
|
||||
|
||||
@@ -2520,7 +2543,7 @@ _NextGroup:
|
||||
movSize = opSize;
|
||||
|
||||
// Handle the case that a 32-bit operation in 64-bit mode
|
||||
// always zeroes the rest of the destination register and
|
||||
// always clears the rest of the destination register and
|
||||
// the case that move size is actually greater than or
|
||||
// equal to the size of the variable.
|
||||
if (movSize >= 4 || movSize >= varSize)
|
||||
@@ -2533,12 +2556,12 @@ _NextGroup:
|
||||
combinedFlags = outFlags;
|
||||
}
|
||||
}
|
||||
// Comparison/Test instructions don't modify any operand.
|
||||
else if (extendedInfo.isTest()) {
|
||||
else if (extendedInfo.isRO()) {
|
||||
// Comparison/Test instructions don't modify any operand.
|
||||
combinedFlags = inFlags;
|
||||
}
|
||||
// Imul.
|
||||
else if (instId == kX86InstIdImul && opCount == 3) {
|
||||
// Imul.
|
||||
combinedFlags = outFlags;
|
||||
}
|
||||
}
|
||||
@@ -2576,18 +2599,18 @@ _NextGroup:
|
||||
// Default for the first operand.
|
||||
combinedFlags = inFlags | outFlags;
|
||||
|
||||
// Move to memory - setting the right flags is important
|
||||
// as if it's just move to the register. It's just a bit
|
||||
// simpler as there are no special cases.
|
||||
if (extendedInfo.isMove()) {
|
||||
if (extendedInfo.isWO()) {
|
||||
// Move to memory - setting the right flags is important
|
||||
// as if it's just move to the register. It's just a bit
|
||||
// simpler as there are no special cases.
|
||||
uint32_t movSize = Utils::iMax<uint32_t>(extendedInfo.getWriteSize(), m->getSize());
|
||||
uint32_t varSize = vd->getSize();
|
||||
|
||||
if (movSize >= varSize)
|
||||
combinedFlags = outFlags;
|
||||
}
|
||||
// Comparison/Test instructions don't modify any operand.
|
||||
else if (extendedInfo.isTest()) {
|
||||
else if (extendedInfo.isRO()) {
|
||||
// Comparison/Test instructions don't modify any operand.
|
||||
combinedFlags = inFlags;
|
||||
}
|
||||
}
|
||||
@@ -5142,7 +5165,7 @@ static Error X86Context_translatePrologEpilog(X86Context* self, X86FuncNode* fun
|
||||
stackBase = -static_cast<int32_t>(func->getAlignStackSize() + func->getMoveStackSize());
|
||||
}
|
||||
|
||||
// Save Xmm/Mm/Gp (Mov).
|
||||
// Save XMM/MMX/GP (Mov).
|
||||
stackPtr = stackBase;
|
||||
for (i = 0, mask = regsXmm; mask != 0; i++, mask >>= 1) {
|
||||
if (mask & 0x1) {
|
||||
@@ -5208,7 +5231,7 @@ static Error X86Context_translatePrologEpilog(X86Context* self, X86FuncNode* fun
|
||||
|
||||
compiler->_setCursor(func->getExitNode());
|
||||
|
||||
// Restore Xmm/Mm/Gp (Mov).
|
||||
// Restore XMM/MMX/GP (Mov).
|
||||
stackPtr = stackBase;
|
||||
for (i = 0, mask = regsXmm; mask != 0; i++, mask >>= 1) {
|
||||
if (mask & 0x1) {
|
||||
|
||||
@@ -170,19 +170,19 @@ union X86StateCell {
|
||||
//! X86/X64 state.
|
||||
struct X86VarState : VarState {
|
||||
enum {
|
||||
//! Base index of Gp registers.
|
||||
//! Base index of GP registers.
|
||||
kGpIndex = 0,
|
||||
//! Count of Gp registers.
|
||||
//! Count of GP registers.
|
||||
kGpCount = 16,
|
||||
|
||||
//! Base index of Mm registers.
|
||||
//! Base index of MMX registers.
|
||||
kMmIndex = kGpIndex + kGpCount,
|
||||
//! Count of Mm registers.
|
||||
kMmCount = 8,
|
||||
|
||||
//! Base index of Xmm registers.
|
||||
//! Base index of XMM registers.
|
||||
kXmmIndex = kMmIndex + kMmCount,
|
||||
//! Count of Xmm registers.
|
||||
//! Count of XMM registers.
|
||||
kXmmCount = 16,
|
||||
|
||||
//! Count of all registers in `X86VarState`.
|
||||
@@ -227,11 +227,11 @@ struct X86VarState : VarState {
|
||||
VarData* _list[kAllCount];
|
||||
|
||||
struct {
|
||||
//! Allocated Gp registers.
|
||||
//! Allocated GP registers.
|
||||
VarData* _listGp[kGpCount];
|
||||
//! Allocated Mm registers.
|
||||
//! Allocated MMX registers.
|
||||
VarData* _listMm[kMmCount];
|
||||
//! Allocated Xmm registers.
|
||||
//! Allocated XMM registers.
|
||||
VarData* _listXmm[kXmmCount];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -378,7 +378,7 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch,
|
||||
if (callConv == kCallConvX64Win) {
|
||||
int32_t argMax = Utils::iMin<int32_t>(numArgs, 4);
|
||||
|
||||
// Register arguments (Gp/Xmm), always left-to-right.
|
||||
// Register arguments (GP/XMM), always left-to-right.
|
||||
for (i = 0; i != argMax; i++) {
|
||||
FuncInOut& arg = self->getArg(i);
|
||||
uint32_t varType = varMapping[arg.getVarType()];
|
||||
@@ -433,7 +433,7 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch,
|
||||
self->_used.or_(kX86RegClassGp, Utils::mask(arg.getRegIndex()));
|
||||
}
|
||||
|
||||
// Register arguments (Xmm), always left-to-right.
|
||||
// Register arguments (XMM), always left-to-right.
|
||||
for (i = 0; i != static_cast<int32_t>(numArgs); i++) {
|
||||
FuncInOut& arg = self->getArg(i);
|
||||
uint32_t varType = varMapping[arg.getVarType()];
|
||||
|
||||
@@ -58,32 +58,32 @@ struct X86FuncDecl : public FuncDecl {
|
||||
|
||||
//! Get used registers mask for the given register class `rc`.
|
||||
//!
|
||||
//! \note The result depends on the function calling convention AND the
|
||||
//! NOTE: The result depends on the function calling convention AND the
|
||||
//! function prototype. Returned mask contains only registers actually used
|
||||
//! to pass function arguments.
|
||||
ASMJIT_INLINE uint32_t getUsed(uint32_t rc) const { return _used.get(rc); }
|
||||
|
||||
//! Get passed registers mask for the given register class `rc`.
|
||||
//!
|
||||
//! \note The result depends on the function calling convention used; the
|
||||
//! NOTE: The result depends on the function calling convention used; the
|
||||
//! prototype of the function doesn't affect the mask returned.
|
||||
ASMJIT_INLINE uint32_t getPassed(uint32_t rc) const { return _passed.get(rc); }
|
||||
|
||||
//! Get preserved registers mask for the given register class `rc`.
|
||||
//!
|
||||
//! \note The result depends on the function calling convention used; the
|
||||
//! NOTE: The result depends on the function calling convention used; the
|
||||
//! prototype of the function doesn't affect the mask returned.
|
||||
ASMJIT_INLINE uint32_t getPreserved(uint32_t rc) const { return _preserved.get(rc); }
|
||||
|
||||
//! Get ther order of passed registers (Gp).
|
||||
//! Get ther order of passed registers (GP).
|
||||
//!
|
||||
//! \note The result depends on the function calling convention used; the
|
||||
//! NOTE: The result depends on the function calling convention used; the
|
||||
//! prototype of the function doesn't affect the mask returned.
|
||||
ASMJIT_INLINE const uint8_t* getPassedOrderGp() const { return _passedOrderGp; }
|
||||
|
||||
//! Get ther order of passed registers (Xmm/Ymm/Zmm).
|
||||
//! Get ther order of passed registers (XMM/YMM/ZMM).
|
||||
//!
|
||||
//! \note The result depends on the function calling convention used; the
|
||||
//! NOTE: The result depends on the function calling convention used; the
|
||||
//! prototype of the function doesn't affect the mask returned.
|
||||
ASMJIT_INLINE const uint8_t* getPassedOrderXyz() const { return _passedOrderXyz; }
|
||||
|
||||
@@ -95,7 +95,7 @@ struct X86FuncDecl : public FuncDecl {
|
||||
//!
|
||||
//! This will set function calling convention and setup arguments variables.
|
||||
//!
|
||||
//! \note This function will allocate variables, it can be called only once.
|
||||
//! NOTE: This function will allocate variables, it can be called only once.
|
||||
ASMJIT_API Error setPrototype(const FuncPrototype& p);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -115,9 +115,9 @@ struct X86FuncDecl : public FuncDecl {
|
||||
//! Preserved registers (defined by the calling convention).
|
||||
X86RegMask _preserved;
|
||||
|
||||
//! Order of registers used to pass Gp function arguments.
|
||||
//! Order of registers used to pass GP function arguments.
|
||||
uint8_t _passedOrderGp[8];
|
||||
//! Order of registers used to pass Xmm function arguments.
|
||||
//! Order of registers used to pass XMM/YMM/ZMM function arguments.
|
||||
uint8_t _passedOrderXyz[8];
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -71,7 +71,7 @@ ASMJIT_ENUM(X86RegClass) {
|
||||
kX86RegClassMm = 1,
|
||||
//! X86/X64 K register class.
|
||||
kX86RegClassK = 2,
|
||||
//! X86/X64 Xmm/Ymm/Zmm register class.
|
||||
//! X86/X64 XMM/YMM/ZMM register class.
|
||||
kX86RegClassXyz = 3,
|
||||
|
||||
//! \internal
|
||||
@@ -96,36 +96,36 @@ ASMJIT_ENUM(X86RegClass) {
|
||||
|
||||
//! X86/X64 register type.
|
||||
ASMJIT_ENUM(X86RegType) {
|
||||
//! Gpb-lo register (AL, BL, CL, DL, ...).
|
||||
//! Low GPB register (AL, BL, CL, DL, ...).
|
||||
kX86RegTypeGpbLo = 0x01,
|
||||
//! Gpb-hi register (AH, BH, CH, DH only).
|
||||
//! High GPB register (AH, BH, CH, DH only).
|
||||
kX86RegTypeGpbHi = 0x02,
|
||||
|
||||
//! \internal
|
||||
//!
|
||||
//! Gpb-hi register patched to native index (4-7).
|
||||
//! High GPB register patched to a native index (4-7).
|
||||
_kX86RegTypePatchedGpbHi = kX86RegTypeGpbLo | kX86RegTypeGpbHi,
|
||||
|
||||
//! Gpw register.
|
||||
//! GPW register.
|
||||
kX86RegTypeGpw = 0x10,
|
||||
//! Gpd register.
|
||||
//! GPD register.
|
||||
kX86RegTypeGpd = 0x20,
|
||||
//! Gpq register (X64).
|
||||
//! GPQ register (X64).
|
||||
kX86RegTypeGpq = 0x30,
|
||||
|
||||
//! Fp register.
|
||||
//! FPU register.
|
||||
kX86RegTypeFp = 0x40,
|
||||
//! Mm register (MMX+).
|
||||
//! MMX register (MMX+).
|
||||
kX86RegTypeMm = 0x50,
|
||||
|
||||
//! K register (AVX512+).
|
||||
kX86RegTypeK = 0x60,
|
||||
|
||||
//! Xmm register (SSE+).
|
||||
//! XMM register (SSE+).
|
||||
kX86RegTypeXmm = 0x70,
|
||||
//! Ymm register (AVX+).
|
||||
//! YMM register (AVX+).
|
||||
kX86RegTypeYmm = 0x80,
|
||||
//! Zmm register (AVX512+).
|
||||
//! ZMM register (AVX512+).
|
||||
kX86RegTypeZmm = 0x90,
|
||||
|
||||
//! Instruction pointer (RIP).
|
||||
@@ -140,7 +140,7 @@ ASMJIT_ENUM(X86RegType) {
|
||||
|
||||
//! X86/X64 register indexes.
|
||||
//!
|
||||
//! \note Register indexes have been reduced to only support general purpose
|
||||
//! NOTE: Register indexes have been reduced to only support general purpose
|
||||
//! registers. There is no need to have enumerations with number suffix that
|
||||
//! expands to the exactly same value as the suffix value itself.
|
||||
ASMJIT_ENUM(X86RegIndex) {
|
||||
@@ -201,7 +201,7 @@ ASMJIT_ENUM(X86Seg) {
|
||||
|
||||
//! Count of X86 segment registers supported by AsmJit.
|
||||
//!
|
||||
//! \note X86 architecture has 6 segment registers - ES, CS, SS, DS, FS, GS.
|
||||
//! NOTE: X86 architecture has 6 segment registers - ES, CS, SS, DS, FS, GS.
|
||||
//! X64 architecture lowers them down to just FS and GS. AsmJit supports 7
|
||||
//! segment registers - all addressable in both X86 and X64 modes and one
|
||||
//! extra called `kX86SegDefault`, which is AsmJit specific and means that there
|
||||
@@ -215,13 +215,13 @@ ASMJIT_ENUM(X86Seg) {
|
||||
|
||||
//! X86/X64 index register legacy and AVX2 (VSIB) support.
|
||||
ASMJIT_ENUM(X86MemVSib) {
|
||||
//! Memory operand uses Gpd/Gpq index (or no index register).
|
||||
//! Memory operand uses GPD/GPQ index (or no index register).
|
||||
kX86MemVSibGpz = 0,
|
||||
//! Memory operand uses Xmm index (or no index register).
|
||||
//! Memory operand uses XMM index (or no index register).
|
||||
kX86MemVSibXmm = 1,
|
||||
//! Memory operand uses Ymm index (or no index register).
|
||||
//! Memory operand uses YMM index (or no index register).
|
||||
kX86MemVSibYmm = 2,
|
||||
//! Memory operand uses Zmm index (or no index register).
|
||||
//! Memory operand uses ZMM index (or no index register).
|
||||
kX86MemVSibZmm = 3
|
||||
};
|
||||
|
||||
@@ -256,40 +256,40 @@ ASMJIT_ENUM(X86MemFlags) {
|
||||
|
||||
//! X86/X64 variable type.
|
||||
ASMJIT_ENUM(X86VarType) {
|
||||
//! Variable is SP-FP (x87).
|
||||
//! Variable is SP-FP (FPU).
|
||||
kX86VarTypeFp32 = kVarTypeFp32,
|
||||
//! Variable is DP-FP (x87).
|
||||
//! Variable is DP-FP (FPU).
|
||||
kX86VarTypeFp64 = kVarTypeFp64,
|
||||
|
||||
//! Variable is Mm (MMX).
|
||||
//! Variable is MMX (MMX).
|
||||
kX86VarTypeMm = 12,
|
||||
|
||||
//! Variable is K (AVX512+)
|
||||
kX86VarTypeK,
|
||||
|
||||
//! Variable is Xmm (SSE+).
|
||||
//! Variable is XMM (SSE+).
|
||||
kX86VarTypeXmm,
|
||||
//! Variable is a scalar Xmm SP-FP number.
|
||||
//! Variable is a scalar XMM SP-FP number.
|
||||
kX86VarTypeXmmSs,
|
||||
//! Variable is a packed Xmm SP-FP number (4 floats).
|
||||
//! Variable is a packed XMM SP-FP number (4 floats).
|
||||
kX86VarTypeXmmPs,
|
||||
//! Variable is a scalar Xmm DP-FP number.
|
||||
//! Variable is a scalar XMM DP-FP number.
|
||||
kX86VarTypeXmmSd,
|
||||
//! Variable is a packed Xmm DP-FP number (2 doubles).
|
||||
//! Variable is a packed XMM DP-FP number (2 doubles).
|
||||
kX86VarTypeXmmPd,
|
||||
|
||||
//! Variable is Ymm (AVX+).
|
||||
//! Variable is YMM (AVX+).
|
||||
kX86VarTypeYmm,
|
||||
//! Variable is a packed Ymm SP-FP number (8 floats).
|
||||
//! Variable is a packed YMM SP-FP number (8 floats).
|
||||
kX86VarTypeYmmPs,
|
||||
//! Variable is a packed Ymm DP-FP number (4 doubles).
|
||||
//! Variable is a packed YMM DP-FP number (4 doubles).
|
||||
kX86VarTypeYmmPd,
|
||||
|
||||
//! Variable is Zmm (AVX512+).
|
||||
//! Variable is ZMM (AVX512+).
|
||||
kX86VarTypeZmm,
|
||||
//! Variable is a packed Zmm SP-FP number (16 floats).
|
||||
//! Variable is a packed ZMM SP-FP number (16 floats).
|
||||
kX86VarTypeZmmPs,
|
||||
//! Variable is a packed Zmm DP-FP number (8 doubles).
|
||||
//! Variable is a packed ZMM DP-FP number (8 doubles).
|
||||
kX86VarTypeZmmPd,
|
||||
|
||||
//! Count of variable types.
|
||||
@@ -323,15 +323,15 @@ ASMJIT_ENUM(X86VarType) {
|
||||
//! class is used by `X86Assembler` and `X86Compiler` to provide a way to get
|
||||
//! number of available registers dynamically. 32-bit mode offers always only
|
||||
//! 8 registers of all classes, however, 64-bit mode offers 16 Gp registers and
|
||||
//! 16 Xmm/Ymm/Zmm registers. AVX512 instruction set doubles the number of SIMD
|
||||
//! registers (Xmm/Ymm/Zmm) to 32, this mode has to be explicitly enabled to
|
||||
//! 16 XMM/YMM/ZMM registers. AVX512 instruction set doubles the number of SIMD
|
||||
//! registers (XMM/YMM/ZMM) to 32, this mode has to be explicitly enabled to
|
||||
//! take effect as it changes some assumptions.
|
||||
//!
|
||||
//! `X86RegCount` is also used extensively by `X86Compiler`'s register allocator
|
||||
//! and data structures. Fp registers were omitted as they are never mapped to
|
||||
//! variables, thus, not needed to be managed.
|
||||
//!
|
||||
//! \note At the moment `X86RegCount` can fit into 32-bits, having 8-bits for
|
||||
//! NOTE: At the moment `X86RegCount` can fit into 32-bits, having 8-bits for
|
||||
//! each register class except `fp`. This can change in the future after a
|
||||
//! new instruction set, which adds more registers, is introduced.
|
||||
struct X86RegCount {
|
||||
@@ -360,7 +360,7 @@ struct X86RegCount {
|
||||
ASMJIT_INLINE uint32_t getMm() const noexcept { return get(kX86RegClassMm); }
|
||||
//! Get K count.
|
||||
ASMJIT_INLINE uint32_t getK() const noexcept { return get(kX86RegClassK); }
|
||||
//! Get Xmm/Ymm/Zmm count.
|
||||
//! Get XMM/YMM/ZMM count.
|
||||
ASMJIT_INLINE uint32_t getXyz() const noexcept { return get(kX86RegClassXyz); }
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -382,7 +382,7 @@ struct X86RegCount {
|
||||
ASMJIT_INLINE void setMm(uint32_t n) noexcept { set(kX86RegClassMm, n); }
|
||||
//! Set K count.
|
||||
ASMJIT_INLINE void setK(uint32_t n) noexcept { set(kX86RegClassK, n); }
|
||||
//! Set Xmm/Ymm/Zmm count.
|
||||
//! Set XMM/YMM/ZMM count.
|
||||
ASMJIT_INLINE void setXyz(uint32_t n) noexcept { set(kX86RegClassXyz, n); }
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -398,13 +398,13 @@ struct X86RegCount {
|
||||
_packed += n << shift;
|
||||
}
|
||||
|
||||
//! Add Gp count.
|
||||
//! Add GP count.
|
||||
ASMJIT_INLINE void addGp(uint32_t n) noexcept { add(kX86RegClassGp, n); }
|
||||
//! Add Mm count.
|
||||
//! Add MMX count.
|
||||
ASMJIT_INLINE void addMm(uint32_t n) noexcept { add(kX86RegClassMm, n); }
|
||||
//! Add K count.
|
||||
ASMJIT_INLINE void addK(uint32_t n) noexcept { add(kX86RegClassK, n); }
|
||||
//! Add Xmm/Ymm/Zmm count.
|
||||
//! Add XMM/YMM/ZMM count.
|
||||
ASMJIT_INLINE void addXyz(uint32_t n) noexcept { add(kX86RegClassXyz, n); }
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -428,13 +428,13 @@ struct X86RegCount {
|
||||
|
||||
union {
|
||||
struct {
|
||||
//! Count of Gp registers.
|
||||
//! Count of GP registers.
|
||||
uint8_t _gp;
|
||||
//! Count of Mm registers.
|
||||
//! Count of MMX registers.
|
||||
uint8_t _mm;
|
||||
//! Count of K registers.
|
||||
uint8_t _k;
|
||||
//! Count of Xmm/Ymm/Zmm registers.
|
||||
//! Count of XMM/YMM/ZMM registers.
|
||||
uint8_t _xyz;
|
||||
};
|
||||
|
||||
@@ -654,13 +654,13 @@ struct X86RegMask {
|
||||
|
||||
union {
|
||||
struct {
|
||||
//! Gp registers mask (16 bits).
|
||||
//! GP registers mask (16 bits).
|
||||
uint16_t _gp;
|
||||
//! Mm registers mask (8 bits).
|
||||
//! MMX registers mask (8 bits).
|
||||
uint8_t _mm;
|
||||
//! K registers mask (8 bits).
|
||||
uint8_t _k;
|
||||
//! Xmm/Ymm/Zmm registers mask (32 bits).
|
||||
//! XMM/YMM/ZMM registers mask (32 bits).
|
||||
uint32_t _xyz;
|
||||
};
|
||||
|
||||
@@ -720,46 +720,46 @@ class X86Reg : public Reg {
|
||||
|
||||
ASMJIT_REG_OP(X86Reg)
|
||||
|
||||
//! Get whether the register is Gp register.
|
||||
//! Get whether the register is a GP register (any size).
|
||||
ASMJIT_INLINE bool isGp() const noexcept { return _vreg.type <= kX86RegTypeGpq; }
|
||||
//! Get whether the register is Gp byte (8-bit) register.
|
||||
//! Get whether the register is a GPB register (8-bit).
|
||||
ASMJIT_INLINE bool isGpb() const noexcept { return _vreg.type <= _kX86RegTypePatchedGpbHi; }
|
||||
//! Get whether the register is Gp lo-byte (8-bit) register.
|
||||
//! Get whether the register is a low GPB register (8-bit).
|
||||
ASMJIT_INLINE bool isGpbLo() const noexcept { return _vreg.type == kX86RegTypeGpbLo; }
|
||||
//! Get whether the register is Gp hi-byte (8-bit) register.
|
||||
//! Get whether the register is a high GPB register (8-bit).
|
||||
ASMJIT_INLINE bool isGpbHi() const noexcept { return _vreg.type == kX86RegTypeGpbHi; }
|
||||
//! Get whether the register is Gp word (16-bit) register.
|
||||
//! Get whether the register is a GPW register (16-bit).
|
||||
ASMJIT_INLINE bool isGpw() const noexcept { return _vreg.type == kX86RegTypeGpw; }
|
||||
//! Get whether the register is Gp dword (32-bit) register.
|
||||
//! Get whether the register is a GPD register (32-bit).
|
||||
ASMJIT_INLINE bool isGpd() const noexcept { return _vreg.type == kX86RegTypeGpd; }
|
||||
//! Get whether the register is Gp qword (64-bit) register.
|
||||
//! Get whether the register is a GPQ register (64-bit).
|
||||
ASMJIT_INLINE bool isGpq() const noexcept { return _vreg.type == kX86RegTypeGpq; }
|
||||
|
||||
//! Get whether the register is Fp register.
|
||||
//! Get whether the register is an FPU register (80-bit).
|
||||
ASMJIT_INLINE bool isFp() const noexcept { return _vreg.type == kX86RegTypeFp; }
|
||||
//! Get whether the register is Mm (64-bit) register.
|
||||
//! Get whether the register is an MMX register (64-bit).
|
||||
ASMJIT_INLINE bool isMm() const noexcept { return _vreg.type == kX86RegTypeMm; }
|
||||
|
||||
//! Get whether the register is K (64-bit) register.
|
||||
//! Get whether the register is a K register (64-bit).
|
||||
ASMJIT_INLINE bool isK() const noexcept { return _vreg.type == kX86RegTypeK; }
|
||||
|
||||
//! Get whether the register is Xmm (128-bit) register.
|
||||
//! Get whether the register is an XMM register (128-bit).
|
||||
ASMJIT_INLINE bool isXmm() const noexcept { return _vreg.type == kX86RegTypeXmm; }
|
||||
//! Get whether the register is Ymm (256-bit) register.
|
||||
//! Get whether the register is a YMM register (256-bit).
|
||||
ASMJIT_INLINE bool isYmm() const noexcept { return _vreg.type == kX86RegTypeYmm; }
|
||||
//! Get whether the register is Zmm (512-bit) register.
|
||||
//! Get whether the register is a ZMM register (512-bit).
|
||||
ASMJIT_INLINE bool isZmm() const noexcept { return _vreg.type == kX86RegTypeZmm; }
|
||||
|
||||
//! Get whether the register is RIP.
|
||||
ASMJIT_INLINE bool isRip() const noexcept { return _vreg.type == kX86RegTypeRip; }
|
||||
//! Get whether the register is Segment.
|
||||
//! Get whether the register is a segment register.
|
||||
ASMJIT_INLINE bool isSeg() const noexcept { return _vreg.type == kX86RegTypeSeg; }
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// [Statics]
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//! Get whether the `op` operand is Gpb-Lo or Gpb-Hi register.
|
||||
//! Get whether the `op` operand is low or high GPB register.
|
||||
static ASMJIT_INLINE bool isGpbReg(const Operand& op) noexcept {
|
||||
const uint32_t mask = Utils::pack32_2x8_1x16(
|
||||
0xFF, 0xFF, ~(_kX86RegTypePatchedGpbHi << 8) & 0xFF00);
|
||||
@@ -826,7 +826,7 @@ class X86SegReg : public X86Reg {
|
||||
// [asmjit::X86GpReg]
|
||||
// ============================================================================
|
||||
|
||||
//! X86/X64 Gpb/Gpw/Gpd/Gpq register.
|
||||
//! X86/X64 general purpose register (GPB, GPW, GPD, GPQ).
|
||||
class X86GpReg : public X86Reg {
|
||||
public:
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -923,9 +923,9 @@ class X86FpReg : public X86Reg {
|
||||
//!
|
||||
//! MMX Register
|
||||
//! +-----------------------+
|
||||
//! | QWord |
|
||||
//! | QWORD |
|
||||
//! +-----------+-----------+
|
||||
//! | HI-DWord | LO-DWord |
|
||||
//! | HI-DWORD | LO-DWORD |
|
||||
//! +-----------+-----------+
|
||||
//! | W3 | W2 | W1 | W0 |
|
||||
//! +--+--+--+--+--+--+--+--+
|
||||
@@ -935,8 +935,8 @@ class X86FpReg : public X86Reg {
|
||||
//!
|
||||
//! Move instruction semantics:
|
||||
//!
|
||||
//! - `movd` - writes 4-bytes in `LO-DWord` and zeroes `HI-DWord`.
|
||||
//! - `movq` - writes 8-bytes in `QWord`.
|
||||
//! - `movd` - writes 4-bytes in low DWORD and clears high DWORD.
|
||||
//! - `movq` - writes 8-bytes in `QWORD`.
|
||||
class X86MmReg : public X86Reg {
|
||||
public:
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -994,7 +994,7 @@ class X86KReg : public X86Reg {
|
||||
// [asmjit::X86XmmReg]
|
||||
// ============================================================================
|
||||
|
||||
//! X86/X64 128-bit Xmm register (SSE+).
|
||||
//! X86/X64 128-bit XMM register (SSE+).
|
||||
//!
|
||||
//! Structure of XMM register and it's memory mapping:
|
||||
//!
|
||||
@@ -1006,9 +1006,9 @@ class X86KReg : public X86Reg {
|
||||
//!
|
||||
//! XMM Register
|
||||
//! +-----------------------------------------------+
|
||||
//! | OWord |
|
||||
//! | DQWORD |
|
||||
//! +-----------------------+-----------------------+
|
||||
//! | HI-QWord/PD | LO-QWord/SD |
|
||||
//! | HI-QWORD/PD | LO-QWORD/SD |
|
||||
//! +-----------+-----------+-----------+-----------+
|
||||
//! | D3/PS | D2/PS | D1/PS | D0/SS |
|
||||
//! +-----------+-----------+-----------+-----------+
|
||||
@@ -1020,13 +1020,13 @@ class X86KReg : public X86Reg {
|
||||
//!
|
||||
//! Move instruction semantics:
|
||||
//!
|
||||
//! - `movd` - writes 4-bytes in `D0` and zeroes the rest.
|
||||
//! - `movq` - writes 8-bytes in `Lo-QWord` and zeroes the rest.
|
||||
//! - `movq2dq` - writes 8 bytes in `Lo-QWord` and zeroes the rest.
|
||||
//! - `movd` - writes 4-bytes in `D0` and clears the rest.
|
||||
//! - `movq` - writes 8-bytes in low QWORD and clears the rest.
|
||||
//! - `movq2dq` - writes 8 bytes in low QWORD and clears the rest.
|
||||
//!
|
||||
//! - `movss` - writes 4-bytes in `D0`
|
||||
//! (the rest is zeroed only if the source operand is a memory location).
|
||||
//! - `movsd` - writes 8-bytes in `Lo-QWord`
|
||||
//! - `movsd` - writes 8-bytes in low QWORD
|
||||
//! (the rest is zeroed only if the source operand is a memory location).
|
||||
//!
|
||||
//! - `movaps`,
|
||||
@@ -1035,34 +1035,34 @@ class X86KReg : public X86Reg {
|
||||
//! `movupd`,
|
||||
//! `movdqu`,
|
||||
//! `movdqa`,
|
||||
//! `lddqu` - writes 16-bytes in `OWord`.
|
||||
//! `lddqu` - writes 16-bytes in DQWORD.
|
||||
//!
|
||||
//! - `movlps`,
|
||||
//! `movlpd`,
|
||||
//! `movhlps` - writes 8-bytes in `Lo-QWord` and keeps the rest untouched.
|
||||
//! `movhlps` - writes 8-bytes in low QWORD and keeps the rest untouched.
|
||||
//!
|
||||
//! - `movhps`,
|
||||
//! `movhpd`,
|
||||
//! `movlhps` - writes 8-bytes in `Hi-QWord` and keeps the rest untouched.
|
||||
//! `movlhps` - writes 8-bytes in high QWORD and keeps the rest untouched.
|
||||
//!
|
||||
//! - `movddup`,
|
||||
//! - `movsldup`,
|
||||
//! - `movshdup` - writes 16 bytes in `OWord`.
|
||||
//! - `movshdup` - writes 16 bytes in DQWORD.
|
||||
class X86XmmReg : public X86Reg {
|
||||
public:
|
||||
// --------------------------------------------------------------------------
|
||||
// [Construction / Destruction]
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//! Create a dummy Xmm register.
|
||||
//! Create a dummy XMM register.
|
||||
ASMJIT_INLINE X86XmmReg() noexcept : X86Reg() {}
|
||||
//! Create a reference to `other` Xmm register.
|
||||
//! Create a reference to `other` XMM register.
|
||||
ASMJIT_INLINE X86XmmReg(const X86XmmReg& other) noexcept : X86Reg(other) {}
|
||||
//! Create a reference to `other` Xmm register and change the index to `index`.
|
||||
//! Create a reference to `other` XMM register and change the index to `index`.
|
||||
ASMJIT_INLINE X86XmmReg(const X86XmmReg& other, uint32_t index) noexcept : X86Reg(other, index) {}
|
||||
//! Create a custom Xmm register.
|
||||
//! Create a custom XMM register.
|
||||
ASMJIT_INLINE X86XmmReg(uint32_t type, uint32_t index, uint32_t size) noexcept : X86Reg(type, index, size) {}
|
||||
//! Create non-initialized Xmm register.
|
||||
//! Create non-initialized XMM register.
|
||||
explicit ASMJIT_INLINE X86XmmReg(const _NoInit&) noexcept : X86Reg(NoInit) {}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -1075,11 +1075,11 @@ class X86XmmReg : public X86Reg {
|
||||
// [X86XmmReg Cast]
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//! Cast this register to Xmm (clone).
|
||||
//! Cast this register to XMM (clone).
|
||||
ASMJIT_INLINE X86XmmReg xmm() const noexcept { return X86XmmReg(kX86RegTypeXmm, getRegIndex(), 16); }
|
||||
//! Cast this register to Ymm.
|
||||
//! Cast this register to YMM.
|
||||
ASMJIT_INLINE X86YmmReg ymm() const noexcept;
|
||||
//! Cast this register to Zmm.
|
||||
//! Cast this register to ZMM.
|
||||
ASMJIT_INLINE X86ZmmReg zmm() const noexcept;
|
||||
};
|
||||
|
||||
@@ -1087,7 +1087,7 @@ class X86XmmReg : public X86Reg {
|
||||
// [asmjit::X86YmmReg]
|
||||
// ============================================================================
|
||||
|
||||
//! X86/X64 256-bit Ymm register (AVX+).
|
||||
//! X86/X64 256-bit YMM register (AVX+).
|
||||
//!
|
||||
//! Structure of YMM register and it's memory mapping:
|
||||
//!
|
||||
@@ -1099,7 +1099,7 @@ class X86XmmReg : public X86Reg {
|
||||
//!
|
||||
//! YMM Register
|
||||
//! +-----------------------------------------------+-----------------------------------------------+
|
||||
//! | HI-DQWord | LO-DQWord |
|
||||
//! | HI-DQWORD | LO-DQWORD |
|
||||
//! +-----------------------+-----------------------+-----------------------+-----------------------+
|
||||
//! | Q3/PD | Q2/PD | Q1/PD | Q0/SD |
|
||||
//! +-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
|
||||
@@ -1116,15 +1116,15 @@ class X86YmmReg : public X86Reg {
|
||||
// [Construction / Destruction]
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//! Create a dummy Ymm register.
|
||||
//! Create a dummy YMM register.
|
||||
ASMJIT_INLINE X86YmmReg() noexcept : X86Reg() {}
|
||||
//! Create a reference to `other` Ymm register.
|
||||
//! Create a reference to `other` YMM register.
|
||||
ASMJIT_INLINE X86YmmReg(const X86YmmReg& other) noexcept : X86Reg(other) {}
|
||||
//! Create a reference to `other` Ymm register and change the index to `index`.
|
||||
//! Create a reference to `other` YMM register and change the index to `index`.
|
||||
ASMJIT_INLINE X86YmmReg(const X86YmmReg& other, uint32_t index) noexcept : X86Reg(other, index) {}
|
||||
//! Create a custom Ymm register.
|
||||
//! Create a custom YMM register.
|
||||
ASMJIT_INLINE X86YmmReg(uint32_t type, uint32_t index, uint32_t size) noexcept : X86Reg(type, index, size) {}
|
||||
//! Create non-initialized Ymm register.
|
||||
//! Create non-initialized YMM register.
|
||||
explicit ASMJIT_INLINE X86YmmReg(const _NoInit&) noexcept : X86Reg(NoInit) {}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -1137,11 +1137,11 @@ class X86YmmReg : public X86Reg {
|
||||
// [X86YmmReg Cast]
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//! Cast this register to Xmm.
|
||||
//! Cast this register to XMM.
|
||||
ASMJIT_INLINE X86XmmReg xmm() const noexcept{ return X86XmmReg(kX86RegTypeXmm, getRegIndex(), 16); }
|
||||
//! Cast this register to Ymm (clone).
|
||||
//! Cast this register to YMM (clone).
|
||||
ASMJIT_INLINE X86YmmReg ymm() const noexcept { return X86YmmReg(kX86RegTypeYmm, getRegIndex(), 32); }
|
||||
//! Cast this register to Zmm.
|
||||
//! Cast this register to ZMM.
|
||||
ASMJIT_INLINE X86ZmmReg zmm() const noexcept;
|
||||
};
|
||||
|
||||
@@ -1151,22 +1151,22 @@ ASMJIT_INLINE X86YmmReg X86XmmReg::ymm() const noexcept { return X86YmmReg(kX86R
|
||||
// [asmjit::X86ZmmReg]
|
||||
// ============================================================================
|
||||
|
||||
//! X86/X64 512-bit Zmm register (AVX512+).
|
||||
//! X86/X64 512-bit ZMM register (AVX512+).
|
||||
class X86ZmmReg : public X86Reg {
|
||||
public:
|
||||
// --------------------------------------------------------------------------
|
||||
// [Construction / Destruction]
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//! Create a dummy Zmm register.
|
||||
//! Create a dummy ZMM register.
|
||||
ASMJIT_INLINE X86ZmmReg() noexcept : X86Reg() {}
|
||||
//! Create a reference to `other` Zmm register.
|
||||
//! Create a reference to `other` ZMM register.
|
||||
ASMJIT_INLINE X86ZmmReg(const X86ZmmReg& other) noexcept : X86Reg(other) {}
|
||||
//! Create a reference to `other` Zmm register and change the index to `index`.
|
||||
//! Create a reference to `other` ZMM register and change the index to `index`.
|
||||
ASMJIT_INLINE X86ZmmReg(const X86ZmmReg& other, uint32_t index) noexcept : X86Reg(other, index) {}
|
||||
//! Create a custom Zmm register.
|
||||
//! Create a custom ZMM register.
|
||||
ASMJIT_INLINE X86ZmmReg(uint32_t type, uint32_t index, uint32_t size) noexcept : X86Reg(type, index, size) {}
|
||||
//! Create non-initialized Zmm register.
|
||||
//! Create non-initialized ZMM register.
|
||||
explicit ASMJIT_INLINE X86ZmmReg(const _NoInit&) noexcept : X86Reg(NoInit) {}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -1179,11 +1179,11 @@ class X86ZmmReg : public X86Reg {
|
||||
// [X86ZmmReg Cast]
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//! Cast this register to Xmm.
|
||||
//! Cast this register to XMM.
|
||||
ASMJIT_INLINE X86XmmReg xmm() const noexcept { return X86XmmReg(kX86RegTypeXmm, getRegIndex(), 16); }
|
||||
//! Cast this register to Ymm.
|
||||
//! Cast this register to YMM.
|
||||
ASMJIT_INLINE X86YmmReg ymm() const noexcept { return X86YmmReg(kX86RegTypeYmm, getRegIndex(), 32); }
|
||||
//! Cast this register to Zmm (clone).
|
||||
//! Cast this register to ZMM (clone).
|
||||
ASMJIT_INLINE X86ZmmReg zmm() const noexcept { return X86ZmmReg(kX86RegTypeZmm, getRegIndex(), 64); }
|
||||
};
|
||||
|
||||
@@ -1689,31 +1689,31 @@ class X86Var : public Var {
|
||||
//! Get variable type.
|
||||
ASMJIT_INLINE uint32_t getVarType() const noexcept { return _vreg.vType; }
|
||||
|
||||
//! Get whether the variable is Gp register.
|
||||
//! Get whether the variable is a general purpose register.
|
||||
ASMJIT_INLINE bool isGp() const noexcept { return _vreg.type <= kX86RegTypeGpq; }
|
||||
//! Get whether the variable is Gpb (8-bit) register.
|
||||
//! Get whether the variable is a GPB (8-bit) register.
|
||||
ASMJIT_INLINE bool isGpb() const noexcept { return _vreg.type <= kX86RegTypeGpbHi; }
|
||||
//! Get whether the variable is Gpb-lo (8-bit) register.
|
||||
//! Get whether the variable is a low GPB (8-bit) register.
|
||||
ASMJIT_INLINE bool isGpbLo() const noexcept { return _vreg.type == kX86RegTypeGpbLo; }
|
||||
//! Get whether the variable is Gpb-hi (8-bit) register.
|
||||
//! Get whether the variable is a high GPB (8-bit) register.
|
||||
ASMJIT_INLINE bool isGpbHi() const noexcept { return _vreg.type == kX86RegTypeGpbHi; }
|
||||
//! Get whether the variable is Gpw (16-bit) register.
|
||||
//! Get whether the variable is a GPW (16-bit) register.
|
||||
ASMJIT_INLINE bool isGpw() const noexcept { return _vreg.type == kX86RegTypeGpw; }
|
||||
//! Get whether the variable is Gpd (32-bit) register.
|
||||
//! Get whether the variable is a GPD (32-bit) register.
|
||||
ASMJIT_INLINE bool isGpd() const noexcept { return _vreg.type == kX86RegTypeGpd; }
|
||||
//! Get whether the variable is Gpq (64-bit) register.
|
||||
//! Get whether the variable is a GPQ (64-bit) register.
|
||||
ASMJIT_INLINE bool isGpq() const noexcept { return _vreg.type == kX86RegTypeGpq; }
|
||||
|
||||
//! Get whether the variable is Mm (64-bit) register.
|
||||
//! Get whether the variable is MMX (64-bit) register.
|
||||
ASMJIT_INLINE bool isMm() const noexcept { return _vreg.type == kX86RegTypeMm; }
|
||||
//! Get whether the variable is K (64-bit) register.
|
||||
ASMJIT_INLINE bool isK() const noexcept { return _vreg.type == kX86RegTypeK; }
|
||||
|
||||
//! Get whether the variable is Xmm (128-bit) register.
|
||||
//! Get whether the variable is XMM (128-bit) register.
|
||||
ASMJIT_INLINE bool isXmm() const noexcept { return _vreg.type == kX86RegTypeXmm; }
|
||||
//! Get whether the variable is Ymm (256-bit) register.
|
||||
//! Get whether the variable is YMM (256-bit) register.
|
||||
ASMJIT_INLINE bool isYmm() const noexcept { return _vreg.type == kX86RegTypeYmm; }
|
||||
//! Get whether the variable is Zmm (512-bit) register.
|
||||
//! Get whether the variable is ZMM (512-bit) register.
|
||||
ASMJIT_INLINE bool isZmm() const noexcept { return _vreg.type == kX86RegTypeZmm; }
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -1722,7 +1722,7 @@ class X86Var : public Var {
|
||||
|
||||
//! Cast this variable to a memory operand.
|
||||
//!
|
||||
//! \note Size of operand depends on native variable type, you can use other
|
||||
//! NOTE: Size of operand depends on native variable type, you can use other
|
||||
//! variants if you want specific one.
|
||||
ASMJIT_INLINE X86Mem m(int32_t disp = 0) const noexcept {
|
||||
return X86Mem(Init, kMemTypeStackIndex, *this, disp, getSize());
|
||||
@@ -1958,7 +1958,7 @@ class X86MmVar : public X86Var {
|
||||
// ============================================================================
|
||||
|
||||
#if !defined(ASMJIT_DISABLE_COMPILER)
|
||||
//! Xmm variable.
|
||||
//! XMM variable.
|
||||
class X86XmmVar : public X86Var {
|
||||
public:
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -2013,7 +2013,7 @@ public:
|
||||
// ============================================================================
|
||||
|
||||
#if !defined(ASMJIT_DISABLE_COMPILER)
|
||||
//! Ymm variable.
|
||||
//! YMM variable.
|
||||
class X86YmmVar : public X86Var {
|
||||
public:
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -2070,7 +2070,7 @@ ASMJIT_INLINE X86YmmVar X86XmmVar::ymm() const noexcept { return X86YmmVar(*this
|
||||
// ============================================================================
|
||||
|
||||
#if !defined(ASMJIT_DISABLE_COMPILER)
|
||||
//! Zmm variable.
|
||||
//! ZMM variable.
|
||||
class X86ZmmVar : public X86Var {
|
||||
public:
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -2167,177 +2167,177 @@ namespace x86 {
|
||||
#define ASMJIT_DEF_REG(_Type_, _Name_, _Field_) \
|
||||
static const _Type_& _Name_ = x86RegData._Field_;
|
||||
|
||||
ASMJIT_DEF_REG(X86GpReg , eax , gpd[0]) //!< 32-bit Gpd register.
|
||||
ASMJIT_DEF_REG(X86GpReg , ecx , gpd[1]) //!< 32-bit Gpd register.
|
||||
ASMJIT_DEF_REG(X86GpReg , edx , gpd[2]) //!< 32-bit Gpd register.
|
||||
ASMJIT_DEF_REG(X86GpReg , ebx , gpd[3]) //!< 32-bit Gpd register.
|
||||
ASMJIT_DEF_REG(X86GpReg , esp , gpd[4]) //!< 32-bit Gpd register.
|
||||
ASMJIT_DEF_REG(X86GpReg , ebp , gpd[5]) //!< 32-bit Gpd register.
|
||||
ASMJIT_DEF_REG(X86GpReg , esi , gpd[6]) //!< 32-bit Gpd register.
|
||||
ASMJIT_DEF_REG(X86GpReg , edi , gpd[7]) //!< 32-bit Gpd register.
|
||||
ASMJIT_DEF_REG(X86GpReg , r8d , gpd[8]) //!< 32-bit Gpd register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r9d , gpd[9]) //!< 32-bit Gpd register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r10d , gpd[10]) //!< 32-bit Gpd register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r11d , gpd[11]) //!< 32-bit Gpd register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r12d , gpd[12]) //!< 32-bit Gpd register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r13d , gpd[13]) //!< 32-bit Gpd register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r14d , gpd[14]) //!< 32-bit Gpd register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r15d , gpd[15]) //!< 32-bit Gpd register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , eax , gpd[0]) //!< 32-bit GPD register.
|
||||
ASMJIT_DEF_REG(X86GpReg , ecx , gpd[1]) //!< 32-bit GPD register.
|
||||
ASMJIT_DEF_REG(X86GpReg , edx , gpd[2]) //!< 32-bit GPD register.
|
||||
ASMJIT_DEF_REG(X86GpReg , ebx , gpd[3]) //!< 32-bit GPD register.
|
||||
ASMJIT_DEF_REG(X86GpReg , esp , gpd[4]) //!< 32-bit GPD register.
|
||||
ASMJIT_DEF_REG(X86GpReg , ebp , gpd[5]) //!< 32-bit GPD register.
|
||||
ASMJIT_DEF_REG(X86GpReg , esi , gpd[6]) //!< 32-bit GPD register.
|
||||
ASMJIT_DEF_REG(X86GpReg , edi , gpd[7]) //!< 32-bit GPD register.
|
||||
ASMJIT_DEF_REG(X86GpReg , r8d , gpd[8]) //!< 32-bit GPD register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r9d , gpd[9]) //!< 32-bit GPD register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r10d , gpd[10]) //!< 32-bit GPD register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r11d , gpd[11]) //!< 32-bit GPD register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r12d , gpd[12]) //!< 32-bit GPD register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r13d , gpd[13]) //!< 32-bit GPD register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r14d , gpd[14]) //!< 32-bit GPD register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r15d , gpd[15]) //!< 32-bit GPD register (X64).
|
||||
|
||||
ASMJIT_DEF_REG(X86GpReg , rax , gpq[0]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rcx , gpq[1]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rdx , gpq[2]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rbx , gpq[3]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rsp , gpq[4]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rbp , gpq[5]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rsi , gpq[6]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rdi , gpq[7]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r8 , gpq[8]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r9 , gpq[9]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r10 , gpq[10]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r11 , gpq[11]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r12 , gpq[12]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r13 , gpq[13]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r14 , gpq[14]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r15 , gpq[15]) //!< 64-bit Gpq register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rax , gpq[0]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rcx , gpq[1]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rdx , gpq[2]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rbx , gpq[3]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rsp , gpq[4]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rbp , gpq[5]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rsi , gpq[6]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , rdi , gpq[7]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r8 , gpq[8]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r9 , gpq[9]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r10 , gpq[10]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r11 , gpq[11]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r12 , gpq[12]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r13 , gpq[13]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r14 , gpq[14]) //!< 64-bit GPQ register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r15 , gpq[15]) //!< 64-bit GPQ register (X64).
|
||||
|
||||
ASMJIT_DEF_REG(X86GpReg , al , gpbLo[0]) //!< 8-bit Gpb-lo register.
|
||||
ASMJIT_DEF_REG(X86GpReg , cl , gpbLo[1]) //!< 8-bit Gpb-lo register.
|
||||
ASMJIT_DEF_REG(X86GpReg , dl , gpbLo[2]) //!< 8-bit Gpb-lo register.
|
||||
ASMJIT_DEF_REG(X86GpReg , bl , gpbLo[3]) //!< 8-bit Gpb-lo register.
|
||||
ASMJIT_DEF_REG(X86GpReg , spl , gpbLo[4]) //!< 8-bit Gpb-lo register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , bpl , gpbLo[5]) //!< 8-bit Gpb-lo register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , sil , gpbLo[6]) //!< 8-bit Gpb-lo register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , dil , gpbLo[7]) //!< 8-bit Gpb-lo register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r8b , gpbLo[8]) //!< 8-bit Gpb-lo register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r9b , gpbLo[9]) //!< 8-bit Gpb-lo register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r10b , gpbLo[10])//!< 8-bit Gpb-lo register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r11b , gpbLo[11])//!< 8-bit Gpb-lo register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r12b , gpbLo[12])//!< 8-bit Gpb-lo register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r13b , gpbLo[13])//!< 8-bit Gpb-lo register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r14b , gpbLo[14])//!< 8-bit Gpb-lo register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r15b , gpbLo[15])//!< 8-bit Gpb-lo register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , al , gpbLo[0]) //!< 8-bit low GPB register.
|
||||
ASMJIT_DEF_REG(X86GpReg , cl , gpbLo[1]) //!< 8-bit low GPB register.
|
||||
ASMJIT_DEF_REG(X86GpReg , dl , gpbLo[2]) //!< 8-bit low GPB register.
|
||||
ASMJIT_DEF_REG(X86GpReg , bl , gpbLo[3]) //!< 8-bit low GPB register.
|
||||
ASMJIT_DEF_REG(X86GpReg , spl , gpbLo[4]) //!< 8-bit low GPB register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , bpl , gpbLo[5]) //!< 8-bit low GPB register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , sil , gpbLo[6]) //!< 8-bit low GPB register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , dil , gpbLo[7]) //!< 8-bit low GPB register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r8b , gpbLo[8]) //!< 8-bit low GPB register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r9b , gpbLo[9]) //!< 8-bit low GPB register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r10b , gpbLo[10])//!< 8-bit low GPB register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r11b , gpbLo[11])//!< 8-bit low GPB register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r12b , gpbLo[12])//!< 8-bit low GPB register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r13b , gpbLo[13])//!< 8-bit low GPB register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r14b , gpbLo[14])//!< 8-bit low GPB register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r15b , gpbLo[15])//!< 8-bit low GPB register (X64).
|
||||
|
||||
ASMJIT_DEF_REG(X86GpReg , ah , gpbHi[0]) //!< 8-bit Gpb-hi register.
|
||||
ASMJIT_DEF_REG(X86GpReg , ch , gpbHi[1]) //!< 8-bit Gpb-hi register.
|
||||
ASMJIT_DEF_REG(X86GpReg , dh , gpbHi[2]) //!< 8-bit Gpb-hi register.
|
||||
ASMJIT_DEF_REG(X86GpReg , bh , gpbHi[3]) //!< 8-bit Gpb-hi register.
|
||||
ASMJIT_DEF_REG(X86GpReg , ah , gpbHi[0]) //!< 8-bit high GPB register.
|
||||
ASMJIT_DEF_REG(X86GpReg , ch , gpbHi[1]) //!< 8-bit high GPB register.
|
||||
ASMJIT_DEF_REG(X86GpReg , dh , gpbHi[2]) //!< 8-bit high GPB register.
|
||||
ASMJIT_DEF_REG(X86GpReg , bh , gpbHi[3]) //!< 8-bit high GPB register.
|
||||
|
||||
ASMJIT_DEF_REG(X86GpReg , ax , gpw[0]) //!< 16-bit Gpw register.
|
||||
ASMJIT_DEF_REG(X86GpReg , cx , gpw[1]) //!< 16-bit Gpw register.
|
||||
ASMJIT_DEF_REG(X86GpReg , dx , gpw[2]) //!< 16-bit Gpw register.
|
||||
ASMJIT_DEF_REG(X86GpReg , bx , gpw[3]) //!< 16-bit Gpw register.
|
||||
ASMJIT_DEF_REG(X86GpReg , sp , gpw[4]) //!< 16-bit Gpw register.
|
||||
ASMJIT_DEF_REG(X86GpReg , bp , gpw[5]) //!< 16-bit Gpw register.
|
||||
ASMJIT_DEF_REG(X86GpReg , si , gpw[6]) //!< 16-bit Gpw register.
|
||||
ASMJIT_DEF_REG(X86GpReg , di , gpw[7]) //!< 16-bit Gpw register.
|
||||
ASMJIT_DEF_REG(X86GpReg , r8w , gpw[8]) //!< 16-bit Gpw register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r9w , gpw[9]) //!< 16-bit Gpw register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r10w , gpw[10]) //!< 16-bit Gpw register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r11w , gpw[11]) //!< 16-bit Gpw register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r12w , gpw[12]) //!< 16-bit Gpw register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r13w , gpw[13]) //!< 16-bit Gpw register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r14w , gpw[14]) //!< 16-bit Gpw register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r15w , gpw[15]) //!< 16-bit Gpw register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , ax , gpw[0]) //!< 16-bit GPW register.
|
||||
ASMJIT_DEF_REG(X86GpReg , cx , gpw[1]) //!< 16-bit GPW register.
|
||||
ASMJIT_DEF_REG(X86GpReg , dx , gpw[2]) //!< 16-bit GPW register.
|
||||
ASMJIT_DEF_REG(X86GpReg , bx , gpw[3]) //!< 16-bit GPW register.
|
||||
ASMJIT_DEF_REG(X86GpReg , sp , gpw[4]) //!< 16-bit GPW register.
|
||||
ASMJIT_DEF_REG(X86GpReg , bp , gpw[5]) //!< 16-bit GPW register.
|
||||
ASMJIT_DEF_REG(X86GpReg , si , gpw[6]) //!< 16-bit GPW register.
|
||||
ASMJIT_DEF_REG(X86GpReg , di , gpw[7]) //!< 16-bit GPW register.
|
||||
ASMJIT_DEF_REG(X86GpReg , r8w , gpw[8]) //!< 16-bit GPW register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r9w , gpw[9]) //!< 16-bit GPW register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r10w , gpw[10]) //!< 16-bit GPW register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r11w , gpw[11]) //!< 16-bit GPW register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r12w , gpw[12]) //!< 16-bit GPW register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r13w , gpw[13]) //!< 16-bit GPW register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r14w , gpw[14]) //!< 16-bit GPW register (X64).
|
||||
ASMJIT_DEF_REG(X86GpReg , r15w , gpw[15]) //!< 16-bit GPW register (X64).
|
||||
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm0 , xmm[0]) //!< 128-bit Xmm register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm1 , xmm[1]) //!< 128-bit Xmm register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm2 , xmm[2]) //!< 128-bit Xmm register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm3 , xmm[3]) //!< 128-bit Xmm register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm4 , xmm[4]) //!< 128-bit Xmm register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm5 , xmm[5]) //!< 128-bit Xmm register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm6 , xmm[6]) //!< 128-bit Xmm register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm7 , xmm[7]) //!< 128-bit Xmm register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm8 , xmm[8]) //!< 128-bit Xmm register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm9 , xmm[9]) //!< 128-bit Xmm register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm10, xmm[10]) //!< 128-bit Xmm register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm11, xmm[11]) //!< 128-bit Xmm register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm12, xmm[12]) //!< 128-bit Xmm register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm13, xmm[13]) //!< 128-bit Xmm register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm14, xmm[14]) //!< 128-bit Xmm register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm15, xmm[15]) //!< 128-bit Xmm register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm16, xmm[16]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm17, xmm[17]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm18, xmm[18]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm19, xmm[19]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm20, xmm[20]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm21, xmm[21]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm22, xmm[22]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm23, xmm[23]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm24, xmm[24]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm25, xmm[25]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm26, xmm[26]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm27, xmm[27]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm28, xmm[28]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm29, xmm[29]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm30, xmm[30]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm31, xmm[31]) //!< 128-bit Xmm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm0 , xmm[0]) //!< 128-bit XMM register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm1 , xmm[1]) //!< 128-bit XMM register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm2 , xmm[2]) //!< 128-bit XMM register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm3 , xmm[3]) //!< 128-bit XMM register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm4 , xmm[4]) //!< 128-bit XMM register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm5 , xmm[5]) //!< 128-bit XMM register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm6 , xmm[6]) //!< 128-bit XMM register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm7 , xmm[7]) //!< 128-bit XMM register.
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm8 , xmm[8]) //!< 128-bit XMM register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm9 , xmm[9]) //!< 128-bit XMM register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm10, xmm[10]) //!< 128-bit XMM register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm11, xmm[11]) //!< 128-bit XMM register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm12, xmm[12]) //!< 128-bit XMM register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm13, xmm[13]) //!< 128-bit XMM register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm14, xmm[14]) //!< 128-bit XMM register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm15, xmm[15]) //!< 128-bit XMM register (X64).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm16, xmm[16]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm17, xmm[17]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm18, xmm[18]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm19, xmm[19]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm20, xmm[20]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm21, xmm[21]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm22, xmm[22]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm23, xmm[23]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm24, xmm[24]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm25, xmm[25]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm26, xmm[26]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm27, xmm[27]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm28, xmm[28]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm29, xmm[29]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm30, xmm[30]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86XmmReg, xmm31, xmm[31]) //!< 128-bit XMM register (X64 & AVX512VL+).
|
||||
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm0 , ymm[0]) //!< 256-bit Ymm register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm1 , ymm[1]) //!< 256-bit Ymm register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm2 , ymm[2]) //!< 256-bit Ymm register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm3 , ymm[3]) //!< 256-bit Ymm register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm4 , ymm[4]) //!< 256-bit Ymm register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm5 , ymm[5]) //!< 256-bit Ymm register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm6 , ymm[6]) //!< 256-bit Ymm register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm7 , ymm[7]) //!< 256-bit Ymm register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm8 , ymm[8]) //!< 256-bit Ymm register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm9 , ymm[9]) //!< 256-bit Ymm register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm10, ymm[10]) //!< 256-bit Ymm register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm11, ymm[11]) //!< 256-bit Ymm register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm12, ymm[12]) //!< 256-bit Ymm register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm13, ymm[13]) //!< 256-bit Ymm register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm14, ymm[14]) //!< 256-bit Ymm register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm15, ymm[15]) //!< 256-bit Ymm register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm16, ymm[16]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm17, ymm[17]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm18, ymm[18]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm19, ymm[19]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm20, ymm[20]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm21, ymm[21]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm22, ymm[22]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm23, ymm[23]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm24, ymm[24]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm25, ymm[25]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm26, ymm[26]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm27, ymm[27]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm28, ymm[28]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm29, ymm[29]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm30, ymm[30]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm31, ymm[31]) //!< 256-bit Ymm register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm0 , ymm[0]) //!< 256-bit YMM register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm1 , ymm[1]) //!< 256-bit YMM register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm2 , ymm[2]) //!< 256-bit YMM register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm3 , ymm[3]) //!< 256-bit YMM register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm4 , ymm[4]) //!< 256-bit YMM register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm5 , ymm[5]) //!< 256-bit YMM register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm6 , ymm[6]) //!< 256-bit YMM register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm7 , ymm[7]) //!< 256-bit YMM register.
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm8 , ymm[8]) //!< 256-bit YMM register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm9 , ymm[9]) //!< 256-bit YMM register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm10, ymm[10]) //!< 256-bit YMM register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm11, ymm[11]) //!< 256-bit YMM register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm12, ymm[12]) //!< 256-bit YMM register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm13, ymm[13]) //!< 256-bit YMM register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm14, ymm[14]) //!< 256-bit YMM register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm15, ymm[15]) //!< 256-bit YMM register (X64).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm16, ymm[16]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm17, ymm[17]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm18, ymm[18]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm19, ymm[19]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm20, ymm[20]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm21, ymm[21]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm22, ymm[22]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm23, ymm[23]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm24, ymm[24]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm25, ymm[25]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm26, ymm[26]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm27, ymm[27]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm28, ymm[28]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm29, ymm[29]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm30, ymm[30]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
ASMJIT_DEF_REG(X86YmmReg, ymm31, ymm[31]) //!< 256-bit YMM register (X64 & AVX512VL+).
|
||||
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm0 , zmm[0]) //!< 512-bit Zmm register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm1 , zmm[1]) //!< 512-bit Zmm register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm2 , zmm[2]) //!< 512-bit Zmm register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm3 , zmm[3]) //!< 512-bit Zmm register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm4 , zmm[4]) //!< 512-bit Zmm register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm5 , zmm[5]) //!< 512-bit Zmm register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm6 , zmm[6]) //!< 512-bit Zmm register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm7 , zmm[7]) //!< 512-bit Zmm register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm8 , zmm[8]) //!< 512-bit Zmm register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm9 , zmm[9]) //!< 512-bit Zmm register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm10, zmm[10]) //!< 512-bit Zmm register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm11, zmm[11]) //!< 512-bit Zmm register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm12, zmm[12]) //!< 512-bit Zmm register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm13, zmm[13]) //!< 512-bit Zmm register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm14, zmm[14]) //!< 512-bit Zmm register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm15, zmm[15]) //!< 512-bit Zmm register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm16, zmm[16]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm17, zmm[17]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm18, zmm[18]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm19, zmm[19]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm20, zmm[20]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm21, zmm[21]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm22, zmm[22]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm23, zmm[23]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm24, zmm[24]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm25, zmm[25]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm26, zmm[26]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm27, zmm[27]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm28, zmm[28]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm29, zmm[29]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm30, zmm[30]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm31, zmm[31]) //!< 512-bit Zmm register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm0 , zmm[0]) //!< 512-bit ZMM register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm1 , zmm[1]) //!< 512-bit ZMM register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm2 , zmm[2]) //!< 512-bit ZMM register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm3 , zmm[3]) //!< 512-bit ZMM register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm4 , zmm[4]) //!< 512-bit ZMM register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm5 , zmm[5]) //!< 512-bit ZMM register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm6 , zmm[6]) //!< 512-bit ZMM register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm7 , zmm[7]) //!< 512-bit ZMM register.
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm8 , zmm[8]) //!< 512-bit ZMM register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm9 , zmm[9]) //!< 512-bit ZMM register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm10, zmm[10]) //!< 512-bit ZMM register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm11, zmm[11]) //!< 512-bit ZMM register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm12, zmm[12]) //!< 512-bit ZMM register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm13, zmm[13]) //!< 512-bit ZMM register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm14, zmm[14]) //!< 512-bit ZMM register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm15, zmm[15]) //!< 512-bit ZMM register (X64).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm16, zmm[16]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm17, zmm[17]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm18, zmm[18]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm19, zmm[19]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm20, zmm[20]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm21, zmm[21]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm22, zmm[22]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm23, zmm[23]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm24, zmm[24]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm25, zmm[25]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm26, zmm[26]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm27, zmm[27]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm28, zmm[28]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm29, zmm[29]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm30, zmm[30]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
ASMJIT_DEF_REG(X86ZmmReg, zmm31, zmm[31]) //!< 512-bit ZMM register (X64 & AVX512+).
|
||||
|
||||
ASMJIT_DEF_REG(X86KReg , k0 , k[0]) //!< 64-bit K register.
|
||||
ASMJIT_DEF_REG(X86KReg , k1 , k[1]) //!< 64-bit K register.
|
||||
@@ -2348,23 +2348,23 @@ ASMJIT_DEF_REG(X86KReg , k5 , k[5]) //!< 64-bit K register.
|
||||
ASMJIT_DEF_REG(X86KReg , k6 , k[6]) //!< 64-bit K register.
|
||||
ASMJIT_DEF_REG(X86KReg , k7 , k[7]) //!< 64-bit K register.
|
||||
|
||||
ASMJIT_DEF_REG(X86FpReg , fp0 , fp[0]) //!< 80-bit Fp register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp1 , fp[1]) //!< 80-bit Fp register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp2 , fp[2]) //!< 80-bit Fp register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp3 , fp[3]) //!< 80-bit Fp register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp4 , fp[4]) //!< 80-bit Fp register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp5 , fp[5]) //!< 80-bit Fp register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp6 , fp[6]) //!< 80-bit Fp register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp7 , fp[7]) //!< 80-bit Fp register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp0 , fp[0]) //!< 80-bit FPU register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp1 , fp[1]) //!< 80-bit FPU register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp2 , fp[2]) //!< 80-bit FPU register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp3 , fp[3]) //!< 80-bit FPU register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp4 , fp[4]) //!< 80-bit FPU register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp5 , fp[5]) //!< 80-bit FPU register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp6 , fp[6]) //!< 80-bit FPU register.
|
||||
ASMJIT_DEF_REG(X86FpReg , fp7 , fp[7]) //!< 80-bit FPU register.
|
||||
|
||||
ASMJIT_DEF_REG(X86MmReg , mm0 , mm[0]) //!< 64-bit Mm register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm1 , mm[1]) //!< 64-bit Mm register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm2 , mm[2]) //!< 64-bit Mm register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm3 , mm[3]) //!< 64-bit Mm register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm4 , mm[4]) //!< 64-bit Mm register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm5 , mm[5]) //!< 64-bit Mm register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm6 , mm[6]) //!< 64-bit Mm register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm7 , mm[7]) //!< 64-bit Mm register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm0 , mm[0]) //!< 64-bit MMX register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm1 , mm[1]) //!< 64-bit MMX register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm2 , mm[2]) //!< 64-bit MMX register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm3 , mm[3]) //!< 64-bit MMX register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm4 , mm[4]) //!< 64-bit MMX register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm5 , mm[5]) //!< 64-bit MMX register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm6 , mm[6]) //!< 64-bit MMX register.
|
||||
ASMJIT_DEF_REG(X86MmReg , mm7 , mm[7]) //!< 64-bit MMX register.
|
||||
|
||||
ASMJIT_DEF_REG(X86SegReg, es , seg[1]) //!< Cs segment register.
|
||||
ASMJIT_DEF_REG(X86SegReg, cs , seg[2]) //!< Ss segment register.
|
||||
@@ -2378,15 +2378,15 @@ ASMJIT_DEF_REG(X86RipReg, rip, rip) //!< RIP register.
|
||||
|
||||
#undef ASMJIT_DEF_REG
|
||||
|
||||
//! Create 8-bit Gpb-lo register operand.
|
||||
//! Create 8-bit low GPB register operand.
|
||||
static ASMJIT_INLINE X86GpReg gpb_lo(uint32_t index) noexcept { return X86GpReg(kX86RegTypeGpbLo, index, 1); }
|
||||
//! Create 8-bit Gpb-hi register operand.
|
||||
//! Create 8-bit high GPB register operand.
|
||||
static ASMJIT_INLINE X86GpReg gpb_hi(uint32_t index) noexcept { return X86GpReg(kX86RegTypeGpbHi, index, 1); }
|
||||
//! Create 16-bit Gpw register operand.
|
||||
//! Create 16-bit GPW register operand.
|
||||
static ASMJIT_INLINE X86GpReg gpw(uint32_t index) noexcept { return X86GpReg(kX86RegTypeGpw, index, 2); }
|
||||
//! Create 32-bit Gpd register operand.
|
||||
//! Create 32-bit GPD register operand.
|
||||
static ASMJIT_INLINE X86GpReg gpd(uint32_t index) noexcept { return X86GpReg(kX86RegTypeGpd, index, 4); }
|
||||
//! Create 64-bit Gpq register operand (X64).
|
||||
//! Create 64-bit GPQ register operand (X64).
|
||||
static ASMJIT_INLINE X86GpReg gpq(uint32_t index) noexcept { return X86GpReg(kX86RegTypeGpq, index, 8); }
|
||||
//! Create 80-bit Fp register operand.
|
||||
static ASMJIT_INLINE X86FpReg fp(uint32_t index) noexcept { return X86FpReg(kX86RegTypeFp, index, 10); }
|
||||
@@ -2394,11 +2394,11 @@ static ASMJIT_INLINE X86FpReg fp(uint32_t index) noexcept { return X86FpReg(kX86
|
||||
static ASMJIT_INLINE X86MmReg mm(uint32_t index) noexcept { return X86MmReg(kX86RegTypeMm, index, 8); }
|
||||
//! Create 64-bit K register operand.
|
||||
static ASMJIT_INLINE X86KReg k(uint32_t index) noexcept { return X86KReg(kX86RegTypeK, index, 8); }
|
||||
//! Create 128-bit Xmm register operand.
|
||||
//! Create 128-bit XMM register operand.
|
||||
static ASMJIT_INLINE X86XmmReg xmm(uint32_t index) noexcept { return X86XmmReg(kX86RegTypeXmm, index, 16); }
|
||||
//! Create 256-bit Ymm register operand.
|
||||
//! Create 256-bit YMM register operand.
|
||||
static ASMJIT_INLINE X86YmmReg ymm(uint32_t index) noexcept { return X86YmmReg(kX86RegTypeYmm, index, 32); }
|
||||
//! Create 512-bit Zmm register operand.
|
||||
//! Create 512-bit ZMM register operand.
|
||||
static ASMJIT_INLINE X86ZmmReg zmm(uint32_t index) noexcept { return X86ZmmReg(kX86RegTypeZmm, index, 64); }
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -600,12 +600,182 @@ static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 =
|
||||
a.fucomp(fpB);
|
||||
a.fucompp();
|
||||
a.fxam();
|
||||
a.fxrstor(anyptr_gpA);
|
||||
a.fxsave(anyptr_gpA);
|
||||
a.fxtract();
|
||||
a.fyl2x();
|
||||
a.fyl2xp1();
|
||||
|
||||
// FXSR.
|
||||
a.fxrstor(anyptr_gpA);
|
||||
a.fxsave(anyptr_gpA);
|
||||
|
||||
// XSAVE.
|
||||
a.nop();
|
||||
|
||||
a.xgetbv();
|
||||
a.xsetbv();
|
||||
|
||||
a.xsave(anyptr_gpA);
|
||||
a.xsaveopt(anyptr_gpA);
|
||||
a.xrstor(anyptr_gpA);
|
||||
|
||||
// POPCNT.
|
||||
a.nop();
|
||||
|
||||
a.popcnt(gdA, gdB);
|
||||
a.popcnt(gzA, gzB);
|
||||
a.popcnt(gdA, anyptr_gpB);
|
||||
a.popcnt(gzA, anyptr_gpB);
|
||||
|
||||
// LZCNT.
|
||||
a.nop();
|
||||
|
||||
a.lzcnt(gdA, gdB);
|
||||
a.lzcnt(gzA, gzB);
|
||||
a.lzcnt(gdA, anyptr_gpB);
|
||||
a.lzcnt(gzA, anyptr_gpB);
|
||||
|
||||
// BMI.
|
||||
a.nop();
|
||||
|
||||
a.andn(gdA, gdB, gdC);
|
||||
a.andn(gzA, gzB, gzC);
|
||||
a.andn(gdA, gdB, anyptr_gpC);
|
||||
a.andn(gzA, gzB, anyptr_gpC);
|
||||
a.bextr(gdA, gdB, gdC);
|
||||
a.bextr(gzA, gzB, gzC);
|
||||
a.bextr(gdA, anyptr_gpB, gdC);
|
||||
a.bextr(gzA, anyptr_gpB, gzC);
|
||||
a.blsi(gdA, gdB);
|
||||
a.blsi(gzA, gzB);
|
||||
a.blsi(gdA, anyptr_gpB);
|
||||
a.blsi(gzA, anyptr_gpB);
|
||||
a.blsmsk(gdA, gdB);
|
||||
a.blsmsk(gzA, gzB);
|
||||
a.blsmsk(gdA, anyptr_gpB);
|
||||
a.blsmsk(gzA, anyptr_gpB);
|
||||
a.blsr(gdA, gdB);
|
||||
a.blsr(gzA, gzB);
|
||||
a.blsr(gdA, anyptr_gpB);
|
||||
a.blsr(gzA, anyptr_gpB);
|
||||
a.tzcnt(gdA, gdB);
|
||||
a.tzcnt(gzA, gzB);
|
||||
a.tzcnt(gdA, anyptr_gpB);
|
||||
a.tzcnt(gzA, anyptr_gpB);
|
||||
|
||||
// BMI2.
|
||||
a.nop();
|
||||
|
||||
a.bzhi(gdA, gdB, gdC);
|
||||
a.bzhi(gzA, gzB, gzC);
|
||||
a.bzhi(gdA, anyptr_gpB, gdC);
|
||||
a.bzhi(gzA, anyptr_gpB, gzC);
|
||||
a.mulx(gdA, gdB, gdC);
|
||||
a.mulx(gzA, gzB, gzC);
|
||||
a.mulx(gdA, gdB, anyptr_gpC);
|
||||
a.mulx(gzA, gzB, anyptr_gpC);
|
||||
a.pdep(gdA, gdB, gdC);
|
||||
a.pdep(gzA, gzB, gzC);
|
||||
a.pdep(gdA, gdB, anyptr_gpC);
|
||||
a.pdep(gzA, gzB, anyptr_gpC);
|
||||
a.pext(gdA, gdB, gdC);
|
||||
a.pext(gzA, gzB, gzC);
|
||||
a.pext(gdA, gdB, anyptr_gpC);
|
||||
a.pext(gzA, gzB, anyptr_gpC);
|
||||
a.rorx(gdA, gdB, 0);
|
||||
a.rorx(gzA, gzB, 0);
|
||||
a.rorx(gdA, anyptr_gpB, 0);
|
||||
a.rorx(gzA, anyptr_gpB, 0);
|
||||
a.sarx(gdA, gdB, gdC);
|
||||
a.sarx(gzA, gzB, gzC);
|
||||
a.sarx(gdA, anyptr_gpB, gdC);
|
||||
a.sarx(gzA, anyptr_gpB, gzC);
|
||||
a.shlx(gdA, gdB, gdC);
|
||||
a.shlx(gzA, gzB, gzC);
|
||||
a.shlx(gdA, anyptr_gpB, gdC);
|
||||
a.shlx(gzA, anyptr_gpB, gzC);
|
||||
a.shrx(gdA, gdB, gdC);
|
||||
a.shrx(gzA, gzB, gzC);
|
||||
a.shrx(gdA, anyptr_gpB, gdC);
|
||||
a.shrx(gzA, anyptr_gpB, gzC);
|
||||
|
||||
// ADX.
|
||||
a.nop();
|
||||
|
||||
a.adcx(gdA, gdB);
|
||||
a.adcx(gzA, gzB);
|
||||
a.adcx(gdA, anyptr_gpB);
|
||||
a.adcx(gzA, anyptr_gpB);
|
||||
a.adox(gdA, gdB);
|
||||
a.adox(gzA, gzB);
|
||||
a.adox(gdA, anyptr_gpB);
|
||||
a.adox(gzA, anyptr_gpB);
|
||||
|
||||
// TBM.
|
||||
a.nop();
|
||||
|
||||
a.blcfill(gdA, gdB);
|
||||
a.blcfill(gzA, gzB);
|
||||
a.blcfill(gdA, anyptr_gpB);
|
||||
a.blcfill(gzA, anyptr_gpB);
|
||||
|
||||
a.blci(gdA, gdB);
|
||||
a.blci(gzA, gzB);
|
||||
a.blci(gdA, anyptr_gpB);
|
||||
a.blci(gzA, anyptr_gpB);
|
||||
|
||||
a.blcic(gdA, gdB);
|
||||
a.blcic(gzA, gzB);
|
||||
a.blcic(gdA, anyptr_gpB);
|
||||
a.blcic(gzA, anyptr_gpB);
|
||||
|
||||
a.blcmsk(gdA, gdB);
|
||||
a.blcmsk(gzA, gzB);
|
||||
a.blcmsk(gdA, anyptr_gpB);
|
||||
a.blcmsk(gzA, anyptr_gpB);
|
||||
|
||||
a.blcs(gdA, gdB);
|
||||
a.blcs(gzA, gzB);
|
||||
a.blcs(gdA, anyptr_gpB);
|
||||
a.blcs(gzA, anyptr_gpB);
|
||||
|
||||
a.blsfill(gdA, gdB);
|
||||
a.blsfill(gzA, gzB);
|
||||
a.blsfill(gdA, anyptr_gpB);
|
||||
a.blsfill(gzA, anyptr_gpB);
|
||||
|
||||
a.blsic(gdA, gdB);
|
||||
a.blsic(gzA, gzB);
|
||||
a.blsic(gdA, anyptr_gpB);
|
||||
a.blsic(gzA, anyptr_gpB);
|
||||
|
||||
a.t1mskc(gdA, gdB);
|
||||
a.t1mskc(gzA, gzB);
|
||||
a.t1mskc(gdA, anyptr_gpB);
|
||||
a.t1mskc(gzA, anyptr_gpB);
|
||||
|
||||
a.tzmsk(gdA, gdB);
|
||||
a.tzmsk(gzA, gzB);
|
||||
a.tzmsk(gdA, anyptr_gpB);
|
||||
a.tzmsk(gzA, anyptr_gpB);
|
||||
|
||||
// CLFLUSH / CLFLUSH_OPT.
|
||||
a.nop();
|
||||
a.clflush(anyptr_gpA);
|
||||
a.clflushopt(anyptr_gpA);
|
||||
|
||||
// PREFETCHW / PREFETCHWT1.
|
||||
a.nop();
|
||||
a.prefetchw(anyptr_gpA);
|
||||
a.prefetchwt1(anyptr_gpA);
|
||||
|
||||
// RDRAND / RDSEED.
|
||||
a.nop();
|
||||
|
||||
a.rdrand(gdA);
|
||||
a.rdrand(gzA);
|
||||
a.rdseed(gdA);
|
||||
a.rdseed(gzA);
|
||||
|
||||
// MMX/MMX-EXT.
|
||||
a.nop();
|
||||
|
||||
@@ -713,6 +883,8 @@ static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 =
|
||||
// 3DNOW!
|
||||
a.nop();
|
||||
|
||||
a.pavgusb(mmA, mmB);
|
||||
a.pavgusb(mmA, anyptr_gpB);
|
||||
a.pf2id(mmA, mmB);
|
||||
a.pf2id(mmA, anyptr_gpB);
|
||||
a.pf2iw(mmA, mmB);
|
||||
@@ -755,10 +927,11 @@ static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 =
|
||||
a.pi2fd(mmA, anyptr_gpB);
|
||||
a.pi2fw(mmA, mmB);
|
||||
a.pi2fw(mmA, anyptr_gpB);
|
||||
a.pmulhrw(mmA, mmB);
|
||||
a.pmulhrw(mmA, anyptr_gpB);
|
||||
a.pswapd(mmA, mmB);
|
||||
a.pswapd(mmA, anyptr_gpB);
|
||||
a.prefetch3dnow(anyptr_gpA);
|
||||
a.prefetchw3dnow(anyptr_gpA);
|
||||
a.femms();
|
||||
|
||||
// SSE.
|
||||
@@ -899,7 +1072,6 @@ static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 =
|
||||
a.andnpd(xmmA, anyptr_gpB);
|
||||
a.andpd(xmmA, xmmB);
|
||||
a.andpd(xmmA, anyptr_gpB);
|
||||
a.clflush(anyptr_gpA);
|
||||
a.cmppd(xmmA, xmmB, 0);
|
||||
a.cmppd(xmmA, anyptr_gpB, 0);
|
||||
a.cmpsd(xmmA, xmmB, 0);
|
||||
@@ -1358,12 +1530,6 @@ static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 =
|
||||
a.movntsd(anyptr_gpA, xmmB);
|
||||
a.movntss(anyptr_gpA, xmmB);
|
||||
|
||||
// POPCNT.
|
||||
a.nop();
|
||||
|
||||
a.popcnt(gzA, gzB);
|
||||
a.popcnt(gzA, anyptr_gpB);
|
||||
|
||||
// AESNI.
|
||||
a.nop();
|
||||
|
||||
@@ -1380,22 +1546,30 @@ static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 =
|
||||
a.aeskeygenassist(xmmA, xmmB, 0);
|
||||
a.aeskeygenassist(xmmA, anyptr_gpB, 0);
|
||||
|
||||
// SHA.
|
||||
a.nop();
|
||||
|
||||
a.sha1msg1(xmmA, xmmB);
|
||||
a.sha1msg1(xmmA, anyptr_gpB);
|
||||
a.sha1msg2(xmmA, xmmB);
|
||||
a.sha1msg2(xmmA, anyptr_gpB);
|
||||
a.sha1nexte(xmmA, xmmB);
|
||||
a.sha1nexte(xmmA, anyptr_gpB);
|
||||
a.sha1rnds4(xmmA, xmmB, 0);
|
||||
a.sha1rnds4(xmmA, anyptr_gpB, 0);
|
||||
a.sha256msg1(xmmA, xmmB);
|
||||
a.sha256msg1(xmmA, anyptr_gpB);
|
||||
a.sha256msg2(xmmA, xmmB);
|
||||
a.sha256msg2(xmmA, anyptr_gpB);
|
||||
a.sha256rnds2(xmmA, xmmB);
|
||||
a.sha256rnds2(xmmA, anyptr_gpB);
|
||||
|
||||
// PCLMULQDQ.
|
||||
a.nop();
|
||||
|
||||
a.pclmulqdq(xmmA, xmmB, 0);
|
||||
a.pclmulqdq(xmmA, anyptr_gpB, 0);
|
||||
|
||||
// XSAVE.
|
||||
a.nop();
|
||||
|
||||
a.xgetbv();
|
||||
a.xsetbv();
|
||||
|
||||
a.xsave(anyptr_gpA);
|
||||
a.xsaveopt(anyptr_gpA);
|
||||
a.xrstor(anyptr_gpA);
|
||||
|
||||
// AVX.
|
||||
a.nop();
|
||||
|
||||
@@ -2823,87 +2997,6 @@ static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 =
|
||||
a.vpshlw(xmmA, anyptr_gpB, xmmC);
|
||||
a.vpshlw(xmmA, xmmB, anyptr_gpC);
|
||||
|
||||
// BMI.
|
||||
a.nop();
|
||||
|
||||
a.andn(gdA, gdB, gdC);
|
||||
a.andn(gzA, gzB, gzC);
|
||||
a.andn(gdA, gdB, anyptr_gpC);
|
||||
a.andn(gzA, gzB, anyptr_gpC);
|
||||
a.bextr(gdA, gdB, gdC);
|
||||
a.bextr(gzA, gzB, gzC);
|
||||
a.bextr(gdA, anyptr_gpB, gdC);
|
||||
a.bextr(gzA, anyptr_gpB, gzC);
|
||||
a.blsi(gdA, gdB);
|
||||
a.blsi(gzA, gzB);
|
||||
a.blsi(gdA, anyptr_gpB);
|
||||
a.blsi(gzA, anyptr_gpB);
|
||||
a.blsmsk(gdA, gdB);
|
||||
a.blsmsk(gzA, gzB);
|
||||
a.blsmsk(gdA, anyptr_gpB);
|
||||
a.blsmsk(gzA, anyptr_gpB);
|
||||
a.blsr(gdA, gdB);
|
||||
a.blsr(gzA, gzB);
|
||||
a.blsr(gdA, anyptr_gpB);
|
||||
a.blsr(gzA, anyptr_gpB);
|
||||
|
||||
// LZCNT.
|
||||
a.nop();
|
||||
|
||||
a.lzcnt(gdA, gdB);
|
||||
a.lzcnt(gzA, gzB);
|
||||
a.lzcnt(gdA, anyptr_gpB);
|
||||
a.lzcnt(gzA, anyptr_gpB);
|
||||
|
||||
// TZCNT.
|
||||
a.nop();
|
||||
|
||||
a.tzcnt(gdA, gdB);
|
||||
a.tzcnt(gzA, gzB);
|
||||
a.tzcnt(gdA, anyptr_gpB);
|
||||
a.tzcnt(gzA, anyptr_gpB);
|
||||
|
||||
// BMI2.
|
||||
a.nop();
|
||||
|
||||
a.bzhi(gdA, gdB, gdC);
|
||||
a.bzhi(gzA, gzB, gzC);
|
||||
a.bzhi(gdA, anyptr_gpB, gdC);
|
||||
a.bzhi(gzA, anyptr_gpB, gzC);
|
||||
a.mulx(gdA, gdB, gdC);
|
||||
a.mulx(gzA, gzB, gzC);
|
||||
a.mulx(gdA, gdB, anyptr_gpC);
|
||||
a.mulx(gzA, gzB, anyptr_gpC);
|
||||
a.pdep(gdA, gdB, gdC);
|
||||
a.pdep(gzA, gzB, gzC);
|
||||
a.pdep(gdA, gdB, anyptr_gpC);
|
||||
a.pdep(gzA, gzB, anyptr_gpC);
|
||||
a.pext(gdA, gdB, gdC);
|
||||
a.pext(gzA, gzB, gzC);
|
||||
a.pext(gdA, gdB, anyptr_gpC);
|
||||
a.pext(gzA, gzB, anyptr_gpC);
|
||||
a.rorx(gdA, gdB, 0);
|
||||
a.rorx(gzA, gzB, 0);
|
||||
a.rorx(gdA, anyptr_gpB, 0);
|
||||
a.rorx(gzA, anyptr_gpB, 0);
|
||||
a.sarx(gdA, gdB, gdC);
|
||||
a.sarx(gzA, gzB, gzC);
|
||||
a.sarx(gdA, anyptr_gpB, gdC);
|
||||
a.sarx(gzA, anyptr_gpB, gzC);
|
||||
a.shlx(gdA, gdB, gdC);
|
||||
a.shlx(gzA, gzB, gzC);
|
||||
a.shlx(gdA, anyptr_gpB, gdC);
|
||||
a.shlx(gzA, anyptr_gpB, gzC);
|
||||
a.shrx(gdA, gdB, gdC);
|
||||
a.shrx(gzA, gzB, gzC);
|
||||
a.shrx(gdA, anyptr_gpB, gdC);
|
||||
a.shrx(gzA, anyptr_gpB, gzC);
|
||||
|
||||
// RDRAND.
|
||||
a.nop();
|
||||
|
||||
a.rdrand(gzA);
|
||||
|
||||
// F16C.
|
||||
a.nop();
|
||||
|
||||
|
||||
@@ -79,6 +79,8 @@ static void dumpCpu(void) {
|
||||
{ asmjit::CpuInfo::kX86FeatureCMPXCHG16B , "CMPXCHG16B" },
|
||||
{ asmjit::CpuInfo::kX86FeatureCLFLUSH , "CLFLUSH" },
|
||||
{ asmjit::CpuInfo::kX86FeatureCLFLUSH_OPT , "CLFLUSH (Opt)" },
|
||||
{ asmjit::CpuInfo::kX86FeatureCLWB , "CLWB" },
|
||||
{ asmjit::CpuInfo::kX86FeaturePCOMMIT , "PCOMMIT" },
|
||||
{ asmjit::CpuInfo::kX86FeaturePREFETCH , "PREFETCH" },
|
||||
{ asmjit::CpuInfo::kX86FeaturePREFETCHWT1 , "PREFETCHWT1" },
|
||||
{ asmjit::CpuInfo::kX86FeatureLAHF_SAHF , "LAHF/SAHF" },
|
||||
@@ -104,6 +106,8 @@ static void dumpCpu(void) {
|
||||
{ asmjit::CpuInfo::kX86FeaturePCLMULQDQ , "PCLMULQDQ" },
|
||||
{ asmjit::CpuInfo::kX86FeatureRDRAND , "RDRAND" },
|
||||
{ asmjit::CpuInfo::kX86FeatureRDSEED , "RDSEED" },
|
||||
{ asmjit::CpuInfo::kX86FeatureSMAP , "SMAP" },
|
||||
{ asmjit::CpuInfo::kX86FeatureSMEP , "SMEP" },
|
||||
{ asmjit::CpuInfo::kX86FeatureSHA , "SHA" },
|
||||
{ asmjit::CpuInfo::kX86FeatureXSAVE , "XSAVE" },
|
||||
{ asmjit::CpuInfo::kX86FeatureXSAVE_OS , "XSAVE (OS)" },
|
||||
@@ -115,19 +119,22 @@ static void dumpCpu(void) {
|
||||
{ asmjit::CpuInfo::kX86FeatureXOP , "XOP" },
|
||||
{ asmjit::CpuInfo::kX86FeatureBMI , "BMI" },
|
||||
{ asmjit::CpuInfo::kX86FeatureBMI2 , "BMI2" },
|
||||
{ asmjit::CpuInfo::kX86FeatureADX , "ADX" },
|
||||
{ asmjit::CpuInfo::kX86FeatureTBM , "TBM" },
|
||||
{ asmjit::CpuInfo::kX86FeatureMPX , "MPX" },
|
||||
{ asmjit::CpuInfo::kX86FeatureHLE , "HLE" },
|
||||
{ asmjit::CpuInfo::kX86FeatureRTM , "RTM" },
|
||||
{ asmjit::CpuInfo::kX86FeatureADX , "ADX" },
|
||||
{ asmjit::CpuInfo::kX86FeatureMPX , "MPX" },
|
||||
{ asmjit::CpuInfo::kX86FeatureERMS , "ERMS" },
|
||||
{ asmjit::CpuInfo::kX86FeatureFSGSBASE , "FS/GS Base" },
|
||||
{ asmjit::CpuInfo::kX86FeatureMOVSBSTOSB_OPT, "REP MOVSB/STOSB (Opt)" },
|
||||
{ asmjit::CpuInfo::kX86FeatureAVX512F , "AVX512F" },
|
||||
{ asmjit::CpuInfo::kX86FeatureAVX512CD , "AVX512CD" },
|
||||
{ asmjit::CpuInfo::kX86FeatureAVX512PF , "AVX512PF" },
|
||||
{ asmjit::CpuInfo::kX86FeatureAVX512ER , "AVX512ER" },
|
||||
{ asmjit::CpuInfo::kX86FeatureAVX512DQ , "AVX512DQ" },
|
||||
{ asmjit::CpuInfo::kX86FeatureAVX512BW , "AVX512BW" },
|
||||
{ asmjit::CpuInfo::kX86FeatureAVX512VL , "AVX512VL" }
|
||||
{ asmjit::CpuInfo::kX86FeatureAVX512VL , "AVX512VL" },
|
||||
{ asmjit::CpuInfo::kX86FeatureAVX512IFMA , "AVX512IFMA" },
|
||||
{ asmjit::CpuInfo::kX86FeatureAVX512VBMI , "AVX512VBMI" }
|
||||
};
|
||||
|
||||
INFO("X86 Specific:");
|
||||
|
||||
@@ -12,290 +12,303 @@ var fs = require("fs");
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// [Utilities]
|
||||
// [Misc]
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
function upFirst(s) {
|
||||
if (!s) return "";
|
||||
return s[0].toUpperCase() + s.substr(1);
|
||||
}
|
||||
const kIndent = " ";
|
||||
const kJustify = 79;
|
||||
|
||||
function trimLeft(s) {
|
||||
return s.replace(/^\s+/, "");
|
||||
}
|
||||
const kDisclaimerStart = "// ------------------- Automatically generated, do not edit -------------------\n";
|
||||
const kDisclaimerEnd = "// ----------------------------------------------------------------------------\n";
|
||||
|
||||
function padLeft(s, n) {
|
||||
while (s.length < n)
|
||||
s += " ";
|
||||
return s;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
// [Utils]
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
function inject(s, start, end, code) {
|
||||
var iStart = s.indexOf(start);
|
||||
var iEnd = s.indexOf(end);
|
||||
class Utils {
|
||||
static upFirst(s) {
|
||||
if (!s) return "";
|
||||
return s[0].toUpperCase() + s.substr(1);
|
||||
}
|
||||
|
||||
if (iStart === -1)
|
||||
throw new Error("Couldn't locate start mark.");
|
||||
static trimLeft(s) {
|
||||
return s.replace(/^\s+/, "");
|
||||
}
|
||||
|
||||
if (iEnd === -1)
|
||||
throw new Error("Couldn't locate end mark.");
|
||||
static padLeft(s, n) {
|
||||
while (s.length < n)
|
||||
s += " ";
|
||||
return s;
|
||||
}
|
||||
|
||||
return s.substr(0, iStart + start.length) + code + s.substr(iEnd);
|
||||
static inject(s, start, end, code) {
|
||||
var iStart = s.indexOf(start);
|
||||
var iEnd = s.indexOf(end);
|
||||
|
||||
if (iStart === -1)
|
||||
throw new Error(`Couldn't locate start mark.`);
|
||||
|
||||
if (iEnd === -1)
|
||||
throw new Error(`Couldn't locate end mark.`);
|
||||
|
||||
return s.substr(0, iStart + start.length) + code + s.substr(iEnd);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// [IndexedString]
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
var IndexedString = function() {
|
||||
this.map = {};
|
||||
this.size = -1;
|
||||
this.array = [];
|
||||
};
|
||||
class IndexedString {
|
||||
constructor() {
|
||||
this.map = Object.create(null);
|
||||
this.size = -1;
|
||||
this.array = [];
|
||||
}
|
||||
|
||||
IndexedString.prototype.add = function(s) {
|
||||
this.map[s] = -1;
|
||||
};
|
||||
add(s) {
|
||||
this.map[s] = -1;
|
||||
}
|
||||
|
||||
IndexedString.prototype.index = function() {
|
||||
var map = this.map;
|
||||
var array = this.array;
|
||||
index() {
|
||||
const map = this.map;
|
||||
const array = this.array;
|
||||
const partialMap = Object.create(null);
|
||||
|
||||
var partialMap = {};
|
||||
var k, kp;
|
||||
var i, len;
|
||||
var k, kp;
|
||||
var i, len;
|
||||
|
||||
// Create a map that will contain all keys and partial keys.
|
||||
for (k in map) {
|
||||
if (!k) {
|
||||
partialMap[k] = k;
|
||||
}
|
||||
else {
|
||||
for (i = 0, len = k.length; i < len; i++) {
|
||||
var kp = k.substr(i);
|
||||
if (!hasOwn.call(partialMap, kp) || partialMap[kp].length < len)
|
||||
partialMap[kp] = k;
|
||||
// Create a map that will contain all keys and partial keys.
|
||||
for (k in map) {
|
||||
if (!k) {
|
||||
partialMap[k] = k;
|
||||
}
|
||||
else {
|
||||
for (i = 0, len = k.length; i < len; i++) {
|
||||
kp = k.substr(i);
|
||||
if (!hasOwn.call(partialMap, kp) || partialMap[kp].length < len)
|
||||
partialMap[kp] = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create an array that will only contain keys that are needed.
|
||||
for (k in map) {
|
||||
if (partialMap[k] === k)
|
||||
array.push(k);
|
||||
}
|
||||
array.sort();
|
||||
// Create an array that will only contain keys that are needed.
|
||||
for (k in map)
|
||||
if (partialMap[k] === k)
|
||||
array.push(k);
|
||||
array.sort();
|
||||
|
||||
// Create valid offsets to the `array`.
|
||||
var offMap = {};
|
||||
var offset = 0;
|
||||
|
||||
for (i = 0, len = array.length; i < len; i++) {
|
||||
k = array[i];
|
||||
|
||||
offMap[k] = offset;
|
||||
offset += k.length + 1;
|
||||
}
|
||||
this.size = offset;
|
||||
|
||||
// Assign valid offsets to `map`.
|
||||
for (kp in map) {
|
||||
k = partialMap[kp];
|
||||
map[kp] = offMap[k] + k.length - kp.length;
|
||||
}
|
||||
|
||||
/*
|
||||
(function() {
|
||||
// Testing code to experiment with eliminating suffixes from instruction names.
|
||||
var suffixList = [
|
||||
"ss", "ps", "sd", "pd",
|
||||
"bw", "bd", "bq",
|
||||
"ww", "wd", "wq",
|
||||
"dq", "b", "w", "d", "q"
|
||||
];
|
||||
var reducedMap = {};
|
||||
var reducedSize = 0;
|
||||
|
||||
var xMap = {};
|
||||
var xArr = [];
|
||||
// Create valid offsets to the `array`.
|
||||
var offMap = {};
|
||||
var offset = 0;
|
||||
|
||||
for (i = 0, len = array.length; i < len; i++) {
|
||||
k = array[i];
|
||||
|
||||
var suffix = null;
|
||||
var after = k;
|
||||
|
||||
for (var j = 0; j < suffixList.length; j++) {
|
||||
suffix = suffixList[j];
|
||||
if (k.lastIndexOf(suffix) === k.length - suffix.length) {
|
||||
after = k.substr(0, k.length - suffix.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
reducedMap[after] = true;
|
||||
offMap[k] = offset;
|
||||
offset += k.length + 1;
|
||||
}
|
||||
this.size = offset;
|
||||
|
||||
// Testing code to get which suffixes are the most used.
|
||||
for (k in map) {
|
||||
for (i = 1; i < k.length; i++) {
|
||||
var xKey = k.substr(i);
|
||||
if (hasOwn.call(xMap, xKey)) {
|
||||
xMap[xKey]++;
|
||||
}
|
||||
else {
|
||||
xMap[xKey] = 1;
|
||||
xArr.push(xKey);
|
||||
}
|
||||
}
|
||||
// Assign valid offsets to `map`.
|
||||
for (kp in map) {
|
||||
k = partialMap[kp];
|
||||
map[kp] = offMap[k] + k.length - kp.length;
|
||||
}
|
||||
|
||||
xArr.sort(function(a, b) {
|
||||
return xMap[a] - xMap[b];
|
||||
});
|
||||
for (i = 0; i < xArr.length; i++) {
|
||||
console.log(xArr[i] + " " + xMap[xArr[i]]);
|
||||
}
|
||||
|
||||
for (k in reducedMap)
|
||||
reducedSize += k.length + 1;
|
||||
console.log("ReducedSize=" + reducedSize);
|
||||
})();
|
||||
*/
|
||||
};
|
||||
|
||||
IndexedString.prototype.format = function(indent) {
|
||||
if (this.size === -1)
|
||||
throw new Error("IndexedString - not indexed yet, call index()");
|
||||
|
||||
var s = "";
|
||||
var array = this.array;
|
||||
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
s += indent + "\"" + array[i];
|
||||
s += (i !== array.length - 1) ? "\\0\"" : "\";";
|
||||
s += "\n";
|
||||
}
|
||||
|
||||
return s;
|
||||
};
|
||||
format(indent, justify) {
|
||||
if (this.size === -1)
|
||||
throw new Error(`IndexedString - not indexed yet, call index()`);
|
||||
|
||||
IndexedString.prototype.getSize = function() {
|
||||
if (this.size === -1)
|
||||
throw new Error("IndexedString - not indexed yet, call index()");
|
||||
return this.size;
|
||||
};
|
||||
const array = this.array;
|
||||
if (!justify) justify = 0;
|
||||
|
||||
IndexedString.prototype.getIndex = function(k) {
|
||||
if (this.size === -1)
|
||||
throw new Error("IndexedString - not indexed yet, call index()");
|
||||
var i;
|
||||
var s = "";
|
||||
var line = "";
|
||||
|
||||
if (!hasOwn.call(this.map, k))
|
||||
throw new Error("IndexedString - key '" + k + "' not found.");
|
||||
for (i = 0; i < array.length; i++) {
|
||||
const item = "\"" + array[i] + ((i !== array.length - 1) ? "\\0\"" : "\";");
|
||||
const newl = line + (line ? " " : indent) + item;
|
||||
|
||||
return this.map[k];
|
||||
};
|
||||
if (newl.length <= justify) {
|
||||
line = newl;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
s += line + "\n";
|
||||
line = indent + item;
|
||||
}
|
||||
}
|
||||
|
||||
s += line + "\n";
|
||||
return s;
|
||||
}
|
||||
|
||||
getSize() {
|
||||
if (this.size === -1)
|
||||
throw new Error(`IndexedString - not indexed yet, call index()`);
|
||||
return this.size;
|
||||
}
|
||||
|
||||
getIndex(k) {
|
||||
if (this.size === -1)
|
||||
throw new Error(`IndexedString - not indexed yet, call index()`);
|
||||
|
||||
if (!hasOwn.call(this.map, k))
|
||||
throw new Error(`IndexedString - key '${k}' not found.`);
|
||||
|
||||
return this.map[k];
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// [Database]
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
var Database = function() {
|
||||
this.instMap = {};
|
||||
this.instNames = new IndexedString();
|
||||
this.instAlpha = new Array(26);
|
||||
class Database {
|
||||
constructor() {
|
||||
this.instMap = Object.create(null);
|
||||
this.instArray = [];
|
||||
|
||||
this.extendedData = [];
|
||||
this.extendedMap = {};
|
||||
};
|
||||
this.instNames = new IndexedString();
|
||||
this.instAlpha = new Array(26);
|
||||
|
||||
Database.prototype.add = function(name, id, extendedData) {
|
||||
this.instMap[name] = {
|
||||
id : id, // Instruction ID.
|
||||
nameIndex : -1, // Instruction name-index.
|
||||
extendedData : extendedData,
|
||||
extendedIndex : ""
|
||||
};
|
||||
this.instNames.add(name);
|
||||
};
|
||||
this.extendedData = [];
|
||||
this.extendedMap = {};
|
||||
}
|
||||
|
||||
Database.prototype.index = function() {
|
||||
var instMap = this.instMap;
|
||||
var instNames = this.instNames;
|
||||
var instAlpha = this.instAlpha;
|
||||
add(name, enum_, id, extendedData) {
|
||||
const inst = {
|
||||
id : id, // Instruction index (number).
|
||||
name : name, // Instruction name.
|
||||
enum : enum_, // Instruction enum string.
|
||||
nameIndex : -1, // Instruction name-index.
|
||||
extendedData : extendedData,
|
||||
extendedIndex : ""
|
||||
};
|
||||
|
||||
var extendedData = this.extendedData;
|
||||
var extendedMap = this.extendedMap;
|
||||
this.instMap[name] = inst;
|
||||
this.instArray[id] = inst;
|
||||
|
||||
instNames.index();
|
||||
this.instNames.add(name);
|
||||
}
|
||||
|
||||
for (var name in instMap) {
|
||||
var inst = instMap[name];
|
||||
index() {
|
||||
const instMap = this.instMap;
|
||||
const instNames = this.instNames;
|
||||
const instAlpha = this.instAlpha;
|
||||
|
||||
var nameIndex = instNames.getIndex(name);
|
||||
var extendedIndex = extendedMap[inst.extendedData];
|
||||
var extendedData = this.extendedData;
|
||||
var extendedMap = this.extendedMap;
|
||||
|
||||
if (typeof extendedIndex !== "number") {
|
||||
extendedIndex = extendedData.length;
|
||||
extendedMap[inst.extendedData] = extendedIndex;
|
||||
extendedData.push(inst.extendedData);
|
||||
instNames.index();
|
||||
|
||||
for (var name in instMap) {
|
||||
var inst = instMap[name];
|
||||
|
||||
var nameIndex = instNames.getIndex(name);
|
||||
var extendedIndex = extendedMap[inst.extendedData];
|
||||
|
||||
if (typeof extendedIndex !== "number") {
|
||||
extendedIndex = extendedData.length;
|
||||
extendedMap[inst.extendedData] = extendedIndex;
|
||||
extendedData.push(inst.extendedData);
|
||||
}
|
||||
|
||||
inst.nameIndex = nameIndex;
|
||||
inst.extendedIndex = extendedIndex;
|
||||
|
||||
var aIndex = name.charCodeAt(0) - 'a'.charCodeAt(0);
|
||||
if (aIndex < 0 || aIndex >= 26)
|
||||
throw new Error("Alphabetical index error");
|
||||
|
||||
if (instAlpha[aIndex] === undefined)
|
||||
instAlpha[aIndex] = inst.enum;
|
||||
}
|
||||
}
|
||||
|
||||
formatInstNameIndex(indent, justify) {
|
||||
const instArray = this.instArray;
|
||||
if (!justify) justify = 0;
|
||||
|
||||
for (var i = 0; i < instArray; i++) {
|
||||
const inst = instArray[i];
|
||||
if (inst === undefined)
|
||||
throw new Error(`Database - no instruction #${i}`);
|
||||
}
|
||||
|
||||
inst.nameIndex = nameIndex;
|
||||
inst.extendedIndex = extendedIndex;
|
||||
var i;
|
||||
var s = "";
|
||||
var line = "";
|
||||
|
||||
var aIndex = name.charCodeAt(0) - 'a'.charCodeAt(0);
|
||||
if (aIndex < 0 || aIndex >= 26)
|
||||
throw new Error("Alphabetical index error");
|
||||
for (i = 0; i < instArray.length; i++) {
|
||||
const inst = instArray[i];
|
||||
if (inst === undefined)
|
||||
throw new Error(`Database - no instruction #${i}`);
|
||||
|
||||
if (instAlpha[aIndex] === undefined)
|
||||
instAlpha[aIndex] = inst.id;
|
||||
const item = String(inst.nameIndex) + ((i !== instArray.length - 1) ? "," : "");
|
||||
const newl = line + (line ? " " : indent) + item;
|
||||
|
||||
if (newl.length <= justify) {
|
||||
line = newl;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
s += line + "\n";
|
||||
line = indent + item;
|
||||
}
|
||||
}
|
||||
|
||||
s += line + "\n";
|
||||
return s;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// [Generate]
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
var decToHex = function(n, nPad) {
|
||||
function decToHex(n, nPad) {
|
||||
var hex = Number(n < 0 ? 0x100000000 + n : n).toString(16);
|
||||
while (nPad > hex.length)
|
||||
hex = "0" + hex;
|
||||
return "0x" + hex.toUpperCase();
|
||||
};
|
||||
}
|
||||
|
||||
var getEFlagsMask = function(eflags, passing) {
|
||||
function getEFlagsMask(eflags, passing) {
|
||||
var msk = 0x0;
|
||||
var bit = 0x1;
|
||||
|
||||
for (var i = 0; i < 8; i++, bit <<= 1) {
|
||||
for (var i = 0; i < 8; i++, bit <<= 1)
|
||||
if (passing.indexOf(eflags[i]) !== -1)
|
||||
msk |= bit;
|
||||
}
|
||||
|
||||
return msk;
|
||||
};
|
||||
}
|
||||
|
||||
var generate = function(fileName, arch) {
|
||||
var Arch = upFirst(arch);
|
||||
var oldData = fs.readFileSync(fileName, "utf8").replace(/\r\n/g, "\n");
|
||||
function generate(fileName, arch) {
|
||||
const Arch = Utils.upFirst(arch);
|
||||
const oldData = fs.readFileSync(fileName, "utf8").replace(/\r\n/g, "\n");
|
||||
|
||||
var data = oldData;
|
||||
var code = "";
|
||||
var disclaimer = "// Automatically generated, do not edit.\n";
|
||||
|
||||
var instCount = 0;
|
||||
var sizeof_X86InstInfo = 8;
|
||||
var sizeof_X86InstExtendedInfo = 24;
|
||||
|
||||
var kX86InstPrefix = "kX86InstId";
|
||||
|
||||
// Create database.
|
||||
var db = new Database();
|
||||
var re = new RegExp(
|
||||
"INST\\(([A-Za-z0-9_]+)\\s*," + // [01] Id.
|
||||
"\\s*\\\"([A-Za-z0-9_ ]*)\\\"\\s*," + // [02] Name.
|
||||
"(.{20}[^,]*)," + // [03] Opcode[0].
|
||||
"(.{20}[^,]*)," + // [04] Opcode[1].
|
||||
"([^,]+)," + // [05] Encoding.
|
||||
"([^,]+)," + // [03] Encoding.
|
||||
"(.{20}[^,]*)," + // [04] Opcode[0].
|
||||
"(.{20}[^,]*)," + // [05] Opcode[1].
|
||||
"([^,]+)," + // [06] IFLAGS.
|
||||
"\\s*EF\\(([A-Z_]+)\\)\\s*," + // [07] EFLAGS.
|
||||
"([^,]+)," + // [08] Write-Index.
|
||||
@@ -308,62 +321,41 @@ var generate = function(fileName, arch) {
|
||||
"g");
|
||||
|
||||
var i, k, m;
|
||||
var srcForm = "";
|
||||
var opCombinations = {};
|
||||
|
||||
while (m = re.exec(data)) {
|
||||
// Extract instruction ID and Name.
|
||||
var id = m[1];
|
||||
var name = m[2];
|
||||
const enum_ = kX86InstPrefix + m[1];
|
||||
const name = m[2];
|
||||
|
||||
// Extract data that goes to the secondary table (X86InstExtendedInfo).
|
||||
var opcode0 = trimLeft(m[3]);
|
||||
var opcode1 = trimLeft(m[4]);
|
||||
var encoding = trimLeft(m[5]);
|
||||
var iflags = trimLeft(m[6]);
|
||||
var eflags = m[7];
|
||||
var writeIndex = trimLeft(m[8]);
|
||||
var writeSize = trimLeft(m[9]);
|
||||
var oflags0 = trimLeft(m[10]);
|
||||
var oflags1 = trimLeft(m[11]);
|
||||
var oflags2 = trimLeft(m[12]);
|
||||
var oflags3 = trimLeft(m[13]);
|
||||
var oflags4 = trimLeft(m[14]);
|
||||
const encoding = Utils.trimLeft(m[3]);
|
||||
const opcode0 = Utils.trimLeft(m[4]);
|
||||
const opcode1 = Utils.trimLeft(m[5]);
|
||||
const iflags = Utils.trimLeft(m[6]);
|
||||
const eflags = m[7];
|
||||
const writeIndex = Utils.trimLeft(m[8]);
|
||||
const writeSize = Utils.trimLeft(m[9]);
|
||||
const oflags0 = Utils.trimLeft(m[10]);
|
||||
const oflags1 = Utils.trimLeft(m[11]);
|
||||
const oflags2 = Utils.trimLeft(m[12]);
|
||||
const oflags3 = Utils.trimLeft(m[13]);
|
||||
const oflags4 = Utils.trimLeft(m[14]);
|
||||
|
||||
// Generate EFlags-In and EFlags-Out.
|
||||
var eflagsIn = decToHex(getEFlagsMask(eflags, "RX" ), 2);
|
||||
var eflagsOut = decToHex(getEFlagsMask(eflags, "WXU"), 2);
|
||||
|
||||
var extData =
|
||||
encoding + ", " +
|
||||
writeIndex + ", " +
|
||||
writeSize + ", " +
|
||||
eflagsIn + ", " +
|
||||
eflagsOut + ", " +
|
||||
"0" + ", " +
|
||||
"{ " + oflags0 + ", " + oflags1 + ", " + oflags2 + ", " + oflags3 + ", " + oflags4 + " }, " +
|
||||
iflags + ", " +
|
||||
opcode1;
|
||||
var ops = `{ ${oflags0}, ${oflags1}, ${oflags2}, ${oflags3}, ${oflags4} }`;
|
||||
var extData = `${encoding}, ${writeIndex}, ${writeSize}, ${eflagsIn}, ${eflagsOut}, 0, ${ops}, ${iflags}, ${opcode1}`;
|
||||
|
||||
srcForm += " INST(" +
|
||||
padLeft(id, 27) + ", " +
|
||||
padLeft('"' + name + '"', 19) + ", " +
|
||||
opcode0 + ", " +
|
||||
opcode1 + ", " +
|
||||
encoding + ", " +
|
||||
iflags + ", " +
|
||||
"EF(" + eflags + "), " +
|
||||
writeIndex + ", " +
|
||||
writeSize + ", " +
|
||||
oflags0 + ", " +
|
||||
oflags1 + ", " +
|
||||
oflags2 + ", " +
|
||||
oflags3 + ", " +
|
||||
oflags4 + "),\n";
|
||||
if (!opCombinations[ops]) opCombinations[ops] = 0;
|
||||
opCombinations[ops]++;
|
||||
|
||||
db.add(name, id, extData);
|
||||
db.add(name, enum_, instCount, extData);
|
||||
instCount++;
|
||||
}
|
||||
// fs.writeFileSync("srcform.cpp", srcForm, "utf8");
|
||||
|
||||
db.index();
|
||||
|
||||
var instDataSize = instCount * sizeof_X86InstInfo + db.extendedData.length * sizeof_X86InstExtendedInfo;
|
||||
@@ -373,83 +365,83 @@ var generate = function(fileName, arch) {
|
||||
console.log("Instructions' Data Size: " + instDataSize);
|
||||
console.log("Instructions' Names Size: " + db.instNames.getSize());
|
||||
|
||||
// Generate InstName[] string.
|
||||
code += disclaimer;
|
||||
code += "#if !defined(ASMJIT_DISABLE_NAMES)\n";
|
||||
code += "const char _" + arch + "InstName[] =\n";
|
||||
code += db.instNames.format(" ") + "\n";
|
||||
// Generate _x86InstNameData[].
|
||||
code += kDisclaimerStart;
|
||||
code += `#if !defined(ASMJIT_DISABLE_NAMES)\n`;
|
||||
|
||||
code += `static const char _${arch}InstNameData[] =\n`;
|
||||
code += db.instNames.format(kIndent, kJustify);
|
||||
code += kDisclaimerEnd;
|
||||
code += `\n`;
|
||||
|
||||
// Generate _x86InstNameIndex[].
|
||||
code += `static const uint16_t _${arch}InstNameIndex[] = {\n`;
|
||||
code += db.formatInstNameIndex(kIndent, kJustify);
|
||||
code += `};\n`;
|
||||
code += `\n`;
|
||||
|
||||
// Generate AlphaIndex.
|
||||
code += disclaimer;
|
||||
code += "enum " + Arch + "InstAlphaIndex {\n";
|
||||
code += " k" + Arch + "InstAlphaIndexFirst = 'a',\n";
|
||||
code += " k" + Arch + "InstAlphaIndexLast = 'z',\n";
|
||||
code += " k" + Arch + "InstAlphaIndexInvalid = 0xFFFF\n";
|
||||
code += "};\n";
|
||||
code += "\n";
|
||||
code += `enum ${Arch}InstAlphaIndex {\n`;
|
||||
code += ` k${Arch}InstAlphaIndexFirst = 'a',\n`;
|
||||
code += ` k${Arch}InstAlphaIndexLast = 'z',\n`;
|
||||
code += ` k${Arch}InstAlphaIndexInvalid = 0xFFFF\n`;
|
||||
code += `};\n`;
|
||||
code += `\n`;
|
||||
|
||||
code += disclaimer;
|
||||
code += "static const uint16_t _" + arch + "InstAlphaIndex[26] = {\n";
|
||||
code += `static const uint16_t _${arch}InstAlphaIndex[26] = {\n`;
|
||||
for (i = 0; i < db.instAlpha.length; i++) {
|
||||
var id = db.instAlpha[i];
|
||||
code += " " + (id === undefined ? "0xFFFF" : id);
|
||||
code += kIndent + (id === undefined ? "0xFFFF" : id);
|
||||
if (i !== db.instAlpha.length - 1)
|
||||
code += ",";
|
||||
code += "\n";
|
||||
code += `,`;
|
||||
code += `\n`;
|
||||
}
|
||||
code += "};\n\n";
|
||||
code += `};\n`;
|
||||
|
||||
// Generate NameIndex.
|
||||
code += disclaimer;
|
||||
code += "enum " + Arch + "InstData_NameIndex {\n";
|
||||
for (k in db.instMap) {
|
||||
var inst = db.instMap[k];
|
||||
code += " " + inst.id + "_NameIndex = " + inst.nameIndex + ",\n";
|
||||
}
|
||||
code = code.substr(0, code.length - 2) + "\n};\n";
|
||||
code += "#endif // !ASMJIT_DISABLE_NAMES\n"
|
||||
code += "\n";
|
||||
code += `#endif // !ASMJIT_DISABLE_NAMES\n`;
|
||||
code += kDisclaimerEnd;
|
||||
code += `\n`;
|
||||
|
||||
// Generate ExtendedInfo.
|
||||
code += disclaimer;
|
||||
code += "const " + Arch + "InstExtendedInfo _" + arch + "InstExtendedInfo[] = {\n";
|
||||
code += kDisclaimerStart;
|
||||
code += `const ${Arch}InstExtendedInfo _${arch}InstExtendedInfo[] = {\n`;
|
||||
for (i = 0; i < db.extendedData.length; i++) {
|
||||
code += " { " + db.extendedData[i] + " }";
|
||||
if (i !== db.extendedData.length - 1)
|
||||
code += ",";
|
||||
code += "\n";
|
||||
code += `${kIndent}{ ${db.extendedData[i]} }`;
|
||||
if (i !== db.extendedData.length - 1) code += `,`;
|
||||
code += `\n`;
|
||||
}
|
||||
code += "};\n";
|
||||
code += "\n";
|
||||
code += `};\n`;
|
||||
code += kDisclaimerEnd;
|
||||
code += `\n`;
|
||||
|
||||
code += disclaimer;
|
||||
code += "enum " + Arch + "InstData_ExtendedIndex {\n";
|
||||
code += kDisclaimerStart;
|
||||
code += `enum ${Arch}InstData_ExtendedIndex {\n`;
|
||||
for (k in db.instMap) {
|
||||
var inst = db.instMap[k];
|
||||
code += " " + inst.id + "_ExtendedIndex = " + inst.extendedIndex + ",\n";
|
||||
code += `${kIndent} ${inst.enum}_ExtendedIndex = ${inst.extendedIndex},\n`;
|
||||
}
|
||||
code = code.substr(0, code.length - 2) + "\n};\n";
|
||||
code += kDisclaimerEnd;
|
||||
|
||||
// Inject.
|
||||
data = inject(data,
|
||||
data = Utils.inject(data,
|
||||
"// ${" + Arch + "InstData:Begin}\n",
|
||||
"// ${" + Arch + "InstData:End}\n",
|
||||
code);
|
||||
"// ${" + Arch + "InstData:End}\n", code);
|
||||
|
||||
// Save only if modified.
|
||||
if (data !== oldData)
|
||||
fs.writeFileSync(fileName, data, "utf8");
|
||||
};
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// [Main]
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
var main = function(files) {
|
||||
function main(files) {
|
||||
files.forEach(function(file) {
|
||||
generate(file.name, file.arch);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
main([{
|
||||
name: "../src/asmjit/x86/x86inst.cpp",
|
||||
|
||||
Reference in New Issue
Block a user