Commit 61d5cc0f authored by Peter's avatar Peter
Browse files

Merge branch 'master' into applecl

parents e2999354 afae4bc8
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Guard]
#ifndef _ASMJIT_X86_X86CPUINFO_H
#define _ASMJIT_X86_X86CPUINFO_H
// [Dependencies - AsmJit]
#include "../base/cpuinfo.h"
// [Api-Begin]
#include "../apibegin.h"
namespace asmjit {
// ============================================================================
// [Forward Declarations]
// ============================================================================
struct X86CpuInfo;
//! \addtogroup asmjit_x86_general
//! \{
// ============================================================================
// [asmjit::X86CpuFeature]
// ============================================================================
//! X86 CPU features.
ASMJIT_ENUM(X86CpuFeature) {
//! Cpu has Not-Execute-Bit.
kX86CpuFeatureNX = 0,
//! Cpu has multithreading.
kX86CpuFeatureMT,
//! Cpu has RDTSC.
kX86CpuFeatureRDTSC,
//! Cpu has RDTSCP.
kX86CpuFeatureRDTSCP,
//! Cpu has CMOV.
kX86CpuFeatureCMOV,
//! Cpu has CMPXCHG8B.
kX86CpuFeatureCMPXCHG8B,
//! Cpu has CMPXCHG16B (X64).
kX86CpuFeatureCMPXCHG16B,
//! Cpu has CLFUSH.
kX86CpuFeatureCLFLUSH,
//! Cpu has CLFUSH (Optimized).
kX86CpuFeatureCLFLUSHOpt,
//! Cpu has PREFETCH.
kX86CpuFeaturePREFETCH,
//! Cpu has PREFETCHWT1.
kX86CpuFeaturePREFETCHWT1,
//! Cpu has LAHF/SAHF.
kX86CpuFeatureLahfSahf,
//! Cpu has FXSAVE/FXRSTOR.
kX86CpuFeatureFXSR,
//! Cpu has FXSAVE/FXRSTOR (Optimized).
kX86CpuFeatureFXSROpt,
//! Cpu has MMX.
kX86CpuFeatureMMX,
//! Cpu has extended MMX.
kX86CpuFeatureMMX2,
//! Cpu has 3dNow!
kX86CpuFeature3DNOW,
//! Cpu has enchanced 3dNow!
kX86CpuFeature3DNOW2,
//! Cpu has SSE.
kX86CpuFeatureSSE,
//! Cpu has SSE2.
kX86CpuFeatureSSE2,
//! Cpu has SSE3.
kX86CpuFeatureSSE3,
//! Cpu has SSSE3.
kX86CpuFeatureSSSE3,
//! Cpu has SSE4.A.
kX86CpuFeatureSSE4A,
//! Cpu has SSE4.1.
kX86CpuFeatureSSE4_1,
//! Cpu has SSE4.2.
kX86CpuFeatureSSE4_2,
//! Cpu has Misaligned SSE (MSSE).
kX86CpuFeatureMSSE,
//! Cpu has MONITOR and MWAIT.
kX86CpuFeatureMONITOR,
//! Cpu has MOVBE.
kX86CpuFeatureMOVBE,
//! Cpu has POPCNT.
kX86CpuFeaturePOPCNT,
//! Cpu has LZCNT.
kX86CpuFeatureLZCNT,
//! Cpu has AESNI.
kX86CpuFeatureAESNI,
//! Cpu has PCLMULQDQ.
kX86CpuFeaturePCLMULQDQ,
//! Cpu has RDRAND.
kX86CpuFeatureRDRAND,
//! Cpu has RDSEED.
kX86CpuFeatureRDSEED,
//! Cpu has SHA-1 and SHA-256.
kX86CpuFeatureSHA,
//! Cpu has XSAVE support - XSAVE/XRSTOR, XSETBV/XGETBV, and XCR0.
kX86CpuFeatureXSave,
//! OS has enabled XSAVE, you can call XGETBV to get value of XCR0.
kX86CpuFeatureXSaveOS,
//! Cpu has AVX.
kX86CpuFeatureAVX,
//! Cpu has AVX2.
kX86CpuFeatureAVX2,
//! Cpu has F16C.
kX86CpuFeatureF16C,
//! Cpu has FMA3.
kX86CpuFeatureFMA3,
//! Cpu has FMA4.
kX86CpuFeatureFMA4,
//! Cpu has XOP.
kX86CpuFeatureXOP,
//! Cpu has BMI.
kX86CpuFeatureBMI,
//! Cpu has BMI2.
kX86CpuFeatureBMI2,
//! Cpu has HLE.
kX86CpuFeatureHLE,
//! Cpu has RTM.
kX86CpuFeatureRTM,
//! Cpu has ADX.
kX86CpuFeatureADX,
//! Cpu has MPX (Memory Protection Extensions).
kX86CpuFeatureMPX,
//! Cpu has FSGSBASE.
kX86CpuFeatureFSGSBase,
//! Cpu has optimized REP MOVSB/STOSB.
kX86CpuFeatureMOVSBSTOSBOpt,
//! Cpu has AVX-512F (Foundation).
kX86CpuFeatureAVX512F,
//! Cpu has AVX-512CD (Conflict Detection).
kX86CpuFeatureAVX512CD,
//! Cpu has AVX-512PF (Prefetch Instructions).
kX86CpuFeatureAVX512PF,
//! Cpu has AVX-512ER (Exponential and Reciprocal Instructions).
kX86CpuFeatureAVX512ER,
//! Cpu has AVX-512DQ (DWord/QWord).
kX86CpuFeatureAVX512DQ,
//! Cpu has AVX-512BW (Byte/Word).
kX86CpuFeatureAVX512BW,
//! Cpu has AVX VL (Vector Length Excensions).
kX86CpuFeatureAVX512VL,
//! Count of X86/X64 Cpu features.
kX86CpuFeatureCount
};
// ============================================================================
// [asmjit::X86CpuId]
// ============================================================================
//! X86/X64 CPUID output.
union X86CpuId {
//! EAX/EBX/ECX/EDX output.
uint32_t i[4];
struct {
//! EAX output.
uint32_t eax;
//! EBX output.
uint32_t ebx;
//! ECX output.
uint32_t ecx;
//! EDX output.
uint32_t edx;
};
};
// ============================================================================
// [asmjit::X86CpuUtil]
// ============================================================================
#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64)
//! CPU utilities available only if the host processor is X86/X64.
struct X86CpuUtil {
//! \internal
//!
//! Designed to support VS2008 and less in 64-bit mode, even if this compiler
//! doesn't have `__cpuidex` intrinsic.
ASMJIT_API static void _docpuid(uint32_t inEcx, uint32_t inEax, X86CpuId* out);
//! Get the result of calling CPUID instruction to `out`.
static ASMJIT_INLINE void callCpuId(X86CpuId* out, uint32_t inEax, uint32_t inEcx = 0) {
return _docpuid(inEcx, inEax, out);
}
//! Detect the Host CPU.
ASMJIT_API static void detect(X86CpuInfo* cpuInfo);
};
#endif // ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64
// ============================================================================
// [asmjit::X86CpuInfo]
// ============================================================================
struct X86CpuInfo : public CpuInfo {
ASMJIT_NO_COPY(X86CpuInfo)
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
ASMJIT_INLINE X86CpuInfo();
// --------------------------------------------------------------------------
// [Accessors]
// --------------------------------------------------------------------------
//! Get processor type.
ASMJIT_INLINE uint32_t getProcessorType() const {
return _processorType;
}
//! Get brand index.
ASMJIT_INLINE uint32_t getBrandIndex() const {
return _brandIndex;
}
//! Get flush cache line size.
ASMJIT_INLINE uint32_t getFlushCacheLineSize() const {
return _flushCacheLineSize;
}
//! Get maximum logical processors count.
ASMJIT_INLINE uint32_t getMaxLogicalProcessors() const {
return _maxLogicalProcessors;
}
// --------------------------------------------------------------------------
// [Statics]
// --------------------------------------------------------------------------
#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64)
//! Get global instance of `X86CpuInfo`.
static ASMJIT_INLINE const X86CpuInfo* getHost() {
return static_cast<const X86CpuInfo*>(CpuInfo::getHost());
}
#endif // ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
//! 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;
};
ASMJIT_INLINE X86CpuInfo::X86CpuInfo() :
CpuInfo(sizeof(X86CpuInfo)) {}
//! \}
} // asmjit namespace
// [Api-End]
#include "../apiend.h"
// [Guard]
#endif // _ASMJIT_X86_X86CPUINFO_H
This source diff could not be displayed because it is too large. You can view the blob instead.
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Guard]
#ifndef _ASMJIT_X86_X86INST_H
#define _ASMJIT_X86_X86INST_H
// [Dependencies - AsmJit]
#include "../base/assembler.h"
#include "../base/compiler.h"
#include "../base/globals.h"
#include "../base/intutil.h"
#include "../base/operand.h"
#include "../base/vectypes.h"
// [Api-Begin]
#include "../apibegin.h"
namespace asmjit {
// ============================================================================
// [Forward Declarations]
// ============================================================================
struct X86InstInfo;
struct X86InstExtendedInfo;
//! \addtogroup asmjit_x86_inst
//! \{
// ============================================================================
// [asmjit::X86Inst/X86Cond - Globals]
// ============================================================================
#if !defined(ASMJIT_DISABLE_NAMES)
//! \internal
//!
//! X86/X64 instructions' names, accessible through `X86InstInfo`.
ASMJIT_VAR const char _x86InstName[];
#endif // !ASMJIT_DISABLE_NAMES
//! \internal
//!
//! X86/X64 instructions' extended information, accessible through `X86InstInfo`.
ASMJIT_VAR const X86InstExtendedInfo _x86InstExtendedInfo[];
//! \internal
//!
//! X86/X64 instructions' information.
ASMJIT_VAR const X86InstInfo _x86InstInfo[];
//! \internal
//!
//! X86/X64 condition codes to reversed condition codes map.
ASMJIT_VAR const uint32_t _x86ReverseCond[20];
//! \internal
//!
//! X86/X64 condition codes to "cmovcc" group map.
ASMJIT_VAR const uint32_t _x86CondToCmovcc[20];
//! \internal
//!
//! X86/X64 condition codes to "jcc" group map.
ASMJIT_VAR const uint32_t _x86CondToJcc[20];
//! \internal
//!
//! X86/X64 condition codes to "setcc" group map.
ASMJIT_VAR const uint32_t _x86CondToSetcc[20];
// ============================================================================
// [asmjit::X86InstId]
// ============================================================================
//! X86/X64 instruction IDs.
//!
//! Note that these instruction codes are AsmJit specific. Each instruction has
//! a unique ID that is used as an index to AsmJit instruction table. The list
//! is sorted alphabetically except instructions starting with `j`, because the
//! `jcc` instruction is composition of an opcode and condition code. It means
//! that these instructions are sorted as `jcc`, `jecxz` and `jmp`. Please use
//! \ref X86Util::getInstIdByName() if you need instruction name to ID mapping
//! and are not aware on how to handle such case.
ASMJIT_ENUM(X86InstId) {
kX86InstIdAdc = 1, // X86/X64
kX86InstIdAdd, // X86/X64
kX86InstIdAddpd, // SSE2
kX86InstIdAddps, // SSE
kX86InstIdAddsd, // SSE2
kX86InstIdAddss, // SSE
kX86InstIdAddsubpd, // SSE3
kX86InstIdAddsubps, // SSE3
kX86InstIdAesdec, // AESNI
kX86InstIdAesdeclast, // AESNI
kX86InstIdAesenc, // AESNI
kX86InstIdAesenclast, // AESNI
kX86InstIdAesimc, // AESNI
kX86InstIdAeskeygenassist, // AESNI
kX86InstIdAnd, // X86/X64
kX86InstIdAndn, // BMI
kX86InstIdAndnpd, // SSE2
kX86InstIdAndnps, // SSE
kX86InstIdAndpd, // SSE2
kX86InstIdAndps, // SSE
kX86InstIdBextr, // BMI
kX86InstIdBlendpd, // SSE4.1
kX86InstIdBlendps, // SSE4.1
kX86InstIdBlendvpd, // SSE4.1
kX86InstIdBlendvps, // SSE4.1
kX86InstIdBlsi, // BMI
kX86InstIdBlsmsk, // BMI
kX86InstIdBlsr, // BMI
kX86InstIdBsf, // X86/X64
kX86InstIdBsr, // X86/X64
kX86InstIdBswap, // X86/X64 (i486+)
kX86InstIdBt, // X86/X64
kX86InstIdBtc, // X86/X64
kX86InstIdBtr, // X86/X64
kX86InstIdBts, // X86/X64
kX86InstIdBzhi, // BMI2
kX86InstIdCall, // X86/X64
kX86InstIdCbw, // X86/X64
kX86InstIdCdq, // X86/X64
kX86InstIdCdqe, // X64 only
kX86InstIdClc, // X86/X64
kX86InstIdCld, // X86/X64
kX86InstIdClflush, // SSE2
kX86InstIdCmc, // X86/X64
kX86InstIdCmova, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovae, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovb, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovbe, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovc, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmove, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovg, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovge, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovl, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovle, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovna, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovnae, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovnb, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovnbe, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovnc, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovne, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovng, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovnge, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovnl, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovnle, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovno, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovnp, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovns, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovnz, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovo, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovp, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovpe, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovpo, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovs, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmovz, // X86/X64 (cmovcc) (i586+)
kX86InstIdCmp, // X86/X64
kX86InstIdCmppd, // SSE2
kX86InstIdCmpps, // SSE
kX86InstIdCmpsB, // CMPS - X86/X64
kX86InstIdCmpsD, // CMPS - X86/X64
kX86InstIdCmpsQ, // CMPS - X64
kX86InstIdCmpsW, // CMPS - X86/X64
kX86InstIdCmpsd, // SSE2
kX86InstIdCmpss, // SSE
kX86InstIdCmpxchg, // X86/X64 (i486+)
kX86InstIdCmpxchg16b, // X64 only
kX86InstIdCmpxchg8b, // X86/X64 (i586+)
kX86InstIdComisd, // SSE2
kX86InstIdComiss, // SSE
kX86InstIdCpuid, // X86/X64 (i486/i586+)
kX86InstIdCqo, // X64 only
kX86InstIdCrc32, // SSE4.2
kX86InstIdCvtdq2pd, // SSE2
kX86InstIdCvtdq2ps, // SSE2
kX86InstIdCvtpd2dq, // SSE2
kX86InstIdCvtpd2pi, // SSE2
kX86InstIdCvtpd2ps, // SSE2
kX86InstIdCvtpi2pd, // SSE2
kX86InstIdCvtpi2ps, // SSE
kX86InstIdCvtps2dq, // SSE2
kX86InstIdCvtps2pd, // SSE2
kX86InstIdCvtps2pi, // SSE
kX86InstIdCvtsd2si, // SSE2
kX86InstIdCvtsd2ss, // SSE2
kX86InstIdCvtsi2sd, // SSE2
kX86InstIdCvtsi2ss, // SSE
kX86InstIdCvtss2sd, // SSE2
kX86InstIdCvtss2si, // SSE
kX86InstIdCvttpd2dq, // SSE2
kX86InstIdCvttpd2pi, // SSE2
kX86InstIdCvttps2dq, // SSE2
kX86InstIdCvttps2pi, // SSE
kX86InstIdCvttsd2si, // SSE2
kX86InstIdCvttss2si, // SSE
kX86InstIdCwd, // X86/X64
kX86InstIdCwde, // X86/X64
kX86InstIdDaa, // X86 only
kX86InstIdDas, // X86 only
kX86InstIdDec, // X86/X64
kX86InstIdDiv, // X86/X64
kX86InstIdDivpd, // SSE2
kX86InstIdDivps, // SSE
kX86InstIdDivsd, // SSE2
kX86InstIdDivss, // SSE
kX86InstIdDppd, // SSE4.1
kX86InstIdDpps, // SSE4.1
kX86InstIdEmms, // MMX
kX86InstIdEnter, // X86/X64
kX86InstIdExtractps, // SSE4.1
kX86InstIdExtrq, // SSE4a
kX86InstIdF2xm1, // FPU
kX86InstIdFabs, // FPU
kX86InstIdFadd, // FPU
kX86InstIdFaddp, // FPU
kX86InstIdFbld, // FPU
kX86InstIdFbstp, // FPU
kX86InstIdFchs, // FPU
kX86InstIdFclex, // FPU
kX86InstIdFcmovb, // FPU
kX86InstIdFcmovbe, // FPU
kX86InstIdFcmove, // FPU
kX86InstIdFcmovnb, // FPU
kX86InstIdFcmovnbe, // FPU
kX86InstIdFcmovne, // FPU
kX86InstIdFcmovnu, // FPU
kX86InstIdFcmovu, // FPU
kX86InstIdFcom, // FPU
kX86InstIdFcomi, // FPU
kX86InstIdFcomip, // FPU
kX86InstIdFcomp, // FPU
kX86InstIdFcompp, // FPU
kX86InstIdFcos, // FPU
kX86InstIdFdecstp, // FPU
kX86InstIdFdiv, // FPU
kX86InstIdFdivp, // FPU
kX86InstIdFdivr, // FPU
kX86InstIdFdivrp, // FPU
kX86InstIdFemms, // 3dNow!
kX86InstIdFfree, // FPU
kX86InstIdFiadd, // FPU
kX86InstIdFicom, // FPU
kX86InstIdFicomp, // FPU
kX86InstIdFidiv, // FPU
kX86InstIdFidivr, // FPU
kX86InstIdFild, // FPU
kX86InstIdFimul, // FPU
kX86InstIdFincstp, // FPU
kX86InstIdFinit, // FPU
kX86InstIdFist, // FPU
kX86InstIdFistp, // FPU
kX86InstIdFisttp, // SSE3
kX86InstIdFisub, // FPU
kX86InstIdFisubr, // FPU
kX86InstIdFld, // FPU
kX86InstIdFld1, // FPU
kX86InstIdFldcw, // FPU
kX86InstIdFldenv, // FPU
kX86InstIdFldl2e, // FPU
kX86InstIdFldl2t, // FPU
kX86InstIdFldlg2, // FPU
kX86InstIdFldln2, // FPU
kX86InstIdFldpi, // FPU
kX86InstIdFldz, // FPU
kX86InstIdFmul, // FPU
kX86InstIdFmulp, // FPU
kX86InstIdFnclex, // FPU
kX86InstIdFninit, // FPU
kX86InstIdFnop, // FPU
kX86InstIdFnsave, // FPU
kX86InstIdFnstcw, // FPU
kX86InstIdFnstenv, // FPU
kX86InstIdFnstsw, // FPU
kX86InstIdFpatan, // FPU
kX86InstIdFprem, // FPU
kX86InstIdFprem1, // FPU
kX86InstIdFptan, // FPU
kX86InstIdFrndint, // FPU
kX86InstIdFrstor, // FPU
kX86InstIdFsave, // FPU
kX86InstIdFscale, // FPU
kX86InstIdFsin, // FPU
kX86InstIdFsincos, // FPU
kX86InstIdFsqrt, // FPU
kX86InstIdFst, // FPU
kX86InstIdFstcw, // FPU
kX86InstIdFstenv, // FPU
kX86InstIdFstp, // FPU
kX86InstIdFstsw, // FPU
kX86InstIdFsub, // FPU
kX86InstIdFsubp, // FPU
kX86InstIdFsubr, // FPU
kX86InstIdFsubrp, // FPU
kX86InstIdFtst, // FPU
kX86InstIdFucom, // FPU
kX86InstIdFucomi, // FPU
kX86InstIdFucomip, // FPU
kX86InstIdFucomp, // FPU
kX86InstIdFucompp, // FPU
kX86InstIdFwait, // FPU
kX86InstIdFxam, // FPU
kX86InstIdFxch, // FPU
kX86InstIdFxrstor, // FPU
kX86InstIdFxsave, // FPU
kX86InstIdFxtract, // FPU
kX86InstIdFyl2x, // FPU
kX86InstIdFyl2xp1, // FPU
kX86InstIdHaddpd, // SSE3
kX86InstIdHaddps, // SSE3
kX86InstIdHsubpd, // SSE3
kX86InstIdHsubps, // SSE3
kX86InstIdIdiv, // X86/X64
kX86InstIdImul, // X86/X64
kX86InstIdInc, // X86/X64
kX86InstIdInsertps, // SSE4.1
kX86InstIdInsertq, // SSE4a
kX86InstIdInt, // X86/X64
kX86InstIdJa, // X86/X64 (jcc)
kX86InstIdJae, // X86/X64 (jcc)
kX86InstIdJb, // X86/X64 (jcc)
kX86InstIdJbe, // X86/X64 (jcc)
kX86InstIdJc, // X86/X64 (jcc)
kX86InstIdJe, // X86/X64 (jcc)
kX86InstIdJg, // X86/X64 (jcc)
kX86InstIdJge, // X86/X64 (jcc)
kX86InstIdJl, // X86/X64 (jcc)
kX86InstIdJle, // X86/X64 (jcc)
kX86InstIdJna, // X86/X64 (jcc)
kX86InstIdJnae, // X86/X64 (jcc)
kX86InstIdJnb, // X86/X64 (jcc)
kX86InstIdJnbe, // X86/X64 (jcc)
kX86InstIdJnc, // X86/X64 (jcc)
kX86InstIdJne, // X86/X64 (jcc)
kX86InstIdJng, // X86/X64 (jcc)
kX86InstIdJnge, // X86/X64 (jcc)
kX86InstIdJnl, // X86/X64 (jcc)
kX86InstIdJnle, // X86/X64 (jcc)
kX86InstIdJno, // X86/X64 (jcc)
kX86InstIdJnp, // X86/X64 (jcc)
kX86InstIdJns, // X86/X64 (jcc)
kX86InstIdJnz, // X86/X64 (jcc)
kX86InstIdJo, // X86/X64 (jcc)
kX86InstIdJp, // X86/X64 (jcc)
kX86InstIdJpe, // X86/X64 (jcc)
kX86InstIdJpo, // X86/X64 (jcc)
kX86InstIdJs, // X86/X64 (jcc)
kX86InstIdJz, // X86/X64 (jcc)
kX86InstIdJecxz, // X86/X64 (jcxz/jecxz/jrcxz)
kX86InstIdJmp, // X86/X64 (jmp)
kX86InstIdLahf, // X86/X64 (CPUID NEEDED)
kX86InstIdLddqu, // SSE3
kX86InstIdLdmxcsr, // SSE
kX86InstIdLea, // X86/X64
kX86InstIdLeave, // X86/X64
kX86InstIdLfence, // SSE2
kX86InstIdLodsB, // LODS - X86/X64
kX86InstIdLodsD, // LODS - X86/X64
kX86InstIdLodsQ, // LODS - X86/X64
kX86InstIdLodsW, // LODS - X86/X64
kX86InstIdLzcnt, // LZCNT
kX86InstIdMaskmovdqu, // SSE2
kX86InstIdMaskmovq, // MMX-Ext
kX86InstIdMaxpd, // SSE2
kX86InstIdMaxps, // SSE
kX86InstIdMaxsd, // SSE2
kX86InstIdMaxss, // SSE
kX86InstIdMfence, // SSE2
kX86InstIdMinpd, // SSE2
kX86InstIdMinps, // SSE
kX86InstIdMinsd, // SSE2
kX86InstIdMinss, // SSE
kX86InstIdMonitor, // SSE3
kX86InstIdMov, // X86/X64
kX86InstIdMovPtr, // X86/X64
kX86InstIdMovapd, // SSE2
kX86InstIdMovaps, // SSE
kX86InstIdMovbe, // SSE3 - Intel-Atom
kX86InstIdMovd, // MMX/SSE2
kX86InstIdMovddup, // SSE3
kX86InstIdMovdq2q, // SSE2
kX86InstIdMovdqa, // SSE2
kX86InstIdMovdqu, // SSE2
kX86InstIdMovhlps, // SSE
kX86InstIdMovhpd, // SSE2
kX86InstIdMovhps, // SSE
kX86InstIdMovlhps, // SSE
kX86InstIdMovlpd, // SSE2
kX86InstIdMovlps, // SSE
kX86InstIdMovmskpd, // SSE2
kX86InstIdMovmskps, // SSE2
kX86InstIdMovntdq, // SSE2
kX86InstIdMovntdqa, // SSE4.1
kX86InstIdMovnti, // SSE2
kX86InstIdMovntpd, // SSE2
kX86InstIdMovntps, // SSE
kX86InstIdMovntq, // MMX-Ext
kX86InstIdMovntsd, // SSE4a
kX86InstIdMovntss, // SSE4a
kX86InstIdMovq, // MMX/SSE/SSE2
kX86InstIdMovq2dq, // SSE2
kX86InstIdMovsB, // MOVS - X86/X64
kX86InstIdMovsD, // MOVS - X86/X64
kX86InstIdMovsQ, // MOVS - X64
kX86InstIdMovsW, // MOVS - X86/X64
kX86InstIdMovsd, // SSE2
kX86InstIdMovshdup, // SSE3
kX86InstIdMovsldup, // SSE3
kX86InstIdMovss, // SSE
kX86InstIdMovsx, // X86/X64
kX86InstIdMovsxd, // X86/X64
kX86InstIdMovupd, // SSE2
kX86InstIdMovups, // SSE
kX86InstIdMovzx, // X86/X64
kX86InstIdMpsadbw, // SSE4.1
kX86InstIdMul, // X86/X64
kX86InstIdMulpd, // SSE2
kX86InstIdMulps, // SSE
kX86InstIdMulsd, // SSE2
kX86InstIdMulss, // SSE
kX86InstIdMulx, // BMI2
kX86InstIdMwait, // SSE3
kX86InstIdNeg, // X86/X64
kX86InstIdNop, // X86/X64
kX86InstIdNot, // X86/X64
kX86InstIdOr, // X86/X64
kX86InstIdOrpd, // SSE2
kX86InstIdOrps, // SSE
kX86InstIdPabsb, // SSSE3
kX86InstIdPabsd, // SSSE3
kX86InstIdPabsw, // SSSE3
kX86InstIdPackssdw, // MMX/SSE2
kX86InstIdPacksswb, // MMX/SSE2
kX86InstIdPackusdw, // SSE4.1
kX86InstIdPackuswb, // MMX/SSE2
kX86InstIdPaddb, // MMX/SSE2
kX86InstIdPaddd, // MMX/SSE2
kX86InstIdPaddq, // SSE2
kX86InstIdPaddsb, // MMX/SSE2
kX86InstIdPaddsw, // MMX/SSE2
kX86InstIdPaddusb, // MMX/SSE2
kX86InstIdPaddusw, // MMX/SSE2
kX86InstIdPaddw, // MMX/SSE2
kX86InstIdPalignr, // SSSE3
kX86InstIdPand, // MMX/SSE2
kX86InstIdPandn, // MMX/SSE2
kX86InstIdPause, // SSE2.
kX86InstIdPavgb, // MMX-Ext
kX86InstIdPavgw, // MMX-Ext
kX86InstIdPblendvb, // SSE4.1
kX86InstIdPblendw, // SSE4.1
kX86InstIdPclmulqdq, // PCLMULQDQ
kX86InstIdPcmpeqb, // MMX/SSE2
kX86InstIdPcmpeqd, // MMX/SSE2
kX86InstIdPcmpeqq, // SSE4.1
kX86InstIdPcmpeqw, // MMX/SSE2
kX86InstIdPcmpestri, // SSE4.2
kX86InstIdPcmpestrm, // SSE4.2
kX86InstIdPcmpgtb, // MMX/SSE2
kX86InstIdPcmpgtd, // MMX/SSE2
kX86InstIdPcmpgtq, // SSE4.2
kX86InstIdPcmpgtw, // MMX/SSE2
kX86InstIdPcmpistri, // SSE4.2
kX86InstIdPcmpistrm, // SSE4.2
kX86InstIdPdep, // BMI2
kX86InstIdPext, // BMI2
kX86InstIdPextrb, // SSE4.1
kX86InstIdPextrd, // SSE4.1
kX86InstIdPextrq, // SSE4.1
kX86InstIdPextrw, // MMX-Ext/SSE2
kX86InstIdPf2id, // 3dNow!
kX86InstIdPf2iw, // Enhanced 3dNow!
kX86InstIdPfacc, // 3dNow!
kX86InstIdPfadd, // 3dNow!
kX86InstIdPfcmpeq, // 3dNow!
kX86InstIdPfcmpge, // 3dNow!
kX86InstIdPfcmpgt, // 3dNow!
kX86InstIdPfmax, // 3dNow!
kX86InstIdPfmin, // 3dNow!
kX86InstIdPfmul, // 3dNow!
kX86InstIdPfnacc, // Enhanced 3dNow!
kX86InstIdPfpnacc, // Enhanced 3dNow!
kX86InstIdPfrcp, // 3dNow!
kX86InstIdPfrcpit1, // 3dNow!
kX86InstIdPfrcpit2, // 3dNow!
kX86InstIdPfrsqit1, // 3dNow!
kX86InstIdPfrsqrt, // 3dNow!
kX86InstIdPfsub, // 3dNow!
kX86InstIdPfsubr, // 3dNow!
kX86InstIdPhaddd, // SSSE3
kX86InstIdPhaddsw, // SSSE3
kX86InstIdPhaddw, // SSSE3
kX86InstIdPhminposuw, // SSE4.1
kX86InstIdPhsubd, // SSSE3
kX86InstIdPhsubsw, // SSSE3
kX86InstIdPhsubw, // SSSE3
kX86InstIdPi2fd, // 3dNow!
kX86InstIdPi2fw, // Enhanced 3dNow!
kX86InstIdPinsrb, // SSE4.1
kX86InstIdPinsrd, // SSE4.1
kX86InstIdPinsrq, // SSE4.1
kX86InstIdPinsrw, // MMX-Ext
kX86InstIdPmaddubsw, // SSSE3
kX86InstIdPmaddwd, // MMX/SSE2
kX86InstIdPmaxsb, // SSE4.1
kX86InstIdPmaxsd, // SSE4.1
kX86InstIdPmaxsw, // MMX-Ext
kX86InstIdPmaxub, // MMX-Ext
kX86InstIdPmaxud, // SSE4.1
kX86InstIdPmaxuw, // SSE4.1
kX86InstIdPminsb, // SSE4.1
kX86InstIdPminsd, // SSE4.1
kX86InstIdPminsw, // MMX-Ext
kX86InstIdPminub, // MMX-Ext
kX86InstIdPminud, // SSE4.1
kX86InstIdPminuw, // SSE4.1
kX86InstIdPmovmskb, // MMX-Ext
kX86InstIdPmovsxbd, // SSE4.1
kX86InstIdPmovsxbq, // SSE4.1
kX86InstIdPmovsxbw, // SSE4.1
kX86InstIdPmovsxdq, // SSE4.1
kX86InstIdPmovsxwd, // SSE4.1
kX86InstIdPmovsxwq, // SSE4.1
kX86InstIdPmovzxbd, // SSE4.1
kX86InstIdPmovzxbq, // SSE4.1
kX86InstIdPmovzxbw, // SSE4.1
kX86InstIdPmovzxdq, // SSE4.1
kX86InstIdPmovzxwd, // SSE4.1
kX86InstIdPmovzxwq, // SSE4.1
kX86InstIdPmuldq, // SSE4.1
kX86InstIdPmulhrsw, // SSSE3
kX86InstIdPmulhuw, // MMX-Ext
kX86InstIdPmulhw, // MMX/SSE2
kX86InstIdPmulld, // SSE4.1
kX86InstIdPmullw, // MMX/SSE2
kX86InstIdPmuludq, // SSE2
kX86InstIdPop, // X86/X64
kX86InstIdPopa, // X86 only
kX86InstIdPopcnt, // SSE4.2
kX86InstIdPopf, // X86/X64
kX86InstIdPor, // MMX/SSE2
kX86InstIdPrefetch, // MMX-Ext/SSE
kX86InstIdPrefetch3dNow, // 3dNow!
kX86InstIdPrefetchw3dNow, // 3dNow!
kX86InstIdPsadbw, // MMX-Ext
kX86InstIdPshufb, // SSSE3
kX86InstIdPshufd, // SSE2
kX86InstIdPshufhw, // SSE2
kX86InstIdPshuflw, // SSE2
kX86InstIdPshufw, // MMX-Ext
kX86InstIdPsignb, // SSSE3
kX86InstIdPsignd, // SSSE3
kX86InstIdPsignw, // SSSE3
kX86InstIdPslld, // MMX/SSE2
kX86InstIdPslldq, // SSE2
kX86InstIdPsllq, // MMX/SSE2
kX86InstIdPsllw, // MMX/SSE2
kX86InstIdPsrad, // MMX/SSE2
kX86InstIdPsraw, // MMX/SSE2
kX86InstIdPsrld, // MMX/SSE2
kX86InstIdPsrldq, // SSE2
kX86InstIdPsrlq, // MMX/SSE2
kX86InstIdPsrlw, // MMX/SSE2
kX86InstIdPsubb, // MMX/SSE2
kX86InstIdPsubd, // MMX/SSE2
kX86InstIdPsubq, // SSE2
kX86InstIdPsubsb, // MMX/SSE2
kX86InstIdPsubsw, // MMX/SSE2
kX86InstIdPsubusb, // MMX/SSE2
kX86InstIdPsubusw, // MMX/SSE2
kX86InstIdPsubw, // MMX/SSE2
kX86InstIdPswapd, // Enhanced 3dNow!
kX86InstIdPtest, // SSE4.1
kX86InstIdPunpckhbw, // MMX/SSE2
kX86InstIdPunpckhdq, // MMX/SSE2
kX86InstIdPunpckhqdq, // SSE2
kX86InstIdPunpckhwd, // MMX/SSE2
kX86InstIdPunpcklbw, // MMX/SSE2
kX86InstIdPunpckldq, // MMX/SSE2
kX86InstIdPunpcklqdq, // SSE2
kX86InstIdPunpcklwd, // MMX/SSE2
kX86InstIdPush, // X86/X64
kX86InstIdPusha, // X86 only
kX86InstIdPushf, // X86/X64
kX86InstIdPxor, // MMX/SSE2
kX86InstIdRcl, // X86/X64
kX86InstIdRcpps, // SSE
kX86InstIdRcpss, // SSE
kX86InstIdRcr, // X86/X64
kX86InstIdRdfsbase, // FSGSBASE (x64)
kX86InstIdRdgsbase, // FSGSBASE (x64)
kX86InstIdRdrand, // RDRAND
kX86InstIdRdtsc, // X86/X64
kX86InstIdRdtscp, // X86/X64
kX86InstIdRepLodsB, // X86/X64 (REP)
kX86InstIdRepLodsD, // X86/X64 (REP)
kX86InstIdRepLodsQ, // X64 only (REP)
kX86InstIdRepLodsW, // X86/X64 (REP)
kX86InstIdRepMovsB, // X86/X64 (REP)
kX86InstIdRepMovsD, // X86/X64 (REP)
kX86InstIdRepMovsQ, // X64 only (REP)
kX86InstIdRepMovsW, // X86/X64 (REP)
kX86InstIdRepStosB, // X86/X64 (REP)
kX86InstIdRepStosD, // X86/X64 (REP)
kX86InstIdRepStosQ, // X64 only (REP)
kX86InstIdRepStosW, // X86/X64 (REP)
kX86InstIdRepeCmpsB, // X86/X64 (REP)
kX86InstIdRepeCmpsD, // X86/X64 (REP)
kX86InstIdRepeCmpsQ, // X64 only (REP)
kX86InstIdRepeCmpsW, // X86/X64 (REP)
kX86InstIdRepeScasB, // X86/X64 (REP)
kX86InstIdRepeScasD, // X86/X64 (REP)
kX86InstIdRepeScasQ, // X64 only (REP)
kX86InstIdRepeScasW, // X86/X64 (REP)
kX86InstIdRepneCmpsB, // X86/X64 (REP)
kX86InstIdRepneCmpsD, // X86/X64 (REP)
kX86InstIdRepneCmpsQ, // X64 only (REP)
kX86InstIdRepneCmpsW, // X86/X64 (REP)
kX86InstIdRepneScasB, // X86/X64 (REP)
kX86InstIdRepneScasD, // X86/X64 (REP)
kX86InstIdRepneScasQ, // X64 only (REP)
kX86InstIdRepneScasW, // X86/X64 (REP)
kX86InstIdRet, // X86/X64
kX86InstIdRol, // X86/X64
kX86InstIdRor, // X86/X64
kX86InstIdRorx, // BMI2
kX86InstIdRoundpd, // SSE4.1
kX86InstIdRoundps, // SSE4.1
kX86InstIdRoundsd, // SSE4.1
kX86InstIdRoundss, // SSE4.1
kX86InstIdRsqrtps, // SSE
kX86InstIdRsqrtss, // SSE
kX86InstIdSahf, // X86/X64 (CPUID NEEDED)
kX86InstIdSal, // X86/X64
kX86InstIdSar, // X86/X64
kX86InstIdSarx, // BMI2
kX86InstIdSbb, // X86/X64
kX86InstIdScasB, // SCAS - X86/X64
kX86InstIdScasD, // SCAS - X86/X64
kX86InstIdScasQ, // SCAS - X64
kX86InstIdScasW, // SCAS - X86/X64
kX86InstIdSeta, // X86/X64 (setcc)
kX86InstIdSetae, // X86/X64 (setcc)
kX86InstIdSetb, // X86/X64 (setcc)
kX86InstIdSetbe, // X86/X64 (setcc)
kX86InstIdSetc, // X86/X64 (setcc)
kX86InstIdSete, // X86/X64 (setcc)
kX86InstIdSetg, // X86/X64 (setcc)
kX86InstIdSetge, // X86/X64 (setcc)
kX86InstIdSetl, // X86/X64 (setcc)
kX86InstIdSetle, // X86/X64 (setcc)
kX86InstIdSetna, // X86/X64 (setcc)
kX86InstIdSetnae, // X86/X64 (setcc)
kX86InstIdSetnb, // X86/X64 (setcc)
kX86InstIdSetnbe, // X86/X64 (setcc)
kX86InstIdSetnc, // X86/X64 (setcc)
kX86InstIdSetne, // X86/X64 (setcc)
kX86InstIdSetng, // X86/X64 (setcc)
kX86InstIdSetnge, // X86/X64 (setcc)
kX86InstIdSetnl, // X86/X64 (setcc)
kX86InstIdSetnle, // X86/X64 (setcc)
kX86InstIdSetno, // X86/X64 (setcc)
kX86InstIdSetnp, // X86/X64 (setcc)
kX86InstIdSetns, // X86/X64 (setcc)
kX86InstIdSetnz, // X86/X64 (setcc)
kX86InstIdSeto, // X86/X64 (setcc)
kX86InstIdSetp, // X86/X64 (setcc)
kX86InstIdSetpe, // X86/X64 (setcc)
kX86InstIdSetpo, // X86/X64 (setcc)
kX86InstIdSets, // X86/X64 (setcc)
kX86InstIdSetz, // X86/X64 (setcc)
kX86InstIdSfence, // MMX-Ext/SSE
kX86InstIdShl, // X86/X64
kX86InstIdShld, // X86/X64
kX86InstIdShlx, // BMI2
kX86InstIdShr, // X86/X64
kX86InstIdShrd, // X86/X64
kX86InstIdShrx, // BMI2
kX86InstIdShufpd, // SSE2
kX86InstIdShufps, // SSE
kX86InstIdSqrtpd, // SSE2
kX86InstIdSqrtps, // SSE
kX86InstIdSqrtsd, // SSE2
kX86InstIdSqrtss, // SSE
kX86InstIdStc, // X86/X64
kX86InstIdStd, // X86/X64
kX86InstIdStmxcsr, // SSE
kX86InstIdStosB, // STOS - X86/X64
kX86InstIdStosD, // STOS - X86/X64
kX86InstIdStosQ, // STOS - X64
kX86InstIdStosW, // STOS - X86/X64
kX86InstIdSub, // X86/X64
kX86InstIdSubpd, // SSE2
kX86InstIdSubps, // SSE
kX86InstIdSubsd, // SSE2
kX86InstIdSubss, // SSE
kX86InstIdTest, // X86/X64
kX86InstIdTzcnt, // TZCNT
kX86InstIdUcomisd, // SSE2
kX86InstIdUcomiss, // SSE
kX86InstIdUd2, // X86/X64
kX86InstIdUnpckhpd, // SSE2
kX86InstIdUnpckhps, // SSE
kX86InstIdUnpcklpd, // SSE2
kX86InstIdUnpcklps, // SSE
kX86InstIdVaddpd, // AVX
kX86InstIdVaddps, // AVX
kX86InstIdVaddsd, // AVX
kX86InstIdVaddss, // AVX
kX86InstIdVaddsubpd, // AVX
kX86InstIdVaddsubps, // AVX
kX86InstIdVaesdec, // AVX+AESNI
kX86InstIdVaesdeclast, // AVX+AESNI
kX86InstIdVaesenc, // AVX+AESNI
kX86InstIdVaesenclast, // AVX+AESNI
kX86InstIdVaesimc, // AVX+AESNI
kX86InstIdVaeskeygenassist,// AVX+AESNI
kX86InstIdVandnpd, // AVX
kX86InstIdVandnps, // AVX
kX86InstIdVandpd, // AVX
kX86InstIdVandps, // AVX
kX86InstIdVblendpd, // AVX
kX86InstIdVblendps, // AVX
kX86InstIdVblendvpd, // AVX
kX86InstIdVblendvps, // AVX
kX86InstIdVbroadcastf128, // AVX
kX86InstIdVbroadcasti128, // AVX2
kX86InstIdVbroadcastsd, // AVX/AVX2
kX86InstIdVbroadcastss, // AVX/AVX2
kX86InstIdVcmppd, // AVX
kX86InstIdVcmpps, // AVX
kX86InstIdVcmpsd, // AVX
kX86InstIdVcmpss, // AVX
kX86InstIdVcomisd, // AVX
kX86InstIdVcomiss, // AVX
kX86InstIdVcvtdq2pd, // AVX
kX86InstIdVcvtdq2ps, // AVX
kX86InstIdVcvtpd2dq, // AVX
kX86InstIdVcvtpd2ps, // AVX
kX86InstIdVcvtph2ps, // F16C
kX86InstIdVcvtps2dq, // AVX
kX86InstIdVcvtps2pd, // AVX
kX86InstIdVcvtps2ph, // F16C
kX86InstIdVcvtsd2si, // AVX
kX86InstIdVcvtsd2ss, // AVX
kX86InstIdVcvtsi2sd, // AVX
kX86InstIdVcvtsi2ss, // AVX
kX86InstIdVcvtss2sd, // AVX
kX86InstIdVcvtss2si, // AVX
kX86InstIdVcvttpd2dq, // AVX
kX86InstIdVcvttps2dq, // AVX
kX86InstIdVcvttsd2si, // AVX
kX86InstIdVcvttss2si, // AVX
kX86InstIdVdivpd, // AVX
kX86InstIdVdivps, // AVX
kX86InstIdVdivsd, // AVX
kX86InstIdVdivss, // AVX
kX86InstIdVdppd, // AVX
kX86InstIdVdpps, // AVX
kX86InstIdVextractf128, // AVX
kX86InstIdVextracti128, // AVX2
kX86InstIdVextractps, // AVX
kX86InstIdVfmadd132pd, // FMA3
kX86InstIdVfmadd132ps, // FMA3
kX86InstIdVfmadd132sd, // FMA3
kX86InstIdVfmadd132ss, // FMA3
kX86InstIdVfmadd213pd, // FMA3
kX86InstIdVfmadd213ps, // FMA3
kX86InstIdVfmadd213sd, // FMA3
kX86InstIdVfmadd213ss, // FMA3
kX86InstIdVfmadd231pd, // FMA3
kX86InstIdVfmadd231ps, // FMA3
kX86InstIdVfmadd231sd, // FMA3
kX86InstIdVfmadd231ss, // FMA3
kX86InstIdVfmaddpd, // FMA4
kX86InstIdVfmaddps, // FMA4
kX86InstIdVfmaddsd, // FMA4
kX86InstIdVfmaddss, // FMA4
kX86InstIdVfmaddsub132pd, // FMA3
kX86InstIdVfmaddsub132ps, // FMA3
kX86InstIdVfmaddsub213pd, // FMA3
kX86InstIdVfmaddsub213ps, // FMA3
kX86InstIdVfmaddsub231pd, // FMA3
kX86InstIdVfmaddsub231ps, // FMA3
kX86InstIdVfmaddsubpd, // FMA4
kX86InstIdVfmaddsubps, // FMA4
kX86InstIdVfmsub132pd, // FMA3
kX86InstIdVfmsub132ps, // FMA3
kX86InstIdVfmsub132sd, // FMA3
kX86InstIdVfmsub132ss, // FMA3
kX86InstIdVfmsub213pd, // FMA3
kX86InstIdVfmsub213ps, // FMA3
kX86InstIdVfmsub213sd, // FMA3
kX86InstIdVfmsub213ss, // FMA3
kX86InstIdVfmsub231pd, // FMA3
kX86InstIdVfmsub231ps, // FMA3
kX86InstIdVfmsub231sd, // FMA3
kX86InstIdVfmsub231ss, // FMA3
kX86InstIdVfmsubadd132pd, // FMA3
kX86InstIdVfmsubadd132ps, // FMA3
kX86InstIdVfmsubadd213pd, // FMA3
kX86InstIdVfmsubadd213ps, // FMA3
kX86InstIdVfmsubadd231pd, // FMA3
kX86InstIdVfmsubadd231ps, // FMA3
kX86InstIdVfmsubaddpd, // FMA4
kX86InstIdVfmsubaddps, // FMA4
kX86InstIdVfmsubpd, // FMA4
kX86InstIdVfmsubps, // FMA4
kX86InstIdVfmsubsd, // FMA4
kX86InstIdVfmsubss, // FMA4
kX86InstIdVfnmadd132pd, // FMA3
kX86InstIdVfnmadd132ps, // FMA3
kX86InstIdVfnmadd132sd, // FMA3
kX86InstIdVfnmadd132ss, // FMA3
kX86InstIdVfnmadd213pd, // FMA3
kX86InstIdVfnmadd213ps, // FMA3
kX86InstIdVfnmadd213sd, // FMA3
kX86InstIdVfnmadd213ss, // FMA3
kX86InstIdVfnmadd231pd, // FMA3
kX86InstIdVfnmadd231ps, // FMA3
kX86InstIdVfnmadd231sd, // FMA3
kX86InstIdVfnmadd231ss, // FMA3
kX86InstIdVfnmaddpd, // FMA4
kX86InstIdVfnmaddps, // FMA4
kX86InstIdVfnmaddsd, // FMA4
kX86InstIdVfnmaddss, // FMA4
kX86InstIdVfnmsub132pd, // FMA3
kX86InstIdVfnmsub132ps, // FMA3
kX86InstIdVfnmsub132sd, // FMA3
kX86InstIdVfnmsub132ss, // FMA3
kX86InstIdVfnmsub213pd, // FMA3
kX86InstIdVfnmsub213ps, // FMA3
kX86InstIdVfnmsub213sd, // FMA3
kX86InstIdVfnmsub213ss, // FMA3
kX86InstIdVfnmsub231pd, // FMA3
kX86InstIdVfnmsub231ps, // FMA3
kX86InstIdVfnmsub231sd, // FMA3
kX86InstIdVfnmsub231ss, // FMA3
kX86InstIdVfnmsubpd, // FMA4
kX86InstIdVfnmsubps, // FMA4
kX86InstIdVfnmsubsd, // FMA4
kX86InstIdVfnmsubss, // FMA4
kX86InstIdVfrczpd, // XOP
kX86InstIdVfrczps, // XOP
kX86InstIdVfrczsd, // XOP
kX86InstIdVfrczss, // XOP
kX86InstIdVgatherdpd, // AVX2
kX86InstIdVgatherdps, // AVX2
kX86InstIdVgatherqpd, // AVX2
kX86InstIdVgatherqps, // AVX2
kX86InstIdVhaddpd, // AVX
kX86InstIdVhaddps, // AVX
kX86InstIdVhsubpd, // AVX
kX86InstIdVhsubps, // AVX
kX86InstIdVinsertf128, // AVX
kX86InstIdVinserti128, // AVX2
kX86InstIdVinsertps, // AVX
kX86InstIdVlddqu, // AVX
kX86InstIdVldmxcsr, // AVX
kX86InstIdVmaskmovdqu, // AVX
kX86InstIdVmaskmovpd, // AVX
kX86InstIdVmaskmovps, // AVX
kX86InstIdVmaxpd, // AVX
kX86InstIdVmaxps, // AVX
kX86InstIdVmaxsd, // AVX
kX86InstIdVmaxss, // AVX
kX86InstIdVminpd, // AVX
kX86InstIdVminps, // AVX
kX86InstIdVminsd, // AVX
kX86InstIdVminss, // AVX
kX86InstIdVmovapd, // AVX
kX86InstIdVmovaps, // AVX
kX86InstIdVmovd, // AVX
kX86InstIdVmovddup, // AVX
kX86InstIdVmovdqa, // AVX
kX86InstIdVmovdqu, // AVX
kX86InstIdVmovhlps, // AVX
kX86InstIdVmovhpd, // AVX
kX86InstIdVmovhps, // AVX
kX86InstIdVmovlhps, // AVX
kX86InstIdVmovlpd, // AVX
kX86InstIdVmovlps, // AVX
kX86InstIdVmovmskpd, // AVX
kX86InstIdVmovmskps, // AVX
kX86InstIdVmovntdq, // AVX
kX86InstIdVmovntdqa, // AVX/AVX2
kX86InstIdVmovntpd, // AVX
kX86InstIdVmovntps, // AVX
kX86InstIdVmovq, // AVX
kX86InstIdVmovsd, // AVX
kX86InstIdVmovshdup, // AVX
kX86InstIdVmovsldup, // AVX
kX86InstIdVmovss, // AVX
kX86InstIdVmovupd, // AVX
kX86InstIdVmovups, // AVX
kX86InstIdVmpsadbw, // AVX/AVX2
kX86InstIdVmulpd, // AVX
kX86InstIdVmulps, // AVX
kX86InstIdVmulsd, // AVX
kX86InstIdVmulss, // AVX
kX86InstIdVorpd, // AVX
kX86InstIdVorps, // AVX
kX86InstIdVpabsb, // AVX2
kX86InstIdVpabsd, // AVX2
kX86InstIdVpabsw, // AVX2
kX86InstIdVpackssdw, // AVX2
kX86InstIdVpacksswb, // AVX2
kX86InstIdVpackusdw, // AVX2
kX86InstIdVpackuswb, // AVX2
kX86InstIdVpaddb, // AVX2
kX86InstIdVpaddd, // AVX2
kX86InstIdVpaddq, // AVX2
kX86InstIdVpaddsb, // AVX2
kX86InstIdVpaddsw, // AVX2
kX86InstIdVpaddusb, // AVX2
kX86InstIdVpaddusw, // AVX2
kX86InstIdVpaddw, // AVX2
kX86InstIdVpalignr, // AVX2
kX86InstIdVpand, // AVX2
kX86InstIdVpandn, // AVX2
kX86InstIdVpavgb, // AVX2
kX86InstIdVpavgw, // AVX2
kX86InstIdVpblendd, // AVX2
kX86InstIdVpblendvb, // AVX2
kX86InstIdVpblendw, // AVX2
kX86InstIdVpbroadcastb, // AVX2
kX86InstIdVpbroadcastd, // AVX2
kX86InstIdVpbroadcastq, // AVX2
kX86InstIdVpbroadcastw, // AVX2
kX86InstIdVpclmulqdq, // AVX+PCLMULQDQ
kX86InstIdVpcmov, // XOP
kX86InstIdVpcmpeqb, // AVX2
kX86InstIdVpcmpeqd, // AVX2
kX86InstIdVpcmpeqq, // AVX2
kX86InstIdVpcmpeqw, // AVX2
kX86InstIdVpcmpestri, // AVX
kX86InstIdVpcmpestrm, // AVX
kX86InstIdVpcmpgtb, // AVX2
kX86InstIdVpcmpgtd, // AVX2
kX86InstIdVpcmpgtq, // AVX2
kX86InstIdVpcmpgtw, // AVX2
kX86InstIdVpcmpistri, // AVX
kX86InstIdVpcmpistrm, // AVX
kX86InstIdVpcomb, // XOP
kX86InstIdVpcomd, // XOP
kX86InstIdVpcomq, // XOP
kX86InstIdVpcomub, // XOP
kX86InstIdVpcomud, // XOP
kX86InstIdVpcomuq, // XOP
kX86InstIdVpcomuw, // XOP
kX86InstIdVpcomw, // XOP
kX86InstIdVperm2f128, // AVX
kX86InstIdVperm2i128, // AVX2
kX86InstIdVpermd, // AVX2
kX86InstIdVpermil2pd, // XOP
kX86InstIdVpermil2ps, // XOP
kX86InstIdVpermilpd, // AVX
kX86InstIdVpermilps, // AVX
kX86InstIdVpermpd, // AVX2
kX86InstIdVpermps, // AVX2
kX86InstIdVpermq, // AVX2
kX86InstIdVpextrb, // AVX
kX86InstIdVpextrd, // AVX
kX86InstIdVpextrq, // AVX (x64 only)
kX86InstIdVpextrw, // AVX
kX86InstIdVpgatherdd, // AVX2
kX86InstIdVpgatherdq, // AVX2
kX86InstIdVpgatherqd, // AVX2
kX86InstIdVpgatherqq, // AVX2
kX86InstIdVphaddbd, // XOP
kX86InstIdVphaddbq, // XOP
kX86InstIdVphaddbw, // XOP
kX86InstIdVphaddd, // AVX2
kX86InstIdVphadddq, // XOP
kX86InstIdVphaddsw, // AVX2
kX86InstIdVphaddubd, // XOP
kX86InstIdVphaddubq, // XOP
kX86InstIdVphaddubw, // XOP
kX86InstIdVphaddudq, // XOP
kX86InstIdVphadduwd, // XOP
kX86InstIdVphadduwq, // XOP
kX86InstIdVphaddw, // AVX2
kX86InstIdVphaddwd, // XOP
kX86InstIdVphaddwq, // XOP
kX86InstIdVphminposuw, // AVX
kX86InstIdVphsubbw, // XOP
kX86InstIdVphsubd, // AVX2
kX86InstIdVphsubdq, // XOP
kX86InstIdVphsubsw, // AVX2
kX86InstIdVphsubw, // AVX2
kX86InstIdVphsubwd, // XOP
kX86InstIdVpinsrb, // AVX
kX86InstIdVpinsrd, // AVX
kX86InstIdVpinsrq, // AVX (x64 only)
kX86InstIdVpinsrw, // AVX
kX86InstIdVpmacsdd, // XOP
kX86InstIdVpmacsdqh, // XOP
kX86InstIdVpmacsdql, // XOP
kX86InstIdVpmacssdd, // XOP
kX86InstIdVpmacssdqh, // XOP
kX86InstIdVpmacssdql, // XOP
kX86InstIdVpmacsswd, // XOP
kX86InstIdVpmacssww, // XOP
kX86InstIdVpmacswd, // XOP
kX86InstIdVpmacsww, // XOP
kX86InstIdVpmadcsswd, // XOP
kX86InstIdVpmadcswd, // XOP
kX86InstIdVpmaddubsw, // AVX/AVX2
kX86InstIdVpmaddwd, // AVX/AVX2
kX86InstIdVpmaskmovd, // AVX2
kX86InstIdVpmaskmovq, // AVX2
kX86InstIdVpmaxsb, // AVX/AVX2
kX86InstIdVpmaxsd, // AVX/AVX2
kX86InstIdVpmaxsw, // AVX/AVX2
kX86InstIdVpmaxub, // AVX/AVX2
kX86InstIdVpmaxud, // AVX/AVX2
kX86InstIdVpmaxuw, // AVX/AVX2
kX86InstIdVpminsb, // AVX/AVX2
kX86InstIdVpminsd, // AVX/AVX2
kX86InstIdVpminsw, // AVX/AVX2
kX86InstIdVpminub, // AVX/AVX2
kX86InstIdVpminud, // AVX/AVX2
kX86InstIdVpminuw, // AVX/AVX2
kX86InstIdVpmovmskb, // AVX/AVX2
kX86InstIdVpmovsxbd, // AVX/AVX2
kX86InstIdVpmovsxbq, // AVX/AVX2
kX86InstIdVpmovsxbw, // AVX/AVX2
kX86InstIdVpmovsxdq, // AVX/AVX2
kX86InstIdVpmovsxwd, // AVX/AVX2
kX86InstIdVpmovsxwq, // AVX/AVX2
kX86InstIdVpmovzxbd, // AVX/AVX2
kX86InstIdVpmovzxbq, // AVX/AVX2
kX86InstIdVpmovzxbw, // AVX/AVX2
kX86InstIdVpmovzxdq, // AVX/AVX2
kX86InstIdVpmovzxwd, // AVX/AVX2
kX86InstIdVpmovzxwq, // AVX/AVX2
kX86InstIdVpmuldq, // AVX/AVX2
kX86InstIdVpmulhrsw, // AVX/AVX2
kX86InstIdVpmulhuw, // AVX/AVX2
kX86InstIdVpmulhw, // AVX/AVX2
kX86InstIdVpmulld, // AVX/AVX2
kX86InstIdVpmullw, // AVX/AVX2
kX86InstIdVpmuludq, // AVX/AVX2
kX86InstIdVpor, // AVX/AVX2
kX86InstIdVpperm, // XOP
kX86InstIdVprotb, // XOP
kX86InstIdVprotd, // XOP
kX86InstIdVprotq, // XOP
kX86InstIdVprotw, // XOP
kX86InstIdVpsadbw, // AVX/AVX2
kX86InstIdVpshab, // XOP
kX86InstIdVpshad, // XOP
kX86InstIdVpshaq, // XOP
kX86InstIdVpshaw, // XOP
kX86InstIdVpshlb, // XOP
kX86InstIdVpshld, // XOP
kX86InstIdVpshlq, // XOP
kX86InstIdVpshlw, // XOP
kX86InstIdVpshufb, // AVX/AVX2
kX86InstIdVpshufd, // AVX/AVX2
kX86InstIdVpshufhw, // AVX/AVX2
kX86InstIdVpshuflw, // AVX/AVX2
kX86InstIdVpsignb, // AVX/AVX2
kX86InstIdVpsignd, // AVX/AVX2
kX86InstIdVpsignw, // AVX/AVX2
kX86InstIdVpslld, // AVX/AVX2
kX86InstIdVpslldq, // AVX/AVX2
kX86InstIdVpsllq, // AVX/AVX2
kX86InstIdVpsllvd, // AVX2
kX86InstIdVpsllvq, // AVX2
kX86InstIdVpsllw, // AVX/AVX2
kX86InstIdVpsrad, // AVX/AVX2
kX86InstIdVpsravd, // AVX2
kX86InstIdVpsraw, // AVX/AVX2
kX86InstIdVpsrld, // AVX/AVX2
kX86InstIdVpsrldq, // AVX/AVX2
kX86InstIdVpsrlq, // AVX/AVX2
kX86InstIdVpsrlvd, // AVX2
kX86InstIdVpsrlvq, // AVX2
kX86InstIdVpsrlw, // AVX/AVX2
kX86InstIdVpsubb, // AVX/AVX2
kX86InstIdVpsubd, // AVX/AVX2
kX86InstIdVpsubq, // AVX/AVX2
kX86InstIdVpsubsb, // AVX/AVX2
kX86InstIdVpsubsw, // AVX/AVX2
kX86InstIdVpsubusb, // AVX/AVX2
kX86InstIdVpsubusw, // AVX/AVX2
kX86InstIdVpsubw, // AVX/AVX2
kX86InstIdVptest, // AVX
kX86InstIdVpunpckhbw, // AVX/AVX2
kX86InstIdVpunpckhdq, // AVX/AVX2
kX86InstIdVpunpckhqdq, // AVX/AVX2
kX86InstIdVpunpckhwd, // AVX/AVX2
kX86InstIdVpunpcklbw, // AVX/AVX2
kX86InstIdVpunpckldq, // AVX/AVX2
kX86InstIdVpunpcklqdq, // AVX/AVX2
kX86InstIdVpunpcklwd, // AVX/AVX2
kX86InstIdVpxor, // AVX/AVX2
kX86InstIdVrcpps, // AVX
kX86InstIdVrcpss, // AVX
kX86InstIdVroundpd, // AVX
kX86InstIdVroundps, // AVX
kX86InstIdVroundsd, // AVX
kX86InstIdVroundss, // AVX
kX86InstIdVrsqrtps, // AVX
kX86InstIdVrsqrtss, // AVX
kX86InstIdVshufpd, // AVX
kX86InstIdVshufps, // AVX
kX86InstIdVsqrtpd, // AVX
kX86InstIdVsqrtps, // AVX
kX86InstIdVsqrtsd, // AVX
kX86InstIdVsqrtss, // AVX
kX86InstIdVstmxcsr, // AVX
kX86InstIdVsubpd, // AVX
kX86InstIdVsubps, // AVX
kX86InstIdVsubsd, // AVX
kX86InstIdVsubss, // AVX
kX86InstIdVtestpd, // AVX
kX86InstIdVtestps, // AVX
kX86InstIdVucomisd, // AVX
kX86InstIdVucomiss, // AVX
kX86InstIdVunpckhpd, // AVX
kX86InstIdVunpckhps, // AVX
kX86InstIdVunpcklpd, // AVX
kX86InstIdVunpcklps, // AVX
kX86InstIdVxorpd, // AVX
kX86InstIdVxorps, // AVX
kX86InstIdVzeroall, // AVX
kX86InstIdVzeroupper, // AVX
kX86InstIdWrfsbase, // FSGSBASE (x64)
kX86InstIdWrgsbase, // FSGSBASE (x64)
kX86InstIdXadd, // X86/X64 (i486+)
kX86InstIdXchg, // X86/X64
kX86InstIdXgetbv, // XSAVE
kX86InstIdXor, // X86/X64
kX86InstIdXorpd, // SSE2
kX86InstIdXorps, // SSE
kX86InstIdXrstor, // XSAVE
kX86InstIdXrstor64, // XSAVE
kX86InstIdXsave, // XSAVE
kX86InstIdXsave64, // XSAVE
kX86InstIdXsaveopt, // XSAVE
kX86InstIdXsaveopt64, // XSAVE
kX86InstIdXsetbv, // XSAVE
_kX86InstIdCount,
_kX86InstIdCmovcc = kX86InstIdCmova,
_kX86InstIdJcc = kX86InstIdJa,
_kX86InstIdSetcc = kX86InstIdSeta,
_kX86InstIdJbegin = kX86InstIdJa,
_kX86InstIdJend = kX86InstIdJmp
};
// ============================================================================
// [asmjit::X86InstOptions]
// ============================================================================
//! X86/X64 instruction emit options, mainly for internal purposes.
ASMJIT_ENUM(X86InstOptions) {
//! Emit instruction with LOCK prefix.
//!
//! If this option is used and instruction doesn't support LOCK prefix an
//! invalid instruction error is generated.
kX86InstOptionLock = 0x00000010,
//! Force REX prefix (X64).
//!
//! This option should be used carefully as there are combinations of
//! instructions and their operands that are not encodable. The REX prefix
//! can't be used together with AH, BH, CH, and DH registers. AsmJit reports
//! \ref kErrorIllegalInstruction in such case.
kX86InstOptionRex = 0x00000040,
//! \internal
//!
//! Reserved by `X86Assembler`, do not use!
_kX86InstOptionNoRex = 0x00000080,
//! Force 3-byte VEX prefix even if the instruction is encodable by 2-byte
//! VEX prefix (AVX).
//!
//! Ignored if the instruction is not AVX or `kX86InstOptionEVEX` is used.
kX86InstOptionVex3 = 0x00000100,
//! Force 4-byte EVEX prefix even if the instruction is encodable by using
//! VEX prefix. Please note that all higher bits from `kX86InstOptionEvex`
//! are reserved for EVEX and forces EVEX encoding to be used implicitly.
kX86InstOptionEvex = 0x00010000,
//! Use zeroing instead of merging (AVX512+).
kX86InstOptionEvexZero = 0x00020000,
//! Broadcast one element to all other elements (AVX512+).
kX86InstOptionEvexOneN = 0x00040000,
//! Suppress all exceptions (AVX512+).
kX86InstOptionEvexSae = 0x00080000,
//! Static rounding mode `round-to-nearest` (even) and `SAE` (AVX512+).
kX86InstOptionEvexRnSae = 0x00100000,
//! Static rounding mode `round-down` (toward -inf) and `SAE` (AVX512+).
kX86InstOptionEvexRdSae = 0x00200000,
//! Static rounding mode `round-up` (toward +inf) and `SAE` (AVX512+).
kX86InstOptionEvexRuSae = 0x00400000,
//! Static rounding mode `round-toward-zero` (truncate) and `SAE` (AVX512+).
kX86InstOptionEvexRzSae = 0x00800000
};
// ============================================================================
// [asmjit::X86InstEncodingId]
// ============================================================================
//! \internal
//!
//! X86/X64 instruction groups.
//!
//! This group is specific to AsmJit and only used by `X86Assembler`.
ASMJIT_ENUM(X86InstEncodingId) {
//! Never used.
kX86InstEncodingIdNone = 0,
kX86InstEncodingIdX86Op,
kX86InstEncodingIdX86Op_66H,
kX86InstEncodingIdX86Rm,
kX86InstEncodingIdX86Rm_B,
kX86InstEncodingIdX86RmReg,
kX86InstEncodingIdX86RegRm,
kX86InstEncodingIdX86M,
//! Adc/Add/And/Cmp/Or/Sbb/Sub/Xor.
kX86InstEncodingIdX86Arith,
//! Bswap.
kX86InstEncodingIdX86BSwap,
//! Bt/Btc/Btr/Bts.
kX86InstEncodingIdX86BTest,
//! Call.
kX86InstEncodingIdX86Call,
//! Enter.
kX86InstEncodingIdX86Enter,
//! Imul.
kX86InstEncodingIdX86Imul,
//! Inc/Dec.
kX86InstEncodingIdX86IncDec,
//! Int.
kX86InstEncodingIdX86Int,
//! Jcc.
kX86InstEncodingIdX86Jcc,
//! Jcxz/Jecxz/Jrcxz.
kX86InstEncodingIdX86Jecxz,
//! Jmp.
kX86InstEncodingIdX86Jmp,
//! Lea.
kX86InstEncodingIdX86Lea,
//! Mov.
kX86InstEncodingIdX86Mov,
//! Movsx/Movzx.
kX86InstEncodingIdX86MovSxZx,
//! Movsxd.
kX86InstEncodingIdX86MovSxd,
//! Mov having absolute memory operand (x86/x64).
kX86InstEncodingIdX86MovPtr,
//! Push.
kX86InstEncodingIdX86Push,
//! Pop.
kX86InstEncodingIdX86Pop,
//! Rep/Repe/Repne LodsX/MovsX/StosX/CmpsX/ScasX.
kX86InstEncodingIdX86Rep,
//! Ret.
kX86InstEncodingIdX86Ret,
//! Rcl/Rcr/Rol/Ror/Sal/Sar/Shl/Shr.
kX86InstEncodingIdX86Rot,
//! Setcc.
kX86InstEncodingIdX86Set,
//! Shld/Rhrd.
kX86InstEncodingIdX86Shlrd,
//! Test.
kX86InstEncodingIdX86Test,
//! Xadd.
kX86InstEncodingIdX86Xadd,
//! Xchg.
kX86InstEncodingIdX86Xchg,
//! Fincstp/Finit/FldX/Fnclex/Fninit/Fnop/Fpatan/Fprem/Fprem1/Fptan/Frndint/Fscale/Fsin/Fsincos/Fsqrt/Ftst/Fucompp/Fxam/Fxtract/Fyl2x/Fyl2xp1.
kX86InstEncodingIdFpuOp,
//! Fadd/Fdiv/Fdivr/Fmul/Fsub/Fsubr.
kX86InstEncodingIdFpuArith,
//! Fcom/Fcomp.
kX86InstEncodingIdFpuCom,
//! Fld/Fst/Fstp.
kX86InstEncodingIdFpuFldFst,
//! Fiadd/Ficom/Ficomp/Fidiv/Fidivr/Fild/Fimul/Fist/Fistp/Fisttp/Fisub/Fisubr.
kX86InstEncodingIdFpuM,
//! Fcmov/Fcomi/Fcomip/Ffree/Fucom/Fucomi/Fucomip/Fucomp/Fxch.
kX86InstEncodingIdFpuR,
//! Faddp/Fdivp/Fdivrp/Fmulp/Fsubp/Fsubrp.
kX86InstEncodingIdFpuRDef,
//! Fnstsw/Fstsw.
kX86InstEncodingIdFpuStsw,
//! Mm/Xmm instruction.
kX86InstEncodingIdExtRm,
//! Mm/Xmm instruction (propagates 66H if the instruction uses Xmm register).
kX86InstEncodingIdExtRm_P,
//! Mm/Xmm instruction (propagates REX.W if GPQ is used).
kX86InstEncodingIdExtRm_Q,
//! Mm/Xmm instruction (propagates 66H and REX.W).
kX86InstEncodingIdExtRm_PQ,
//! Mm/Xmm instruction having Rm/Ri encodings.
kX86InstEncodingIdExtRmRi,
//! Mm/Xmm instruction having Rm/Ri encodings (propagates 66H if the instruction uses Xmm register).
kX86InstEncodingIdExtRmRi_P,
//! Mm/Xmm instruction having Rmi encoding.
kX86InstEncodingIdExtRmi,
//! Mm/Xmm instruction having Rmi encoding (propagates 66H if the instruction uses Xmm register).
kX86InstEncodingIdExtRmi_P,
//! Crc32.
kX86InstEncodingIdExtCrc,
//! Pextrb/Pextrw/Pextrd/Pextrq/Extractps.
kX86InstEncodingIdExtExtract,
//! Lfence/Mfence/Sfence.
kX86InstEncodingIdExtFence,
//! Mov Mm/Xmm.
//!
//! 0x66 prefix must be set manually in opcodes.
//!
//! - Primary opcode is used for instructions in (X)Mm <- (X)Mm/X86Mem format,
//! - Secondary opcode is used for instructions in (X)Mm/X86Mem <- (X)Mm format.
kX86InstEncodingIdExtMov,
//! Mov Mm/Xmm.
kX86InstEncodingIdExtMovNoRexW,
//! Movbe.
kX86InstEncodingIdExtMovBe,
//! Movd.
kX86InstEncodingIdExtMovD,
//! Movq.
kX86InstEncodingIdExtMovQ,
//! Prefetch.
kX86InstEncodingIdExtPrefetch,
//! Extrq (SSE4a).
kX86InstEncodingIdExtExtrq,
//! Insrq (SSE4a).
kX86InstEncodingIdExtInsertq,
//! 3dNow instruction.
kX86InstEncodingId3dNow,
//! AVX instruction without operands.
kX86InstEncodingIdAvxOp,
//! AVX instruction encoded as 'M'.
kX86InstEncodingIdAvxM,
//! AVX instruction encoded as 'MR'.
kX86InstEncodingIdAvxMr,
//! AVX instruction encoded as 'MR' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdAvxMr_P,
//! AVX instruction encoded as 'MRI'.
kX86InstEncodingIdAvxMri,
//! AVX instruction encoded as 'MRI' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdAvxMri_P,
//! AVX instruction encoded as 'RM'.
kX86InstEncodingIdAvxRm,
//! AVX instruction encoded as 'RM' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdAvxRm_P,
//! AVX instruction encoded as 'RMI'.
kX86InstEncodingIdAvxRmi,
//! AVX instruction encoded as 'RMI' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdAvxRmi_P,
//! AVX instruction encoded as 'RVM'.
kX86InstEncodingIdAvxRvm,
//! AVX instruction encoded as 'RVM' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdAvxRvm_P,
//! AVX instruction encoded as 'RVMR'.
kX86InstEncodingIdAvxRvmr,
//! AVX instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdAvxRvmr_P,
//! AVX instruction encoded as 'RVMI'.
kX86InstEncodingIdAvxRvmi,
//! AVX instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdAvxRvmi_P,
//! AVX instruction encoded as 'RMV'.
kX86InstEncodingIdAvxRmv,
//! AVX instruction encoded as 'RMVI'.
kX86InstEncodingIdAvxRmvi,
//! AVX instruction encoded as 'RM' or 'MR'.
kX86InstEncodingIdAvxRmMr,
//! AVX instruction encoded as 'RM' or 'MR' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdAvxRmMr_P,
//! AVX instruction encoded as 'RVM' or 'RMI'.
kX86InstEncodingIdAvxRvmRmi,
//! AVX instruction encoded as 'RVM' or 'RMI' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdAvxRvmRmi_P,
//! AVX instruction encoded as 'RVM' or 'MR'.
kX86InstEncodingIdAvxRvmMr,
//! AVX instruction encoded as 'RVM' or 'MVR'.
kX86InstEncodingIdAvxRvmMvr,
//! AVX instruction encoded as 'RVM' or 'MVR' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdAvxRvmMvr_P,
//! AVX instruction encoded as 'RVM' or 'VMI'.
kX86InstEncodingIdAvxRvmVmi,
//! AVX instruction encoded as 'RVM' or 'VMI' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdAvxRvmVmi_P,
//! AVX instruction encoded as 'VM'.
kX86InstEncodingIdAvxVm,
//! AVX instruction encoded as 'VMI'.
kX86InstEncodingIdAvxVmi,
//! AVX instruction encoded as 'VMI' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdAvxVmi_P,
//! AVX instruction encoded as 'RVRM' or 'RVMR'.
kX86InstEncodingIdAvxRvrmRvmr,
//! AVX instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdAvxRvrmRvmr_P,
//! Vmovss/Vmovsd.
kX86InstEncodingIdAvxMovSsSd,
//! AVX2 gather family instructions (VSIB).
kX86InstEncodingIdAvxGather,
//! AVX2 gather family instructions (VSIB), differs only in mem operand.
kX86InstEncodingIdAvxGatherEx,
//! FMA4 instruction in form [R, R, R/M, R/M].
kX86InstEncodingIdFma4,
//! FMA4 instruction in form [R, R, R/M, R/M] (Propagates AVX.L if Ymm used).
kX86InstEncodingIdFma4_P,
//! XOP instruction encoded as 'RM'.
kX86InstEncodingIdXopRm,
//! XOP instruction encoded as 'RM' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdXopRm_P,
//! XOP instruction encoded as 'RVM' or 'RMV'.
kX86InstEncodingIdXopRvmRmv,
//! XOP instruction encoded as 'RVM' or 'RMI'.
kX86InstEncodingIdXopRvmRmi,
//! XOP instruction encoded as 'RVMR'.
kX86InstEncodingIdXopRvmr,
//! XOP instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdXopRvmr_P,
//! XOP instruction encoded as 'RVMI'.
kX86InstEncodingIdXopRvmi,
//! XOP instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdXopRvmi_P,
//! XOP instruction encoded as 'RVRM' or 'RVMR'.
kX86InstEncodingIdXopRvrmRvmr,
//! XOP instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used).
kX86InstEncodingIdXopRvrmRvmr_P,
//! Count of X86 instruction groups.
_kX86InstEncodingIdCount
};
// ============================================================================
// [asmjit::X86InstOpCodeFlags]
// ============================================================================
//! \internal
//!
//! X86/X64 Instruction opcode encoding used by asmjit 'X86InstInfo' table.
//!
//! This schema is AsmJit specific and has been designed to allow encoding of
//! all X86 instructions available. X86, MMX, and SSE+ instructions always use
//! `MMMMM` and `PP` fields, which are encoded to corresponding prefixes needed
//! by X86 or SIMD instructions. AVX+ instructions embed `MMMMM` and `PP` fields
//! in a VEX prefix.
//!
//! The instruction opcode definition uses 1 or 2 bytes as an opcode value. 1
//! byte is needed by most of the instructions, 2 bytes are only used by legacy
//! X87-FPU instructions. This means that a second byte is free to by used by
//! AVX and AVX-512 instructions.
//!
//! The fields description:
//!
//! - `MMMMM` field is used to encode prefixes needed by the instruction or as
//! a part of VEX/EVEX prefix.
//!
//! - `PP` field is used to encode prefixes needed by the instruction or as a
//! part of VEX/EVEX prefix.
//!
//! - `L` field is used exclusively by AVX+ and AVX512+ instruction sets. It
//! describes vector size, which is 128-bit for Xmm register `L_128`, 256
//! for Ymm register `L_256` and 512-bit for Zmm register `L_512`. The `L`
//! field is omitted in case that instruction supports multiple vector lengths,
//! however, if the instruction requires specific `L` value it's specified as
//! a part of the opcode.
//!
//! - `W` field is the most complicated. It was added by 64-bit architecture
//! to promote default operation width (instructions that perform 32-bit
//! operation by default require to override the width to 64-bit explicitly).
//! There is nothing wrong on this, however, some instructions introduced
//! implicit `W` override, for example a `cdqe` instruction is basically a
//! `cwde` instructiontion with overridden `W` (set to 1). There are some
//! others in the base X86 instruction set. More recent instruction sets
//! started using `W` field more often:
//!
//! - AVX instructions started using `W` field as an extended opcode for FMA,
//! GATHER, PERM, and other instructions. It also uses `W` field to override
//! the default operation width in instructions like `vmovq`. AVX `W` field
//! is
//!
//! - AVX-512 instructions started using `W` field as an extended opcode for
//! all new instructions. This wouldn't have been an issue if the `W` field
//! of AVX-512 have matched AVX, but this is not the case.
//!
//! - `O` field is an extended opcode field (3) bytes used by ModR/M BYTE.
ASMJIT_ENUM(X86InstOpCodeFlags) {
// `MMMMM` field in AVX/XOP/AVX-512 instruction (5 bits).
//
// `OpCode` leading bytes in legacy encoding.
//
// AVX reserves 5 bits for `MMMMM` field, however AVX instructions only use
// 2 bits and XOP 4 bits. AVX-512 shrinks `MMMMM` field into `MM` so it's
// safe to assume that `MM` field won't grow in the future as EVEX doesn't
// use more than 2 bits. There is always a way how a fifth bit can be stored
// if needed.
kX86InstOpCode_MM_Shift = 16,
kX86InstOpCode_MM_Mask = 0x0FU << kX86InstOpCode_MM_Shift,
kX86InstOpCode_MM_00 = 0x00U << kX86InstOpCode_MM_Shift,
kX86InstOpCode_MM_0F = 0x01U << kX86InstOpCode_MM_Shift,
kX86InstOpCode_MM_0F38 = 0x02U << kX86InstOpCode_MM_Shift,
kX86InstOpCode_MM_0F3A = 0x03U << kX86InstOpCode_MM_Shift,
kX86InstOpCode_MM_00011 = 0x03U << kX86InstOpCode_MM_Shift, // XOP.
kX86InstOpCode_MM_01000 = 0x08U << kX86InstOpCode_MM_Shift, // XOP.
kX86InstOpCode_MM_01001 = 0x09U << kX86InstOpCode_MM_Shift, // XOP.
kX86InstOpCode_MM_0F01 = 0x0FU << kX86InstOpCode_MM_Shift, // AsmJit specific, not part of AVX.
// `PP` field in AVX/XOP/AVX-512 instruction.
//
// `Mandatory Prefix` in legacy encoding.
//
// AVX reserves 2 bits for `PP` field, but AsmJit extends the storage by 1
// more bit that is used to emit 9B prefix for some X87-FPU instructions.
kX86InstOpCode_PP_Shift = 20,
kX86InstOpCode_PP_Mask = 0x07U << kX86InstOpCode_PP_Shift,
kX86InstOpCode_PP_00 = 0x00U << kX86InstOpCode_PP_Shift,
kX86InstOpCode_PP_66 = 0x01U << kX86InstOpCode_PP_Shift,
kX86InstOpCode_PP_F3 = 0x02U << kX86InstOpCode_PP_Shift,
kX86InstOpCode_PP_F2 = 0x03U << kX86InstOpCode_PP_Shift,
kX86InstOpCode_PP_9B = 0x07U << kX86InstOpCode_PP_Shift, // AsmJit specific, not part of AVX.
// `L` field in AVX/XOP/AVX-512 instruction.
//
// AVX/XOP can only use the first bit `L.128` or `L.256`. AVX-512 makes it
// possible to use also `L.512`.
//
// \note If the instruction set manual describes an instruction by using `LIG`
// it means that the `L` field is ignored. AsmJit emits `0` in such case.
kX86InstOpCode_L_Shift = 23,
kX86InstOpCode_L_Mask = 0x03U << kX86InstOpCode_L_Shift,
kX86InstOpCode_L_128 = 0x00U << kX86InstOpCode_L_Shift,
kX86InstOpCode_L_256 = 0x01U << kX86InstOpCode_L_Shift,
kX86InstOpCode_L_512 = 0x02U << kX86InstOpCode_L_Shift,
// `O` field (ModR/M).
kX86InstOpCode_O_Shift = 25,
kX86InstOpCode_O_Mask = 0x07U << kX86InstOpCode_O_Shift,
// `W` field used in EVEX instruction encoding.
kX86InstOpCode_EW_Shift = 30,
kX86InstOpCode_EW_Mask = 0x01U << kX86InstOpCode_EW_Shift,
kX86InstOpCode_EW = 0x01U << kX86InstOpCode_EW_Shift,
// `W` field used in REX/VEX instruction encoding.
//
// \note If the instruction set manual describes an instruction by using `WIG`
// it means that the `W` field is ignored. AsmJit emits `0` in such case.
kX86InstOpCode_W_Shift = 31,
kX86InstOpCode_W_Mask = 0x01U << kX86InstOpCode_W_Shift,
kX86InstOpCode_W = 0x01U << kX86InstOpCode_W_Shift,
};
// ============================================================================
// [asmjit::X86InstFlags]
// ============================================================================
//! \internal
//!
//! X86/X64 instruction flags.
ASMJIT_ENUM(X86InstFlags) {
//! No flags.
kX86InstFlagNone = 0x00000000,
//! Instruction is a control-flow instruction.
//!
//! Control flow instructions are jmp, jcc, call and ret.
kX86InstFlagFlow = 0x00000001,
//! Instruction is a compare/test like instruction.
kX86InstFlagTest = 0x00000002,
//! Instruction is a move like instruction.
//!
//! Move instructions typically overwrite the first operand by the second
//! operand. The first operand can be the exact copy of the second operand
//! or it can be any kind of conversion or shuffling.
//!
//! Mov instructions are 'mov', 'movd', 'movq', movdq', 'lea', multimedia
//! instructions like 'cvtdq2pd', shuffle instructions like 'pshufb' and
//! SSE/SSE2 mathematic instructions like 'rcp?', 'round?' and 'rsqrt?'.
//!
//! There are some MOV instructions that do only a partial move (for example
//! 'cvtsi2ss'), register allocator has to know the variable size and use
//! the flag accordingly to it.
kX86InstFlagMove = 0x00000004,
//! Instruction is an exchange like instruction.
//!
//! Exchange instruction typically overwrite first and second operand. So
//! far only the instructions 'xchg' and 'xadd' are considered.
kX86InstFlagXchg = 0x00000008,
//! Instruction accesses Fp register(s).
kX86InstFlagFp = 0x00000010,
//! Instruction can be prefixed by using the LOCK prefix.
kX86InstFlagLock = 0x00000020,
//! Instruction requires special handling, used by \ref Compiler.
kX86InstFlagSpecial = 0x00000040,
//! Instruction always performs memory access.
//!
//! This flag is always combined with `kX86InstFlagSpecial` and describes
//! that there is an implicit address which is accessed (usually EDI/RDI or
//! ESI/EDI).
kX86InstFlagSpecialMem = 0x00000080,
//! Instruction memory operand can refer to 16-bit address (used by FPU).
kX86InstFlagMem2 = 0x00000100,
//! Instruction memory operand can refer to 32-bit address (used by FPU).
kX86InstFlagMem4 = 0x00000200,
//! Instruction memory operand can refer to 64-bit address (used by FPU).
kX86InstFlagMem8 = 0x00000400,
//! Instruction memory operand can refer to 80-bit address (used by FPU).
kX86InstFlagMem10 = 0x00000800,
//! Zeroes the rest of the register if the source operand is memory.
//!
//! Special behavior related to some SIMD load instructions.
kX86InstFlagZ = 0x00001000,
//! Instruction is supported by AVX.
kX86InstFlagAvx = 0x00010000,
//! Instruction is supported by XOP.
kX86InstFlagXop = 0x00020000,
//! Instruction is supported by AVX-512 F (Zmm).
kX86InstFlagAvx512F = 0x00100000,
//! Instruction is supported by AVX-512 CD (Zmm).
kX86InstFlagAvx512CD = 0x00200000,
//! Instruction is supported by AVX-512 PF (Zmm).
kX86InstFlagAvx512PF = 0x00400000,
//! Instruction is supported by AVX-512 ER (Zmm).
kX86InstFlagAvx512ER = 0x00800000,
//! Instruction is supported by AVX-512 DQ (Zmm).
kX86InstFlagAvx512DQ = 0x01000000,
//! Instruction is supported by AVX-512 BW (Zmm).
kX86InstFlagAvx512BW = 0x02000000,
//! Instruction is supported by AVX-512 VL (Xmm/Ymm).
kX86InstFlagAvx512VL = 0x04000000,
//! Instruction supports masking {k0..k7}.
kX86InstFlagAvx512KMask = 0x08000000,
//! Instruction supports zeroing of elements {k0z..k7z}.
kX86InstFlagAvx512KZero = 0x10000000,
//! Instruction supports broadcast {1toN}.
kX86InstFlagAvx512Broadcast = 0x20000000,
//! Instruction supports suppressing all exceptions {sae}.
kX86InstFlagAvx512Sae = 0x40000000,
//! Instruction supports static rounding control with SAE {rnd-sae},
kX86InstFlagAvx512Rnd = 0x80000000
};
// ============================================================================
// [asmjit::X86InstOp]
// ============================================================================
//! \internal
//!
//! X86/X64 instruction operand flags.
ASMJIT_ENUM(X86InstOp) {
//! Instruction operand can be 8-bit Gpb register.
kX86InstOpGb = 0x0001,
//! Instruction operand can be 16-bit Gpw register.
kX86InstOpGw = 0x0002,
//! Instruction operand can be 32-bit Gpd register.
kX86InstOpGd = 0x0004,
//! Instruction operand can be 64-bit Gpq register.
kX86InstOpGq = 0x0008,
//! Instruction operand can be Fp register.
kX86InstOpFp = 0x0010,
//! Instruction operand can be 64-bit Mm register.
kX86InstOpMm = 0x0020,
//! Instruction operand can be 64-bit K register.
kX86InstOpK = 0x0040,
//! Instruction operand can be 128-bit Xmm register.
kX86InstOpXmm = 0x0100,
//! Instruction operand can be 256-bit Ymm register.
kX86InstOpYmm = 0x0200,
//! Instruction operand can be 512-bit Zmm register.
kX86InstOpZmm = 0x0400,
//! Instruction operand can be memory.
kX86InstOpMem = 0x1000,
//! Instruction operand can be immediate.
kX86InstOpImm = 0x2000,
//! Instruction operand can be label.
kX86InstOpLabel = 0x4000,
//! Instruction operand doesn't have to be used.
//!
//! \note If no operand is specified the meaning is clear (the operand at the
//! particular index doesn't exist), however, when one or more operand is
//! specified, it's not clear whether the operand can be omitted or not. When
//! `kX86InstOpNone` is used it means that the operand is not used in some
//! cases.
kX86InstOpNone = 0x8000
};
// ============================================================================
// [asmjit::X86Cond]
// ============================================================================
//! X86/X64 Condition codes.
ASMJIT_ENUM(X86Cond) {
kX86CondA = 0x07, // CF==0 & ZF==0 (unsigned)
kX86CondAE = 0x03, // CF==0 (unsigned)
kX86CondB = 0x02, // CF==1 (unsigned)
kX86CondBE = 0x06, // CF==1 | ZF==1 (unsigned)
kX86CondC = 0x02, // CF==1
kX86CondE = 0x04, // ZF==1 (signed/unsigned)
kX86CondG = 0x0F, // ZF==0 & SF==OF (signed)
kX86CondGE = 0x0D, // SF==OF (signed)
kX86CondL = 0x0C, // SF!=OF (signed)
kX86CondLE = 0x0E, // ZF==1 | SF!=OF (signed)
kX86CondNA = 0x06, // CF==1 | ZF==1 (unsigned)
kX86CondNAE = 0x02, // CF==1 (unsigned)
kX86CondNB = 0x03, // CF==0 (unsigned)
kX86CondNBE = 0x07, // CF==0 & ZF==0 (unsigned)
kX86CondNC = 0x03, // CF==0
kX86CondNE = 0x05, // ZF==0 (signed/unsigned)
kX86CondNG = 0x0E, // ZF==1 | SF!=OF (signed)
kX86CondNGE = 0x0C, // SF!=OF (signed)
kX86CondNL = 0x0D, // SF==OF (signed)
kX86CondNLE = 0x0F, // ZF==0 & SF==OF (signed)
kX86CondNO = 0x01, // OF==0
kX86CondNP = 0x0B, // PF==0
kX86CondNS = 0x09, // SF==0
kX86CondNZ = 0x05, // ZF==0
kX86CondO = 0x00, // OF==1
kX86CondP = 0x0A, // PF==1
kX86CondPE = 0x0A, // PF==1
kX86CondPO = 0x0B, // PF==0
kX86CondS = 0x08, // SF==1
kX86CondZ = 0x04, // ZF==1
// Simplified condition codes.
kX86CondSign = kX86CondS , //!< Sign (S).
kX86CondNotSign = kX86CondNS, //!< Not Sign (NS).
kX86CondOverflow = kX86CondO , //!< Signed Overflow (O)
kX86CondNotOverflow = kX86CondNO, //!< Not Signed Overflow (NO)
kX86CondLess = kX86CondL , //!< Signed `a < b` (L or NGE).
kX86CondLessEqual = kX86CondLE, //!< Signed `a <= b` (LE or NG ).
kX86CondGreater = kX86CondG , //!< Signed `a > b` (G or NLE).
kX86CondGreaterEqual = kX86CondGE, //!< Signed `a >= b` (GE or NL ).
kX86CondBelow = kX86CondB , //!< Unsigned `a < b` (B or NAE).
kX86CondBelowEqual = kX86CondBE, //!< Unsigned `a <= b` (BE or NA ).
kX86CondAbove = kX86CondA , //!< Unsigned `a > b` (A or NBE).
kX86CondAboveEqual = kX86CondAE, //!< Unsigned `a >= b` (AE or NB ).
kX86CondEqual = kX86CondE , //!< Equal `a == b` (E or Z ).
kX86CondNotEqual = kX86CondNE, //!< Not Equal `a != b` (NE or NZ ).
kX86CondParityEven = kX86CondP,
kX86CondParityOdd = kX86CondPO,
// Aliases.
kX86CondZero = kX86CondZ,
kX86CondNotZero = kX86CondNZ,
kX86CondNegative = kX86CondS,
kX86CondPositive = kX86CondNS,
// Fpu-only.
kX86CondFpuUnordered = 0x10,
kX86CondFpuNotUnordered = 0x11,
//! No condition code.
kX86CondNone = 0x12
};
// ============================================================================
// [asmjit::X86EFlags]
// ============================================================================
//! X86/X64 EFLAGs bits (AsmJit specific).
//!
//! Each instruction stored in AsmJit database contains flags that instruction
//! uses (reads) and flags that instruction modifies (writes). This is used by
//! instruction reordering, but can be used by third parties as it's part of
//! AsmJit API.
//!
//! \note Flags defined here don't correspond to real flags used by X86/X64
//! architecture, defined in Intel's Manual Section `3.4.3 - EFLAGS Register`.
//!
//! \note Flags are designed to fit in an 8-bit integer.
ASMJIT_ENUM(X86EFlags) {
// --------------------------------------------------------------------------
// src-gendefs.js relies on the values of these masks, the tool has to be
// changed as you plan to modify `X86EFlags`.
// --------------------------------------------------------------------------
//! Overflow flag (OF).
//!
//! Set if the integer result is too large a positive number or too small a
//! negative number (excluding the sign-bit) to fit in the destination
//! operand; cleared otherwise. This flag indicates an overflow condition for
//! signed-integer arithmetic.
kX86EFlagO = 0x01,
//! Sign flag (SF).
//!
//! Set equal to the most-significant bit of the result, which is the sign
//! bit of a signed integer (0 == positive value, 1 == negative value).
kX86EFlagS = 0x02,
//! Zero flag (ZF).
//!
//! Set if the result is zero; cleared otherwise.
kX86EFlagZ = 0x04,
//! Adjust flag (AF).
//!
//! Set if an arithmetic operation generates a carry or a borrow out of bit
//! 3 of the result; cleared otherwise. This flag is used in binary-coded
//! decimal (BCD) arithmetic.
kX86EFlagA = 0x08,
//! Parity flag (PF).
//!
//! Set if the least-significant byte of the result contains an even number
//! of 1 bits; cleared otherwise.
kX86EFlagP = 0x10,
//! Carry flag (CF).
//!
//! Set if an arithmetic operation generates a carry or a borrow out of the
//! mostsignificant bit of the result; cleared otherwise.
kX86EFlagC = 0x20,
//! Direction flag (DF).
//!
//! The direction flag controls string instructions `movs`, `cmps`, `scas,
//! `lods` and `stos`.
kX86EFlagD = 0x40,
//! Any other flag that AsmJit doesn't use to keep track of.
kX86EFlagX = 0x80
};
// ============================================================================
// [asmjit::X86FpSw]
// ============================================================================
//! X86/X64 FPU status word.
ASMJIT_ENUM(X86FpSw) {
kX86FpSw_Invalid = 0x0001,
kX86FpSw_Denormalized = 0x0002,
kX86FpSw_DivByZero = 0x0004,
kX86FpSw_Overflow = 0x0008,
kX86FpSw_Underflow = 0x0010,
kX86FpSw_Precision = 0x0020,
kX86FpSw_StackFault = 0x0040,
kX86FpSw_Interrupt = 0x0080,
kX86FpSw_C0 = 0x0100,
kX86FpSw_C1 = 0x0200,
kX86FpSw_C2 = 0x0400,
kX86FpSw_Top = 0x3800,
kX86FpSw_C3 = 0x4000,
kX86FpSw_Busy = 0x8000
};
// ============================================================================
// [asmjit::X86FpCw]
// ============================================================================
//! X86/X64 FPU control word.
ASMJIT_ENUM(X86FpCw) {
kX86FpCw_EM_Mask = 0x003F, // Bits 0-5.
kX86FpCw_EM_Invalid = 0x0001,
kX86FpCw_EM_Denormal = 0x0002,
kX86FpCw_EM_DivByZero = 0x0004,
kX86FpCw_EM_Overflow = 0x0008,
kX86FpCw_EM_Underflow = 0x0010,
kX86FpCw_EM_Inexact = 0x0020,
kX86FpCw_PC_Mask = 0x0300, // Bits 8-9.
kX86FpCw_PC_Float = 0x0000,
kX86FpCw_PC_Reserved = 0x0100,
kX86FpCw_PC_Double = 0x0200,
kX86FpCw_PC_Extended = 0x0300,
kX86FpCw_RC_Mask = 0x0C00, // Bits 10-11.
kX86FpCw_RC_Nearest = 0x0000,
kX86FpCw_RC_Down = 0x0400,
kX86FpCw_RC_Up = 0x0800,
kX86FpCw_RC_Truncate = 0x0C00,
kX86FpCw_IC_Mask = 0x1000, // Bit 12.
kX86FpCw_IC_Projective = 0x0000,
kX86FpCw_IC_Affine = 0x1000
};
// ============================================================================
// [asmjit::X86Cmp]
// ============================================================================
//! X86/X64 Comparison predicate used by CMP[PD/PS/SD/SS] family instructions.
ASMJIT_ENUM(X86Cmp) {
kX86CmpEQ = 0x00, //!< Equal (Quite).
kX86CmpLT = 0x01, //!< Less (Signaling).
kX86CmpLE = 0x02, //!< Less/Equal (Signaling).
kX86CmpUNORD = 0x03, //!< Unordered (Quite).
kX86CmpNEQ = 0x04, //!< Not Equal (Quite).
kX86CmpNLT = 0x05, //!< Not Less (Signaling).
kX86CmpNLE = 0x06, //!< Not Less/Equal (Signaling).
kX86CmpORD = 0x07 //!< Ordered (Quite).
};
// ============================================================================
// [asmjit::X86VCmp]
// ============================================================================
//! X86/X64 Comparison predicate used by VCMP[PD/PS/SD/SS] family instructions.
//!
//! The first 8 are compatible with \ref X86Cmp.
ASMJIT_ENUM(X86VCmp) {
kX86VCmpEQ_OQ = 0x00, //!< Equal (Quite, Ordered).
kX86VCmpLT_OS = 0x01, //!< Less (Signaling, Ordered).
kX86VCmpLE_OS = 0x02, //!< Less/Equal (Signaling, Ordered).
kX86VCmpUNORD_Q = 0x03, //!< Unordered (Quite).
kX86VCmpNEQ_UQ = 0x04, //!< Not Equal (Quite, Unordered).
kX86VCmpNLT_US = 0x05, //!< Not Less (Signaling, Unordered).
kX86VCmpNLE_US = 0x06, //!< Not Less/Equal (Signaling, Unordered).
kX86VCmpORD_Q = 0x07, //!< Ordered (Quite).
kX86VCmpEQ_UQ = 0x08, //!< Equal (Quite, Unordered).
kX86VCmpNGE_US = 0x09, //!< Not Greater/Equal (Signaling, Unordered).
kX86VCmpNGT_US = 0x0A, //!< Not Greater (Signaling, Unordered).
kX86VCmpFALSE_OQ = 0x0B, //!< False (Quite, Ordered).
kX86VCmpNEQ_OQ = 0x0C, //!< Not Equal (Quite, Ordered).
kX86VCmpGE_OS = 0x0D, //!< Greater/Equal (Signaling, Ordered).
kX86VCmpGT_OS = 0x0E, //!< Greater (Signaling, Ordered).
kX86VCmpTRUE_UQ = 0x0F, //!< True (Quite, Unordered).
kX86VCmpEQ_OS = 0x10, //!< Equal (Signaling, Ordered).
kX86VCmpLT_OQ = 0x11, //!< Less (Quite, Ordered).
kX86VCmpLE_OQ = 0x12, //!< Less/Equal (Quite, Ordered).
kX86VCmpUNORD_S = 0x13, //!< Unordered (Signaling).
kX86VCmpNEQ_US = 0x14, //!< Not Equal (Signaling, Unordered).
kX86VCmpNLT_UQ = 0x15, //!< Not Less (Quite, Unordered).
kX86VCmpNLE_UQ = 0x16, //!< Not Less/Equal (Quite, Unordered).
kX86VCmpORD_S = 0x17, //!< Ordered (Signaling).
kX86VCmpEQ_US = 0x18, //!< Equal (Signaling, Unordered).
kX86VCmpNGE_UQ = 0x19, //!< Not Greater/Equal (Quite, Unordered).
kX86VCmpNGT_UQ = 0x1A, //!< Not Greater (Quite, Unordered).
kX86VCmpFALSE_OS = 0x1B, //!< False (Signaling, Ordered).
kX86VCmpNEQ_OS = 0x1C, //!< Not Equal (Signaling, Ordered).
kX86VCmpGE_OQ = 0x1D, //!< Greater/Equal (Quite, Ordered).
kX86VCmpGT_OQ = 0x1E, //!< Greater (Quite, Ordered).
kX86VCmpTRUE_US = 0x1F //!< True (Signaling, Unordered).
};
// ============================================================================
// [asmjit::X86Prefetch]
// ============================================================================
//! X86/X64 Prefetch hints.
ASMJIT_ENUM(X86Prefetch) {
//! Prefetch using NT hint.
kX86PrefetchNTA = 0,
//! Prefetch to L0 cache.
kX86PrefetchT0 = 1,
//! Prefetch to L1 cache.
kX86PrefetchT1 = 2,
//! Prefetch to L2 cache.
kX86PrefetchT2 = 3
};
// ============================================================================
// [asmjit::X86InstExtendedInfo]
// ============================================================================
//! X86/X64 instruction extended information.
//!
//! Extended information has been introduced to minimize data needed for a
//! single instruction, because two or more instructions can share the common
//! data, for example operands definition or secondary opcode, which is only
//! used by few instructions.
struct X86InstExtendedInfo {
// --------------------------------------------------------------------------
// [Accessors - Instruction Encoding]
// --------------------------------------------------------------------------
//! Get instruction encoding, see \ref kX86InstEncoding.
ASMJIT_INLINE uint32_t getEncodingId() const {
return _encodingId;
}
// --------------------------------------------------------------------------
// [Accessors - Instruction Flags]
// --------------------------------------------------------------------------
//! Get whether the instruction has a `flag`, see `X86InstFlags`.
ASMJIT_INLINE bool hasInstFlag(uint32_t flag) const {
return (_instFlags & flag) != 0;
}
//! Get all instruction flags, see `X86InstFlags`.
ASMJIT_INLINE uint32_t getInstFlags() const {
return _instFlags;
}
//! Get whether the instruction is a control-flow intruction.
//!
//! Control flow instruction is instruction that can perform a branch,
//! typically `jmp`, `jcc`, `call`, or `ret`.
ASMJIT_INLINE bool isFlow() const {
return (getInstFlags() & kX86InstFlagFlow) != 0;
}
//! Get whether the instruction is a compare/test like intruction.
ASMJIT_INLINE bool isTest() const {
return (getInstFlags() & kX86InstFlagTest) != 0;
}
//! Get whether the instruction is a typical move instruction.
//!
//! Move instructions overwrite the first operand or at least part of it,
//! This is a very useful hint that is used by variable liveness analysis
//! and `Compiler` in general to know which variable is completely
//! overwritten.
//!
//! All AVX/XOP instructions that have 3 or more operands are considered to
//! have move semantics move by default.
ASMJIT_INLINE bool isMove() const {
return (getInstFlags() & kX86InstFlagMove) != 0;
}
//! Get whether the instruction is a typical Exchange instruction.
//!
//! Exchange instructios are 'xchg' and 'xadd'.
ASMJIT_INLINE bool isXchg() const {
return (getInstFlags() & kX86InstFlagXchg) != 0;
}
//! Get whether the instruction accesses Fp register(s).
ASMJIT_INLINE bool isFp() const {
return (getInstFlags() & kX86InstFlagFp) != 0;
}
//! Get whether the instruction can be prefixed by LOCK prefix.
ASMJIT_INLINE bool isLockable() const {
return (getInstFlags() & kX86InstFlagLock) != 0;
}
//! Get whether the instruction is special type (this is used by `Compiler`
//! to manage additional variables or functionality).
ASMJIT_INLINE bool isSpecial() const {
return (getInstFlags() & kX86InstFlagSpecial) != 0;
}
//! Get whether the instruction is special type and it performs memory access.
ASMJIT_INLINE bool isSpecialMem() const {
return (getInstFlags() & kX86InstFlagSpecialMem) != 0;
}
//! Get whether the move instruction zeroes the rest of the register
//! if the source is memory operand.
//!
//! Basically flag needed only to support `movsd` and `movss` instructions.
ASMJIT_INLINE bool isZeroIfMem() const {
return (getInstFlags() & kX86InstFlagZ) != 0;
}
// --------------------------------------------------------------------------
// [Accessors - EFlags]
// --------------------------------------------------------------------------
//! Get EFLAGS that the instruction reads, see \ref X86EFlags.
ASMJIT_INLINE uint32_t getEFlagsIn() const {
return _eflagsIn;
}
//! Get EFLAGS that the instruction writes, see \ref X86EFlags.
ASMJIT_INLINE uint32_t getEFlagsOut() const {
return _eflagsOut;
}
// --------------------------------------------------------------------------
// [Accessors - Write Index/Size]
// --------------------------------------------------------------------------
//! Get the destination index of WRITE operation.
ASMJIT_INLINE uint32_t getWriteIndex() const {
return _writeIndex;
}
//! Get the number of bytes that will be written by a WRITE operation.
ASMJIT_INLINE uint32_t getWriteSize() const {
return _writeSize;
}
// --------------------------------------------------------------------------
// [Accessors - Operand-Flags]
// --------------------------------------------------------------------------
//! Get flags of operand at index `index`.
//!
//! See \ref X86InstInfo::getOperandFlags() for more details.
ASMJIT_INLINE uint16_t getOperandFlags(uint32_t index) const {
ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_opFlags));
return _opFlags[index];
}
// --------------------------------------------------------------------------
// [Accessors - OpCode]
// --------------------------------------------------------------------------
//! Get the secondary instruction opcode, see \ref X86InstOpCodeFlags.
//!
//! See \ref X86InstInfo::getSecondaryOpCode() for more details.
ASMJIT_INLINE uint32_t getSecondaryOpCode() const {
return _secondaryOpCode;
}
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
//! Instruction encoding ID.
uint8_t _encodingId;
//! Destination index of WRITE operation, default 0.
uint8_t _writeIndex;
//! Count of bytes affected by a write operation, needed by analysis for all
//! instructions that do not read the register overwritten. Only used with
//! `kX86InstFlagMove` flag. If `_writeSize` is zero it is automatically
//! deduced from the size of the destination register.
//!
//! In general most of SSE write-only instructions should use 16 bytes as
//! this is the size of the register (and of Ymm/Zmm registers). This means
//! that 16-bytes of the register are changed, the rest remains unchanged.
//! However, AVX instructions should use the size of Zmm register as every
//! AVX instruction zeroes the rest of the register (AVX/AVX2 instructions
//! zero the HI part of Zmm if available).
uint8_t _writeSize;
//! EFlags read by the instruction.
uint8_t _eflagsIn;
//! EFlags written by the instruction.
uint8_t _eflagsOut;
//! \internal
uint8_t _reserved;
//! Operands' flags, up to 5 operands.
uint16_t _opFlags[5];
//! Instruction flags.
uint32_t _instFlags;
//! Secondary opcode.
uint32_t _secondaryOpCode;
};
// ============================================================================
// [asmjit::X86InstInfo]
// ============================================================================
//! X86/X64 instruction information.
struct X86InstInfo {
// --------------------------------------------------------------------------
// [Accessors - Instruction Name]
// --------------------------------------------------------------------------
#if !defined(ASMJIT_DISABLE_NAMES)
//! Get instruction name string (null terminated).
ASMJIT_INLINE const char* getInstName() const {
return _x86InstName + static_cast<uint32_t>(_nameIndex);
}
//! Get instruction name index to `_x86InstName` array.
ASMJIT_INLINE uint32_t _getNameIndex() const {
return _nameIndex;
}
#endif // !ASMJIT_DISABLE_NAMES
// --------------------------------------------------------------------------
// [Accessors - Extended-Info]
// --------------------------------------------------------------------------
//! Get `X86InstExtendedInfo` for this instruction.
ASMJIT_INLINE const X86InstExtendedInfo& getExtendedInfo() const {
return _x86InstExtendedInfo[_extendedIndex];
}
//! Get index to the `_x86InstExtendedInfo` table.
ASMJIT_INLINE uint32_t _getExtendedIndex() const {
return _extendedIndex;
}
// --------------------------------------------------------------------------
// [Accessors - Instruction Encoding]
// --------------------------------------------------------------------------
//! Get instruction group, see \ref X86InstEncodingId.
ASMJIT_INLINE uint32_t getEncodingId() const {
return getExtendedInfo().getEncodingId();
}
// --------------------------------------------------------------------------
// [Accessors - Instruction Flags]
// --------------------------------------------------------------------------
//! Get instruction flags, see `X86InstFlags`.
ASMJIT_INLINE uint32_t getInstFlags() const {
return getExtendedInfo().getInstFlags();
}
//! Get whether the instruction has flag `flag`, see `X86InstFlags`.
ASMJIT_INLINE bool hasInstFlag(uint32_t flag) const {
return (getInstFlags() & flag) != 0;
}
// --------------------------------------------------------------------------
// [Accessors - EFlags]
// --------------------------------------------------------------------------
//! Get EFLAGS that the instruction reads, see \ref X86EFlags.
ASMJIT_INLINE uint32_t getEFlagsIn() const {
return getExtendedInfo().getEFlagsIn();
}
//! Get EFLAGS that the instruction writes, see \ref X86EFlags.
ASMJIT_INLINE uint32_t getEFlagsOut() const {
return getExtendedInfo().getEFlagsOut();
}
// --------------------------------------------------------------------------
// [Accessors - Write Index/Size]
// --------------------------------------------------------------------------
//! Get the destination index of WRITE operation.
ASMJIT_INLINE uint32_t getWriteIndex() const {
return getExtendedInfo().getWriteIndex();
}
//! Get the number of bytes that will be written by a WRITE operation.
ASMJIT_INLINE uint32_t getWriteSize() const {
return getExtendedInfo().getWriteSize();
}
// --------------------------------------------------------------------------
// [Accessors - Operand-Flags]
// --------------------------------------------------------------------------
//! Get flags of operand at index `index`.
ASMJIT_INLINE uint32_t getOperandFlags(uint32_t index) const {
return getExtendedInfo().getOperandFlags(index);
}
// --------------------------------------------------------------------------
// [Accessors - OpCode]
// --------------------------------------------------------------------------
//! Get the primary instruction opcode, see \ref X86InstOpCodeFlags.
ASMJIT_INLINE uint32_t getPrimaryOpCode() const {
return _primaryOpCode;
}
//! Get the secondary instruction opcode, see \ref X86InstOpCodeFlags.
ASMJIT_INLINE uint32_t getSecondaryOpCode() const {
return getExtendedInfo().getSecondaryOpCode();
}
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
//! Instruction name index in `_x86InstName[]` array.
uint16_t _nameIndex;
//! Extended information name index in `_x86InstExtendedInfo[]` array.
uint16_t _extendedIndex;
//! Primary opcode, secondary opcode is stored in `X86InstExtendedInfo` table.
uint32_t _primaryOpCode;
};
// ============================================================================
// [asmjit::X86Util]
// ============================================================================
struct X86Util {
// --------------------------------------------------------------------------
// [Instruction Info]
// --------------------------------------------------------------------------
//! Get instruction information based on `instId`.
//!
//! \note `instId` has to be valid instruction ID, it can't be greater than
//! or equal to `_kX86InstIdCount`. It asserts in debug mode.
static ASMJIT_INLINE const X86InstInfo& getInstInfo(uint32_t instId) {
ASMJIT_ASSERT(instId < _kX86InstIdCount);
return _x86InstInfo[instId];
}
#if !defined(ASMJIT_DISABLE_NAMES)
//! Get an instruction ID from a given instruction `name`.
//!
//! If there is an exact match the instruction id is returned, otherwise
//! `kInstIdNone` (zero) is returned.
//!
//! The given `name` doesn't have to be null-terminated if `len` is provided.
ASMJIT_API static uint32_t getInstIdByName(
const char* name, size_t len = kInvalidIndex);
#endif // !ASMJIT_DISABLE_NAMES
// --------------------------------------------------------------------------
// [Condition Codes]
// --------------------------------------------------------------------------
//! Corresponds to transposing the operands of a comparison.
static ASMJIT_INLINE uint32_t reverseCond(uint32_t cond) {
ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_x86ReverseCond));
return _x86ReverseCond[cond];
}
//! Get the equivalent of negated condition code.
static ASMJIT_INLINE uint32_t negateCond(uint32_t cond) {
ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_x86ReverseCond));
return cond ^ static_cast<uint32_t>(cond < kX86CondNone);
}
//! Translate condition code `cc` to `cmovcc` instruction code.
//! \sa \ref X86InstId, \ref _kX86InstIdCmovcc.
static ASMJIT_INLINE uint32_t condToCmovcc(uint32_t cond) {
ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86CondToCmovcc));
return _x86CondToCmovcc[cond];
}
//! Translate condition code `cc` to `jcc` instruction code.
//! \sa \ref X86InstId, \ref _kX86InstIdJcc.
static ASMJIT_INLINE uint32_t condToJcc(uint32_t cond) {
ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86CondToJcc));
return _x86CondToJcc[cond];
}
//! Translate condition code `cc` to `setcc` instruction code.
//! \sa \ref X86InstId, \ref _kX86InstIdSetcc.
static ASMJIT_INLINE uint32_t condToSetcc(uint32_t cond) {
ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86CondToSetcc));
return _x86CondToSetcc[cond];
}
// --------------------------------------------------------------------------
// [MmShuffle]
// --------------------------------------------------------------------------
//! Pack a shuffle constant to be used with multimedia instrutions (2 values).
//!
//! \param x First component position, number at interval [0, 1] inclusive.
//! \param y Second component position, number at interval [0, 1] inclusive.
//!
//! Shuffle constants can be used to make immediate value for these intrinsics:
//! - `X86Assembler::shufpd()` and `X86Compiler::shufpd()`
static ASMJIT_INLINE int mmShuffle(uint32_t x, uint32_t y) {
return static_cast<int>((x << 1) | y);
}
//! Pack a shuffle constant to be used with multimedia instrutions (4 values).
//!
//! \param z First component position, number at interval [0, 3] inclusive.
//! \param x Second component position, number at interval [0, 3] inclusive.
//! \param y Third component position, number at interval [0, 3] inclusive.
//! \param w Fourth component position, number at interval [0, 3] inclusive.
//!
//! Shuffle constants can be used to make immediate value for these intrinsics:
//! - `X86Assembler::pshufw()` and `X86Compiler::pshufw()`
//! - `X86Assembler::pshufd()` and `X86Compiler::pshufd()`
//! - `X86Assembler::pshufhw()` and `X86Compiler::pshufhw()`
//! - `X86Assembler::pshuflw()` and `X86Compiler::pshuflw()`
//! - `X86Assembler::shufps()` and `X86Compiler::shufps()`
static ASMJIT_INLINE int mmShuffle(uint32_t z, uint32_t y, uint32_t x, uint32_t w) {
return static_cast<int>((z << 6) | (y << 4) | (x << 2) | w);
}
};
//! \}
} // asmjit namespace
#undef _OP_ID
// [Api-End]
#include "../apiend.h"
// [Guard]
#endif // _ASMJIT_X86_X86INST_H
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Export]
#define ASMJIT_EXPORTS
// [Guard]
#include "../build.h"
#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
// [Dependencies - AsmJit]
#include "../x86/x86operand.h"
// [Api-Begin]
#include "../apibegin.h"
namespace asmjit {
namespace x86 {
// ============================================================================
// [asmjit::X86Mem - abs[]]
// ============================================================================
X86Mem ptr_abs(Ptr pAbs, int32_t disp, uint32_t size) {
X86Mem m(NoInit);
m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, 0, kInvalidValue);
m._vmem.index = kInvalidValue;
m._vmem.displacement = static_cast<int32_t>((intptr_t)(pAbs + disp));
return m;
}
X86Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift, int32_t disp, uint32_t size) {
X86Mem m(NoInit);
uint32_t flags = shift << kX86MemShiftIndex;
if (index.isGp())
flags |= X86Mem::_getGpdFlags(index);
else if (index.isXmm())
flags |= kX86MemVSibXmm << kX86MemVSibIndex;
else if (index.isYmm())
flags |= kX86MemVSibYmm << kX86MemVSibIndex;
m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, flags, kInvalidValue);
m._vmem.index = index.getRegIndex();
m._vmem.displacement = static_cast<int32_t>((intptr_t)(pAbs + disp));
return m;
}
#if !defined(ASMJIT_DISABLE_COMPILER)
X86Mem ptr_abs(Ptr pAbs, const X86Var& index, uint32_t shift, int32_t disp, uint32_t size) {
X86Mem m(NoInit);
uint32_t flags = shift << kX86MemShiftIndex;
const Var& index_ = reinterpret_cast<const Var&>(index);
uint32_t indexRegType = index_.getRegType();
if (indexRegType <= kX86RegTypeGpq)
flags |= X86Mem::_getGpdFlags(reinterpret_cast<const Var&>(index));
else if (indexRegType == kX86RegTypeXmm)
flags |= kX86MemVSibXmm << kX86MemVSibIndex;
else if (indexRegType == kX86RegTypeYmm)
flags |= kX86MemVSibYmm << kX86MemVSibIndex;
m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, flags, kInvalidValue);
m._vmem.index = index_.getId();
m._vmem.displacement = static_cast<int32_t>((intptr_t)(pAbs + disp));
return m;
}
#endif // !ASMJIT_DISABLE_COMPILER
} // x86 namespace
} // asmjit namespace
// [Api-End]
#include "../apiend.h"
// [Guard]
#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Guard]
#ifndef _ASMJIT_X86_X86OPERAND_H
#define _ASMJIT_X86_X86OPERAND_H
// [Dependencies - AsmJit]
#include "../base/assembler.h"
#include "../base/compiler.h"
#include "../base/globals.h"
#include "../base/intutil.h"
#include "../base/operand.h"
#include "../base/vectypes.h"
// [Api-Begin]
#include "../apibegin.h"
//! \internal
//!
//! Internal macro to get an operand ID casting it to `Operand`. Basically
//! allows to get an id of operand that has been just 'typedef'ed.
#define ASMJIT_OP_ID(_Op_) reinterpret_cast<const Operand&>(_Op_).getId()
namespace asmjit {
// ============================================================================
// [Forward Declarations]
// ============================================================================
struct X86Reg;
struct X86RipReg;
struct X86SegReg;
struct X86GpReg;
struct X86FpReg;
struct X86MmReg;
struct X86KReg;
struct X86XmmReg;
struct X86YmmReg;
struct X86ZmmReg;
#if !defined(ASMJIT_DISABLE_COMPILER)
struct X86Var;
struct X86GpVar;
struct X86MmVar;
struct X86KVar;
struct X86XmmVar;
struct X86YmmVar;
struct X86ZmmVar;
#endif // !ASMJIT_DISABLE_COMPILER
//! \addtogroup asmjit_x86_general
//! \{
// ============================================================================
// [asmjit::X86RegClass]
// ============================================================================
//! X86/X64 variable class.
ASMJIT_ENUM(X86RegClass) {
// --------------------------------------------------------------------------
// [Regs & Vars]
// --------------------------------------------------------------------------
//! X86/X64 Gp register class (compatible with universal \ref kRegClassGp).
kX86RegClassGp = kRegClassGp,
//! X86/X64 Mm register class.
kX86RegClassMm = 1,
//! X86/X64 K register class.
kX86RegClassK = 2,
//! X86/X64 Xmm/Ymm/Zmm register class.
kX86RegClassXyz = 3,
//! \internal
//!
//! Last register class that is managed by `X86Compiler`, used by asserts.
_kX86RegClassManagedCount = 4,
// --------------------------------------------------------------------------
// [Regs Only]
// --------------------------------------------------------------------------
//! X86/X64 Fp register class.
kX86RegClassFp = 4,
//! Count of X86/X64 register classes.
kX86RegClassCount = 5
};
// ============================================================================
// [asmjit::X86RegType]
// ============================================================================
//! X86/X64 register type.
ASMJIT_ENUM(X86RegType) {
//! Gpb-lo register (AL, BL, CL, DL, ...).
kX86RegTypeGpbLo = 0x01,
//! Gpb-hi register (AH, BH, CH, DH only).
kX86RegTypeGpbHi = 0x02,
//! \internal
//!
//! Gpb-hi register patched to native index (4-7).
_kX86RegTypePatchedGpbHi = kX86RegTypeGpbLo | kX86RegTypeGpbHi,
//! Gpw register.
kX86RegTypeGpw = 0x10,
//! Gpd register.
kX86RegTypeGpd = 0x20,
//! Gpq register (X64).
kX86RegTypeGpq = 0x30,
//! Fp register.
kX86RegTypeFp = 0x40,
//! Mm register (MMX+).
kX86RegTypeMm = 0x50,
//! K register (AVX512+).
kX86RegTypeK = 0x60,
//! Xmm register (SSE+).
kX86RegTypeXmm = 0x70,
//! Ymm register (AVX+).
kX86RegTypeYmm = 0x80,
//! Zmm register (AVX512+).
kX86RegTypeZmm = 0x90,
//! Instruction pointer (RIP).
kX86RegTypeRip = 0xE0,
//! Segment register.
kX86RegTypeSeg = 0xF0
};
// ============================================================================
// [asmjit::X86RegIndex]
// ============================================================================
//! X86/X64 register indexes.
//!
//! \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) {
//! Index of Al/Ah/Ax/Eax/Rax registers.
kX86RegIndexAx = 0,
//! Index of Cl/Ch/Cx/Ecx/Rcx registers.
kX86RegIndexCx = 1,
//! Index of Dl/Dh/Dx/Edx/Rdx registers.
kX86RegIndexDx = 2,
//! Index of Bl/Bh/Bx/Ebx/Rbx registers.
kX86RegIndexBx = 3,
//! Index of Spl/Sp/Esp/Rsp registers.
kX86RegIndexSp = 4,
//! Index of Bpl/Bp/Ebp/Rbp registers.
kX86RegIndexBp = 5,
//! Index of Sil/Si/Esi/Rsi registers.
kX86RegIndexSi = 6,
//! Index of Dil/Di/Edi/Rdi registers.
kX86RegIndexDi = 7,
//! Index of R8b/R8w/R8d/R8 registers (64-bit only).
kX86RegIndexR8 = 8,
//! Index of R9B/R9w/R9d/R9 registers (64-bit only).
kX86RegIndexR9 = 9,
//! Index of R10B/R10w/R10D/R10 registers (64-bit only).
kX86RegIndexR10 = 10,
//! Index of R11B/R11w/R11d/R11 registers (64-bit only).
kX86RegIndexR11 = 11,
//! Index of R12B/R12w/R12d/R12 registers (64-bit only).
kX86RegIndexR12 = 12,
//! Index of R13B/R13w/R13d/R13 registers (64-bit only).
kX86RegIndexR13 = 13,
//! Index of R14B/R14w/R14d/R14 registers (64-bit only).
kX86RegIndexR14 = 14,
//! Index of R15B/R15w/R15d/R15 registers (64-bit only).
kX86RegIndexR15 = 15
};
// ============================================================================
// [asmjit::X86Seg]
// ============================================================================
//! X86/X64 segment codes.
ASMJIT_ENUM(X86Seg) {
//! No/Default segment.
kX86SegDefault = 0,
//! Es segment.
kX86SegEs = 1,
//! Cs segment.
kX86SegCs = 2,
//! Ss segment.
kX86SegSs = 3,
//! Ds segment.
kX86SegDs = 4,
//! Fs segment.
kX86SegFs = 5,
//! Gs segment.
kX86SegGs = 6,
//! Count of X86 segment registers supported by AsmJit.
//!
//! \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
//! is no segment register specified so the segment prefix will not be emitted.
kX86SegCount = 7
};
// ============================================================================
// [asmjit::X86MemVSib]
// ============================================================================
//! X86/X64 index register legacy and AVX2 (VSIB) support.
ASMJIT_ENUM(X86MemVSib) {
//! Memory operand uses Gpd/Gpq index (or no index register).
kX86MemVSibGpz = 0,
//! Memory operand uses Xmm index (or no index register).
kX86MemVSibXmm = 1,
//! Memory operand uses Ymm index (or no index register).
kX86MemVSibYmm = 2,
//! Memory operand uses Zmm index (or no index register).
kX86MemVSibZmm = 3
};
// ============================================================================
// [asmjit::X86MemFlags]
// ============================================================================
//! \internal
//!
//! X86/X64 specific memory flags.
ASMJIT_ENUM(X86MemFlags) {
kX86MemSegBits = 0x7,
kX86MemSegIndex = 0,
kX86MemSegMask = kX86MemSegBits << kX86MemSegIndex,
kX86MemGpdBits = 0x1,
kX86MemGpdIndex = 3,
kX86MemGpdMask = kX86MemGpdBits << kX86MemGpdIndex,
kX86MemVSibBits = 0x3,
kX86MemVSibIndex = 4,
kX86MemVSibMask = kX86MemVSibBits << kX86MemVSibIndex,
kX86MemShiftBits = 0x3,
kX86MemShiftIndex = 6,
kX86MemShiftMask = kX86MemShiftBits << kX86MemShiftIndex
};
// This is only defined by `x86operand_regs.cpp` when exporting registers.
#if defined(ASMJIT_EXPORTS_X86OPERAND_REGS)
// Remap all classes to POD structs so they can be statically initialized
// without calling a constructor. Compiler will store these in .DATA section.
struct X86RipReg { Operand::VRegOp data; };
struct X86SegReg { Operand::VRegOp data; };
struct X86GpReg { Operand::VRegOp data; };
struct X86FpReg { Operand::VRegOp data; };
struct X86KReg { Operand::VRegOp data; };
struct X86MmReg { Operand::VRegOp data; };
struct X86XmmReg { Operand::VRegOp data; };
struct X86YmmReg { Operand::VRegOp data; };
struct X86ZmmReg { Operand::VRegOp data; };
#else
// ============================================================================
// [asmjit::X86RegCount]
// ============================================================================
//! \internal
//!
//! X86/X64 registers count (Gp, Mm, K, Xmm/Ymm/Zmm).
//!
//! Since the number of registers changed across CPU generations `X86RegCount`
//! 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
//! 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
//! all register classes (except Fp). This can change in the future after a
//! new instruction set is announced.
struct X86RegCount {
// --------------------------------------------------------------------------
// [Zero]
// --------------------------------------------------------------------------
//! Reset all counters to zero.
ASMJIT_INLINE void reset() {
_packed = 0;
}
// --------------------------------------------------------------------------
// [Get]
// --------------------------------------------------------------------------
//! Get register count by `classId`.
ASMJIT_INLINE uint32_t get(uint32_t classId) const {
ASMJIT_ASSERT(classId < _kX86RegClassManagedCount);
return _regs[classId];
}
//! Get Gp register count.
ASMJIT_INLINE uint32_t getGp() const { return _regs[kX86RegClassGp]; }
//! Get Mm register count.
ASMJIT_INLINE uint32_t getMm() const { return _regs[kX86RegClassMm]; }
//! Get K register count.
ASMJIT_INLINE uint32_t getK() const { return _regs[kX86RegClassK]; }
//! Get Xmm/Ymm/Zmm register count.
ASMJIT_INLINE uint32_t getXyz() const { return _regs[kX86RegClassXyz]; }
// --------------------------------------------------------------------------
// [Set]
// --------------------------------------------------------------------------
//! Set register count by `classId`.
ASMJIT_INLINE void set(uint32_t classId, uint32_t n) {
ASMJIT_ASSERT(classId < _kX86RegClassManagedCount);
ASMJIT_ASSERT(n <= 0xFF);
_regs[classId] = static_cast<uint8_t>(n);
}
//! Set Gp register count.
ASMJIT_INLINE void setGp(uint32_t n) { set(kX86RegClassGp, n); }
//! Set Mm register count.
ASMJIT_INLINE void setMm(uint32_t n) { set(kX86RegClassMm, n); }
//! Set K register count.
ASMJIT_INLINE void setK(uint32_t n) { set(kX86RegClassK, n); }
//! Set Xmm/Ymm/Zmm register count.
ASMJIT_INLINE void setXyz(uint32_t n) { set(kX86RegClassXyz, n); }
// --------------------------------------------------------------------------
// [Add]
// --------------------------------------------------------------------------
//! Add register count by `classId`.
ASMJIT_INLINE void add(uint32_t classId, uint32_t n = 1) {
ASMJIT_ASSERT(classId < _kX86RegClassManagedCount);
ASMJIT_ASSERT(0xFF - static_cast<uint32_t>(_regs[classId]) >= n);
_regs[classId] += static_cast<uint8_t>(n);
}
//! Add Gp register count.
ASMJIT_INLINE void addGp(uint32_t n) { add(kX86RegClassGp, n); }
//! Add Mm register count.
ASMJIT_INLINE void addMm(uint32_t n) { add(kX86RegClassMm, n); }
//! Add K register count.
ASMJIT_INLINE void addK(uint32_t n) { add(kX86RegClassK, n); }
//! Add Xmm/Ymm/Zmm register count.
ASMJIT_INLINE void addXyz(uint32_t n) { add(kX86RegClassXyz, n); }
// --------------------------------------------------------------------------
// [Misc]
// --------------------------------------------------------------------------
//! Build a register indexes, based on register's `count`.
//!
//! Register index is used by \ref `X86Compiler` in per-instruction register
//! data. Indexes are sorted by register class in Gp, Mm, K, and Xmm/Ymm/Zmm
//! order.
ASMJIT_INLINE void indexFromRegCount(const X86RegCount& count) {
uint32_t x = count._regs[0];
uint32_t y;
_regs[0] = static_cast<uint8_t>(0);
_regs[1] = static_cast<uint8_t>(x);
x = x + count._regs[1];
y = x + count._regs[2];
ASMJIT_ASSERT(x <= 0xFF);
ASMJIT_ASSERT(y <= 0xFF);
_regs[2] = static_cast<uint8_t>(x);
_regs[3] = static_cast<uint8_t>(y);
}
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
union {
struct {
//! Count of Gp registers.
uint8_t _gp;
//! Count of Mm registers.
uint8_t _mm;
//! Count of K registers.
uint8_t _k;
//! Count of Xmm/Ymm/Zmm registers.
uint8_t _xyz;
//! \internal
uint8_t _reserved[3];
};
uint8_t _regs[4];
uint32_t _packed;
};
};
// ============================================================================
// [asmjit::X86RegMask]
// ============================================================================
//! \internal
//!
//! X86/X64 registers mask (Gp, Mm, K, Xmm/Ymm/Zmm).
struct X86RegMask {
// --------------------------------------------------------------------------
// [Reset]
// --------------------------------------------------------------------------
//! Reset all register masks to zero.
ASMJIT_INLINE void reset() {
_packed.reset();
}
// --------------------------------------------------------------------------
// [IsEmpty / Has]
// --------------------------------------------------------------------------
//! Get whether all register masks are zero (empty).
ASMJIT_INLINE bool isEmpty() const {
return _packed.isZero();
}
ASMJIT_INLINE bool has(uint32_t classId, uint32_t mask = 0xFFFFFFFF) const {
ASMJIT_ASSERT(classId < _kX86RegClassManagedCount);
switch (classId) {
case kX86RegClassGp : return (static_cast<uint32_t>(_gp ) & mask) != 0;
case kX86RegClassMm : return (static_cast<uint32_t>(_mm ) & mask) != 0;
case kX86RegClassK : return (static_cast<uint32_t>(_k ) & mask) != 0;
case kX86RegClassXyz: return (static_cast<uint32_t>(_xyz) & mask) != 0;
}
return false;
}
ASMJIT_INLINE bool hasGp(uint32_t mask = 0xFFFFFFFF) const { return has(kX86RegClassGp, mask); }
ASMJIT_INLINE bool hasMm(uint32_t mask = 0xFFFFFFFF) const { return has(kX86RegClassMm, mask); }
ASMJIT_INLINE bool hasK(uint32_t mask = 0xFFFFFFFF) const { return has(kX86RegClassK, mask); }
ASMJIT_INLINE bool hasXyz(uint32_t mask = 0xFFFFFFFF) const { return has(kX86RegClassXyz, mask); }
// --------------------------------------------------------------------------
// [Get]
// --------------------------------------------------------------------------
ASMJIT_INLINE uint32_t get(uint32_t classId) const {
ASMJIT_ASSERT(classId < _kX86RegClassManagedCount);
switch (classId) {
case kX86RegClassGp : return _gp;
case kX86RegClassMm : return _mm;
case kX86RegClassK : return _k;
case kX86RegClassXyz: return _xyz;
}
return 0;
}
ASMJIT_INLINE uint32_t getGp() const { return get(kX86RegClassGp); }
ASMJIT_INLINE uint32_t getMm() const { return get(kX86RegClassMm); }
ASMJIT_INLINE uint32_t getK() const { return get(kX86RegClassK); }
ASMJIT_INLINE uint32_t getXyz() const { return get(kX86RegClassXyz); }
// --------------------------------------------------------------------------
// [Zero]
// --------------------------------------------------------------------------
ASMJIT_INLINE void zero(uint32_t classId) {
ASMJIT_ASSERT(classId < _kX86RegClassManagedCount);
switch (classId) {
case kX86RegClassGp : _gp = 0; break;
case kX86RegClassMm : _mm = 0; break;
case kX86RegClassK : _k = 0; break;
case kX86RegClassXyz: _xyz = 0; break;
}
}
ASMJIT_INLINE void zeroGp() { zero(kX86RegClassGp); }
ASMJIT_INLINE void zeroMm() { zero(kX86RegClassMm); }
ASMJIT_INLINE void zeroK() { zero(kX86RegClassK); }
ASMJIT_INLINE void zeroXyz() { zero(kX86RegClassXyz); }
// --------------------------------------------------------------------------
// [Set]
// --------------------------------------------------------------------------
ASMJIT_INLINE void set(const X86RegMask& other) {
_packed = other._packed;
}
ASMJIT_INLINE void set(uint32_t classId, uint32_t mask) {
ASMJIT_ASSERT(classId < _kX86RegClassManagedCount);
switch (classId) {
case kX86RegClassGp : _gp = static_cast<uint16_t>(mask); break;
case kX86RegClassMm : _mm = static_cast<uint8_t >(mask); break;
case kX86RegClassK : _k = static_cast<uint8_t >(mask); break;
case kX86RegClassXyz: _xyz = static_cast<uint32_t>(mask); break;
}
}
ASMJIT_INLINE void setGp(uint32_t mask) { return set(kX86RegClassGp, mask); }
ASMJIT_INLINE void setMm(uint32_t mask) { return set(kX86RegClassMm, mask); }
ASMJIT_INLINE void setK(uint32_t mask) { return set(kX86RegClassK, mask); }
ASMJIT_INLINE void setXyz(uint32_t mask) { return set(kX86RegClassXyz, mask); }
// --------------------------------------------------------------------------
// [And]
// --------------------------------------------------------------------------
ASMJIT_INLINE void and_(const X86RegMask& other) {
_packed.and_(other._packed);
}
ASMJIT_INLINE void and_(uint32_t classId, uint32_t mask) {
ASMJIT_ASSERT(classId < _kX86RegClassManagedCount);
switch (classId) {
case kX86RegClassGp : _gp &= static_cast<uint16_t>(mask); break;
case kX86RegClassMm : _mm &= static_cast<uint8_t >(mask); break;
case kX86RegClassK : _k &= static_cast<uint8_t >(mask); break;
case kX86RegClassXyz: _xyz &= static_cast<uint32_t>(mask); break;
}
}
ASMJIT_INLINE void andGp(uint32_t mask) { and_(kX86RegClassGp, mask); }
ASMJIT_INLINE void andMm(uint32_t mask) { and_(kX86RegClassMm, mask); }
ASMJIT_INLINE void andK(uint32_t mask) { and_(kX86RegClassK, mask); }
ASMJIT_INLINE void andXyz(uint32_t mask) { and_(kX86RegClassXyz, mask); }
// --------------------------------------------------------------------------
// [AndNot]
// --------------------------------------------------------------------------
ASMJIT_INLINE void andNot(const X86RegMask& other) {
_packed.andNot(other._packed);
}
ASMJIT_INLINE void andNot(uint32_t classId, uint32_t mask) {
ASMJIT_ASSERT(classId < _kX86RegClassManagedCount);
switch (classId) {
case kX86RegClassGp : _gp &= ~static_cast<uint16_t>(mask); break;
case kX86RegClassMm : _mm &= ~static_cast<uint8_t >(mask); break;
case kX86RegClassK : _k &= ~static_cast<uint8_t >(mask); break;
case kX86RegClassXyz: _xyz &= ~static_cast<uint32_t>(mask); break;
}
}
ASMJIT_INLINE void andNotGp(uint32_t mask) { andNot(kX86RegClassGp, mask); }
ASMJIT_INLINE void andNotMm(uint32_t mask) { andNot(kX86RegClassMm, mask); }
ASMJIT_INLINE void andNotK(uint32_t mask) { andNot(kX86RegClassK, mask); }
ASMJIT_INLINE void andNotXyz(uint32_t mask) { andNot(kX86RegClassXyz, mask); }
// --------------------------------------------------------------------------
// [Or]
// --------------------------------------------------------------------------
ASMJIT_INLINE void or_(const X86RegMask& other) {
_packed.or_(other._packed);
}
ASMJIT_INLINE void or_(uint32_t classId, uint32_t mask) {
ASMJIT_ASSERT(classId < _kX86RegClassManagedCount);
switch (classId) {
case kX86RegClassGp : _gp |= static_cast<uint16_t>(mask); break;
case kX86RegClassMm : _mm |= static_cast<uint8_t >(mask); break;
case kX86RegClassK : _k |= static_cast<uint8_t >(mask); break;
case kX86RegClassXyz: _xyz |= static_cast<uint32_t>(mask); break;
}
}
ASMJIT_INLINE void orGp(uint32_t mask) { return or_(kX86RegClassGp, mask); }
ASMJIT_INLINE void orMm(uint32_t mask) { return or_(kX86RegClassMm, mask); }
ASMJIT_INLINE void orK(uint32_t mask) { return or_(kX86RegClassK, mask); }
ASMJIT_INLINE void orXyz(uint32_t mask) { return or_(kX86RegClassXyz, mask); }
// --------------------------------------------------------------------------
// [Xor]
// --------------------------------------------------------------------------
ASMJIT_INLINE void xor_(const X86RegMask& other) {
_packed.xor_(other._packed);
}
ASMJIT_INLINE void xor_(uint32_t classId, uint32_t mask) {
ASMJIT_ASSERT(classId < _kX86RegClassManagedCount);
switch (classId) {
case kX86RegClassGp : _gp ^= static_cast<uint16_t>(mask); break;
case kX86RegClassMm : _mm ^= static_cast<uint8_t >(mask); break;
case kX86RegClassK : _k ^= static_cast<uint8_t >(mask); break;
case kX86RegClassXyz: _xyz ^= static_cast<uint32_t>(mask); break;
}
}
ASMJIT_INLINE void xorGp(uint32_t mask) { xor_(kX86RegClassGp, mask); }
ASMJIT_INLINE void xorMm(uint32_t mask) { xor_(kX86RegClassMm, mask); }
ASMJIT_INLINE void xorK(uint32_t mask) { xor_(kX86RegClassK, mask); }
ASMJIT_INLINE void xorXyz(uint32_t mask) { xor_(kX86RegClassXyz, mask); }
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
union {
struct {
//! Gp registers mask (16 bits).
uint16_t _gp;
//! Mm registers mask (8 bits).
uint8_t _mm;
//! K registers mask (8 bits).
uint8_t _k;
//! Xmm/Ymm/Zmm registers mask (32 bits).
uint32_t _xyz;
};
//! Packed masks.
UInt64 _packed;
};
};
// ============================================================================
// [asmjit::X86Reg]
// ============================================================================
//! X86/X86 register base class.
struct X86Reg : public Reg {
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
//! Create a dummy X86 register.
ASMJIT_INLINE X86Reg() : Reg() {}
//! Create a reference to `other` X86 register.
ASMJIT_INLINE X86Reg(const X86Reg& other) : Reg(other) {}
//! Create a reference to `other` X86 register and change the index to `index`.
ASMJIT_INLINE X86Reg(const X86Reg& other, uint32_t index) : Reg(other, index) {}
//! Create a custom X86 register.
ASMJIT_INLINE X86Reg(uint32_t type, uint32_t index, uint32_t size) : Reg(type, index, size) {}
//! Create non-initialized X86 register.
explicit ASMJIT_INLINE X86Reg(const _NoInit&) : Reg(NoInit) {}
// --------------------------------------------------------------------------
// [X86Reg Specific]
// --------------------------------------------------------------------------
ASMJIT_REG_OP(X86Reg)
//! Get whether the register is Gp register.
ASMJIT_INLINE bool isGp() const { return _vreg.type <= kX86RegTypeGpq; }
//! Get whether the register is Gp byte (8-bit) register.
ASMJIT_INLINE bool isGpb() const { return _vreg.type <= _kX86RegTypePatchedGpbHi; }
//! Get whether the register is Gp lo-byte (8-bit) register.
ASMJIT_INLINE bool isGpbLo() const { return _vreg.type == kX86RegTypeGpbLo; }
//! Get whether the register is Gp hi-byte (8-bit) register.
ASMJIT_INLINE bool isGpbHi() const { return _vreg.type == kX86RegTypeGpbHi; }
//! Get whether the register is Gp word (16-bit) register.
ASMJIT_INLINE bool isGpw() const { return _vreg.type == kX86RegTypeGpw; }
//! Get whether the register is Gp dword (32-bit) register.
ASMJIT_INLINE bool isGpd() const { return _vreg.type == kX86RegTypeGpd; }
//! Get whether the register is Gp qword (64-bit) register.
ASMJIT_INLINE bool isGpq() const { return _vreg.type == kX86RegTypeGpq; }
//! Get whether the register is Fp register.
ASMJIT_INLINE bool isFp() const { return _vreg.type == kX86RegTypeFp; }
//! Get whether the register is Mm (64-bit) register.
ASMJIT_INLINE bool isMm() const { return _vreg.type == kX86RegTypeMm; }
//! Get whether the register is K (64-bit) register.
ASMJIT_INLINE bool isK() const { return _vreg.type == kX86RegTypeK; }
//! Get whether the register is Xmm (128-bit) register.
ASMJIT_INLINE bool isXmm() const { return _vreg.type == kX86RegTypeXmm; }
//! Get whether the register is Ymm (256-bit) register.
ASMJIT_INLINE bool isYmm() const { return _vreg.type == kX86RegTypeYmm; }
//! Get whether the register is Zmm (512-bit) register.
ASMJIT_INLINE bool isZmm() const { return _vreg.type == kX86RegTypeZmm; }
//! Get whether the register is RIP.
ASMJIT_INLINE bool isRip() const { return _vreg.type == kX86RegTypeRip; }
//! Get whether the register is Segment.
ASMJIT_INLINE bool isSeg() const { return _vreg.type == kX86RegTypeSeg; }
// --------------------------------------------------------------------------
// [Statics]
// --------------------------------------------------------------------------
//! Get whether the `op` operand is Gpb-Lo or Gpb-Hi register.
static ASMJIT_INLINE bool isGpbReg(const Operand& op) {
const uint32_t mask = IntUtil::pack32_2x8_1x16(
0xFF, 0xFF, ~(_kX86RegTypePatchedGpbHi << 8) & 0xFF00);
return (op._packed[0].u32[0] & mask) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 1, 0x0000);
}
};
// ============================================================================
// [asmjit::X86RipReg]
// ============================================================================
//! X86/X64 RIP register.
struct X86RipReg : public X86Reg {
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
//! Create a RIP register.
ASMJIT_INLINE X86RipReg() : X86Reg(kX86RegTypeRip, 0, 0) {}
//! Create a reference to `other` RIP register.
ASMJIT_INLINE X86RipReg(const X86RipReg& other) : X86Reg(other) {}
//! Create non-initialized RIP register.
explicit ASMJIT_INLINE X86RipReg(const _NoInit&) : X86Reg(NoInit) {}
// --------------------------------------------------------------------------
// [X86RipReg Specific]
// --------------------------------------------------------------------------
ASMJIT_REG_OP(X86RipReg)
};
// ============================================================================
// [asmjit::X86SegReg]
// ============================================================================
//! X86/X64 segment register.
struct X86SegReg : public X86Reg {
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
//! Create a dummy segment register.
ASMJIT_INLINE X86SegReg() : X86Reg() {}
//! Create a reference to `other` segment register.
ASMJIT_INLINE X86SegReg(const X86SegReg& other) : X86Reg(other) {}
//! Create a reference to `other` segment register and change the index to `index`.
ASMJIT_INLINE X86SegReg(const X86SegReg& other, uint32_t index) : X86Reg(other, index) {}
//! Create a custom segment register.
ASMJIT_INLINE X86SegReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
//! Create non-initialized segment register.
explicit ASMJIT_INLINE X86SegReg(const _NoInit&) : X86Reg(NoInit) {}
// --------------------------------------------------------------------------
// [X86SegReg Specific]
// --------------------------------------------------------------------------
ASMJIT_REG_OP(X86SegReg)
};
// ============================================================================
// [asmjit::X86GpReg]
// ============================================================================
//! X86/X64 Gpb/Gpw/Gpd/Gpq register.
struct X86GpReg : public X86Reg {
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
//! Create a dummy Gp register.
ASMJIT_INLINE X86GpReg() : X86Reg() {}
//! Create a reference to `other` Gp register.
ASMJIT_INLINE X86GpReg(const X86GpReg& other) : X86Reg(other) {}
//! Create a reference to `other` Gp register and change the index to `index`.
ASMJIT_INLINE X86GpReg(const X86GpReg& other, uint32_t index) : X86Reg(other, index) {}
//! Create a custom Gp register.
ASMJIT_INLINE X86GpReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
//! Create non-initialized Gp register.
explicit ASMJIT_INLINE X86GpReg(const _NoInit&) : X86Reg(NoInit) {}
// --------------------------------------------------------------------------
// [X86GpReg Specific]
// --------------------------------------------------------------------------
ASMJIT_REG_OP(X86GpReg)
// --------------------------------------------------------------------------
// [X86GpReg Cast]
// --------------------------------------------------------------------------
//! Cast this register to 8-bit (LO) part.
ASMJIT_INLINE X86GpReg r8() const { return X86GpReg(kX86RegTypeGpbLo, getRegIndex(), 1); }
//! Cast this register to 8-bit (LO) part.
ASMJIT_INLINE X86GpReg r8Lo() const { return X86GpReg(kX86RegTypeGpbLo, getRegIndex(), 1); }
//! Cast this register to 8-bit (HI) part.
ASMJIT_INLINE X86GpReg r8Hi() const { return X86GpReg(kX86RegTypeGpbHi, getRegIndex(), 1); }
//! Cast this register to 16-bit.
ASMJIT_INLINE X86GpReg r16() const { return X86GpReg(kX86RegTypeGpw, getRegIndex(), 2); }
//! Cast this register to 32-bit.
ASMJIT_INLINE X86GpReg r32() const { return X86GpReg(kX86RegTypeGpd, getRegIndex(), 4); }
//! Cast this register to 64-bit.
ASMJIT_INLINE X86GpReg r64() const { return X86GpReg(kX86RegTypeGpq, getRegIndex(), 8); }
};
// ============================================================================
// [asmjit::X86FpReg]
// ============================================================================
//! X86/X64 80-bit Fp register.
struct X86FpReg : public X86Reg {
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
//! Create a dummy Fp register.
ASMJIT_INLINE X86FpReg() : X86Reg() {}
//! Create a reference to `other` Fp register.
ASMJIT_INLINE X86FpReg(const X86FpReg& other) : X86Reg(other) {}
//! Create a reference to `other` Fp register and change the index to `index`.
ASMJIT_INLINE X86FpReg(const X86FpReg& other, uint32_t index) : X86Reg(other, index) {}
//! Create a custom Fp register.
ASMJIT_INLINE X86FpReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
//! Create non-initialized Fp register.
explicit ASMJIT_INLINE X86FpReg(const _NoInit&) : X86Reg(NoInit) {}
// --------------------------------------------------------------------------
// [X86FpReg Specific]
// --------------------------------------------------------------------------
ASMJIT_REG_OP(X86FpReg)
};
// ============================================================================
// [asmjit::X86MmReg]
// ============================================================================
//! X86/X64 64-bit Mm register (MMX+).
//!
//! Structure of MMX register and it's memory mapping:
//!
//! ~~~
//! Memory Bytes
//! +--+--+--+--+--+--+--+--+
//! |00|01|02|03|04|05|06|07|
//! +--+--+--+--+--+--+--+--+
//!
//! MMX Register
//! +-----------------------+
//! | QWord |
//! +-----------+-----------+
//! | HI-DWord | LO-DWord |
//! +-----------+-----------+
//! | W3 | W2 | W1 | W0 |
//! +--+--+--+--+--+--+--+--+
//! |07|06|05|04|03|02|01|00|
//! +--+--+--+--+--+--+--+--+
//! ~~~
//!
//! Move instruction semantics:
//!
//! - `movd` - writes 4-bytes in `LO-DWord` and zeroes `HI-DWord`.
//! - `movq` - writes 8-bytes in `QWord`.
struct X86MmReg : public X86Reg {
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
//! Create a dummy Mm register.
ASMJIT_INLINE X86MmReg() : X86Reg() {}
//! Create a reference to `other` Mm register.
ASMJIT_INLINE X86MmReg(const X86MmReg& other) : X86Reg(other) {}
//! Create a reference to `other` Mm register and change the index to `index`.
ASMJIT_INLINE X86MmReg(const X86MmReg& other, uint32_t index) : X86Reg(other, index) {}
//! Create a custom Mm register.
ASMJIT_INLINE X86MmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
//! Create non-initialized Mm register.
explicit ASMJIT_INLINE X86MmReg(const _NoInit&) : X86Reg(NoInit) {}
// --------------------------------------------------------------------------
// [X86MmReg Specific]
// --------------------------------------------------------------------------
ASMJIT_REG_OP(X86MmReg)
};
// ============================================================================
// [asmjit::X86KReg]
// ============================================================================
//! X86/X64 64-bit K register (AVX512+).
struct X86KReg : public X86Reg {
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
//! Create a dummy K register.
ASMJIT_INLINE X86KReg() : X86Reg() {}
//! Create a reference to `other` K register.
ASMJIT_INLINE X86KReg(const X86KReg& other) : X86Reg(other) {}
//! Create a reference to `other` K register and change the index to `index`.
ASMJIT_INLINE X86KReg(const X86KReg& other, uint32_t index) : X86Reg(other, index) {}
//! Create a custom K register.
ASMJIT_INLINE X86KReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
//! Create non-initialized K register.
explicit ASMJIT_INLINE X86KReg(const _NoInit&) : X86Reg(NoInit) {}
// --------------------------------------------------------------------------
// [X86KReg Specific]
// --------------------------------------------------------------------------
ASMJIT_REG_OP(X86KReg)
};
// ============================================================================
// [asmjit::X86XmmReg]
// ============================================================================
//! X86/X64 128-bit Xmm register (SSE+).
//!
//! Structure of XMM register and it's memory mapping:
//!
//! ~~~
//! Memory Bytes
//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
//! |00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
//!
//! XMM Register
//! +-----------------------------------------------+
//! | OWord |
//! +-----------------------+-----------------------+
//! | HI-QWord/PD | LO-QWord/SD |
//! +-----------+-----------+-----------+-----------+
//! | D3/PS | D2/PS | D1/PS | D0/SS |
//! +-----------+-----------+-----------+-----------+
//! | W7 | W6 | W5 | W4 | W3 | W2 | W1 | W0 |
//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
//! |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
//! ~~~
//!
//! 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.
//!
//! - `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`
//! (the rest is zeroed only if the source operand is a memory location).
//!
//! - `movaps`,
//! `movups`,
//! `movapd`,
//! `movupd`,
//! `movdqu`,
//! `movdqa`,
//! `lddqu` - writes 16-bytes in `OWord`.
//!
//! - `movlps`,
//! `movlpd`,
//! `movhlps` - writes 8-bytes in `Lo-QWord` and keeps the rest untouched.
//!
//! - `movhps`,
//! `movhpd`,
//! `movlhps` - writes 8-bytes in `Hi-QWord` and keeps the rest untouched.
//!
//! - `movddup`,
//! - `movsldup`,
//! - `movshdup` - writes 16 bytes in `OWord`.
struct X86XmmReg : public X86Reg {
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
//! Create a dummy Xmm register.
ASMJIT_INLINE X86XmmReg() : X86Reg() {}
//! Create a reference to `other` Xmm register.
ASMJIT_INLINE X86XmmReg(const X86XmmReg& other) : X86Reg(other) {}
//! Create a reference to `other` Xmm register and change the index to `index`.
ASMJIT_INLINE X86XmmReg(const X86XmmReg& other, uint32_t index) : X86Reg(other, index) {}
//! Create a custom Xmm register.
ASMJIT_INLINE X86XmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
//! Create non-initialized Xmm register.
explicit ASMJIT_INLINE X86XmmReg(const _NoInit&) : X86Reg(NoInit) {}
// --------------------------------------------------------------------------
// [X86XmmReg Specific]
// --------------------------------------------------------------------------
ASMJIT_REG_OP(X86XmmReg)
// --------------------------------------------------------------------------
// [X86XmmReg Cast]
// --------------------------------------------------------------------------
//! Cast this register to Xmm (clone).
ASMJIT_INLINE X86XmmReg xmm() const { return X86XmmReg(kX86RegTypeXmm, getRegIndex(), 16); }
//! Cast this register to Ymm.
ASMJIT_INLINE X86YmmReg ymm() const;
//! Cast this register to Zmm.
ASMJIT_INLINE X86ZmmReg zmm() const;
};
// ============================================================================
// [asmjit::X86YmmReg]
// ============================================================================
//! X86/X64 256-bit Ymm register (AVX+).
//!
//! Structure of YMM register and it's memory mapping:
//!
//! ~~~
//! Memory Bytes
//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
//! |00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
//!
//! YMM Register
//! +-----------------------------------------------+-----------------------------------------------+
//! | HI-DQWord | LO-DQWord |
//! +-----------------------+-----------------------+-----------------------+-----------------------+
//! | Q3/PD | Q2/PD | Q1/PD | Q0/SD |
//! +-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
//! | D7/PS | D6/PS | D5/PS | D4/PS | D3/PS | D2/PS | D1/PS | D0/SS |
//! +-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
//! | W15 | W14 | W13 | W12 | W11 | W10 | W9 | W8 | W7 | W6 | W5 | W4 | W3 | W2 | W1 | W0 |
//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
//! |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
//! ~~~
struct X86YmmReg : public X86Reg {
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
//! Create a dummy Ymm register.
ASMJIT_INLINE X86YmmReg() : X86Reg() {}
//! Create a reference to `other` Ymm register.
ASMJIT_INLINE X86YmmReg(const X86YmmReg& other) : X86Reg(other) {}
//! Create a reference to `other` Ymm register and change the index to `index`.
ASMJIT_INLINE X86YmmReg(const X86YmmReg& other, uint32_t index) : X86Reg(other, index) {}
//! Create a custom Ymm register.
ASMJIT_INLINE X86YmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
//! Create non-initialized Ymm register.
explicit ASMJIT_INLINE X86YmmReg(const _NoInit&) : X86Reg(NoInit) {}
// --------------------------------------------------------------------------
// [X86YmmReg Specific]
// --------------------------------------------------------------------------
ASMJIT_REG_OP(X86YmmReg)
// --------------------------------------------------------------------------
// [X86YmmReg Cast]
// --------------------------------------------------------------------------
//! Cast this register to Xmm.
ASMJIT_INLINE X86XmmReg xmm() const { return X86XmmReg(kX86RegTypeXmm, getRegIndex(), 16); }
//! Cast this register to Ymm (clone).
ASMJIT_INLINE X86YmmReg ymm() const { return X86YmmReg(kX86RegTypeYmm, getRegIndex(), 32); }
//! Cast this register to Zmm.
ASMJIT_INLINE X86ZmmReg zmm() const;
};
ASMJIT_INLINE X86YmmReg X86XmmReg::ymm() const { return X86YmmReg(kX86RegTypeYmm, getRegIndex(), 32); }
// ============================================================================
// [asmjit::X86ZmmReg]
// ============================================================================
//! X86/X64 512-bit Zmm register (AVX512+).
struct X86ZmmReg : public X86Reg {
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
//! Create a dummy Zmm register.
ASMJIT_INLINE X86ZmmReg() : X86Reg() {}
//! Create a reference to `other` Zmm register.
ASMJIT_INLINE X86ZmmReg(const X86ZmmReg& other) : X86Reg(other) {}
//! Create a reference to `other` Zmm register and change the index to `index`.
ASMJIT_INLINE X86ZmmReg(const X86ZmmReg& other, uint32_t index) : X86Reg(other, index) {}
//! Create a custom Zmm register.
ASMJIT_INLINE X86ZmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {}
//! Create non-initialized Zmm register.
explicit ASMJIT_INLINE X86ZmmReg(const _NoInit&) : X86Reg(NoInit) {}
// --------------------------------------------------------------------------
// [X86ZmmReg Specific]
// --------------------------------------------------------------------------
ASMJIT_REG_OP(X86ZmmReg)
// --------------------------------------------------------------------------
// [X86ZmmReg Cast]
// --------------------------------------------------------------------------
//! Cast this register to Xmm.
ASMJIT_INLINE X86XmmReg xmm() const { return X86XmmReg(kX86RegTypeXmm, getRegIndex(), 16); }
//! Cast this register to Ymm.
ASMJIT_INLINE X86YmmReg ymm() const { return X86YmmReg(kX86RegTypeYmm, getRegIndex(), 32); }
//! Cast this register to Zmm (clone).
ASMJIT_INLINE X86ZmmReg zmm() const { return X86ZmmReg(kX86RegTypeZmm, getRegIndex(), 64); }
};
ASMJIT_INLINE X86ZmmReg X86XmmReg::zmm() const { return X86ZmmReg(kX86RegTypeZmm, getRegIndex(), 64); }
ASMJIT_INLINE X86ZmmReg X86YmmReg::zmm() const { return X86ZmmReg(kX86RegTypeZmm, getRegIndex(), 64); }
// ============================================================================
// [asmjit::X86Mem]
// ============================================================================
//! X86 memory operand.
struct X86Mem : public BaseMem {
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
ASMJIT_INLINE X86Mem() : BaseMem(NoInit) {
reset();
}
ASMJIT_INLINE X86Mem(const Label& label, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeLabel, 0, label._base.id);
_init_packed_d2_d3(kInvalidValue, disp);
}
ASMJIT_INLINE X86Mem(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
ASMJIT_ASSERT(shift <= 3);
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeLabel,
(kX86MemVSibGpz << kX86MemVSibIndex)
+ (shift << kX86MemShiftIndex),
label.getId());
_vmem.index = index.getRegIndex();
_vmem.displacement = disp;
}
ASMJIT_INLINE X86Mem(const X86GpReg& base, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
_getGpdFlags(base)
+ (kX86MemVSibGpz << kX86MemVSibIndex),
base.getRegIndex());
_init_packed_d2_d3(kInvalidValue, disp);
}
ASMJIT_INLINE X86Mem(const X86GpReg& base, const X86GpReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
ASMJIT_ASSERT(shift <= 3);
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
_getGpdFlags(base) + (shift << kX86MemShiftIndex),
base.getRegIndex());
_vmem.index = index.getRegIndex();
_vmem.displacement = disp;
}
ASMJIT_INLINE X86Mem(const X86GpReg& base, const X86XmmReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
ASMJIT_ASSERT(shift <= 3);
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
_getGpdFlags(base)
+ (kX86MemVSibXmm << kX86MemVSibIndex)
+ (shift << kX86MemShiftIndex),
base.getRegIndex());
_vmem.index = index.getRegIndex();
_vmem.displacement = disp;
}
ASMJIT_INLINE X86Mem(const X86GpReg& base, const X86YmmReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
ASMJIT_ASSERT(shift <= 3);
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
_getGpdFlags(base)
+ (kX86MemVSibYmm << kX86MemVSibIndex)
+ (shift << kX86MemShiftIndex),
base.getRegIndex());
_vmem.index = index.getRegIndex();
_vmem.displacement = disp;
}
#if !defined(ASMJIT_DISABLE_COMPILER)
ASMJIT_INLINE X86Mem(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
ASMJIT_ASSERT(shift <= 3);
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeLabel,
(kX86MemVSibGpz << kX86MemVSibIndex)
+ (shift << kX86MemShiftIndex),
label.getId());
_vmem.index = ASMJIT_OP_ID(index);
_vmem.displacement = disp;
}
ASMJIT_INLINE X86Mem(const X86GpVar& base, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
_getGpdFlags(reinterpret_cast<const Var&>(base))
+ (kX86MemVSibGpz << kX86MemVSibIndex),
ASMJIT_OP_ID(base));
_init_packed_d2_d3(kInvalidValue, disp);
}
ASMJIT_INLINE X86Mem(const X86GpVar& base, const X86GpVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
ASMJIT_ASSERT(shift <= 3);
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
_getGpdFlags(reinterpret_cast<const Var&>(base))
+ (shift << kX86MemShiftIndex),
ASMJIT_OP_ID(base));
_vmem.index = ASMJIT_OP_ID(index);
_vmem.displacement = disp;
}
ASMJIT_INLINE X86Mem(const X86GpVar& base, const X86XmmVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
ASMJIT_ASSERT(shift <= 3);
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
_getGpdFlags(reinterpret_cast<const Var&>(base))
+ (kX86MemVSibXmm << kX86MemVSibIndex)
+ (shift << kX86MemShiftIndex),
ASMJIT_OP_ID(base));
_vmem.index = ASMJIT_OP_ID(index);
_vmem.displacement = disp;
}
ASMJIT_INLINE X86Mem(const X86GpVar& base, const X86YmmVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
ASMJIT_ASSERT(shift <= 3);
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
_getGpdFlags(reinterpret_cast<const Var&>(base))
+ (kX86MemVSibYmm << kX86MemVSibIndex)
+ (shift << kX86MemShiftIndex),
ASMJIT_OP_ID(base));
_vmem.index = ASMJIT_OP_ID(index);
_vmem.displacement = disp;
}
ASMJIT_INLINE X86Mem(const _Init&, uint32_t memType, const X86Var& base, int32_t disp, uint32_t size) : BaseMem(NoInit) {
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, 0, ASMJIT_OP_ID(base));
_vmem.index = kInvalidValue;
_vmem.displacement = disp;
}
ASMJIT_INLINE X86Mem(const _Init&, uint32_t memType, const X86Var& base, const X86GpVar& index, uint32_t shift, int32_t disp, uint32_t size) : BaseMem(NoInit) {
ASMJIT_ASSERT(shift <= 3);
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, shift << kX86MemShiftIndex, ASMJIT_OP_ID(base));
_vmem.index = ASMJIT_OP_ID(index);
_vmem.displacement = disp;
}
#endif // !ASMJIT_DISABLE_COMPILER
ASMJIT_INLINE X86Mem(const X86Mem& other) : BaseMem(other) {}
explicit ASMJIT_INLINE X86Mem(const _NoInit&) : BaseMem(NoInit) {}
// --------------------------------------------------------------------------
// [X86Mem Specific]
// --------------------------------------------------------------------------
//! Clone X86Mem operand.
ASMJIT_INLINE X86Mem clone() const {
return X86Mem(*this);
}
//! Reset X86Mem operand.
ASMJIT_INLINE void reset() {
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, 0, kMemTypeBaseIndex, 0, kInvalidValue);
_init_packed_d2_d3(kInvalidValue, 0);
}
//! \internal
ASMJIT_INLINE void _init(uint32_t memType, uint32_t base, int32_t disp, uint32_t size) {
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, 0, base);
_vmem.index = kInvalidValue;
_vmem.displacement = disp;
}
// --------------------------------------------------------------------------
// [Segment]
// --------------------------------------------------------------------------
//! Get whether the memory operand has segment override prefix.
ASMJIT_INLINE bool hasSegment() const {
return (_vmem.flags & kX86MemSegMask) != (kX86SegDefault << kX86MemSegIndex);
}
//! Get memory operand segment, see `X86Seg`.
ASMJIT_INLINE uint32_t getSegment() const {
return (static_cast<uint32_t>(_vmem.flags) >> kX86MemSegIndex) & kX86MemSegBits;
}
//! Set memory operand segment, see `X86Seg`.
ASMJIT_INLINE X86Mem& setSegment(uint32_t segIndex) {
_vmem.flags = static_cast<uint8_t>(
(static_cast<uint32_t>(_vmem.flags) & kX86MemSegMask) + (segIndex << kX86MemSegIndex));
return *this;
}
//! Set memory operand segment, see `X86Seg`.
ASMJIT_INLINE X86Mem& setSegment(const X86SegReg& seg) {
return setSegment(seg.getRegIndex());
}
// --------------------------------------------------------------------------
// [Gpd]
// --------------------------------------------------------------------------
//! Get whether the memory operand has 32-bit GP base.
ASMJIT_INLINE bool hasGpdBase() const {
return (_packed[0].u32[0] & IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemGpdMask)) != 0;
}
//! Set whether the memory operand has 32-bit GP base.
ASMJIT_INLINE X86Mem& setGpdBase() {
_packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemGpdMask);
return *this;
}
//! Set whether the memory operand has 32-bit GP base to `b`.
ASMJIT_INLINE X86Mem& setGpdBase(uint32_t b) {
_packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemGpdMask);
_packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, b << kX86MemGpdIndex);
return *this;
}
// --------------------------------------------------------------------------
// [VSib]
// --------------------------------------------------------------------------
//! Get V-SIB type.
ASMJIT_INLINE uint32_t getVSib() const {
return (static_cast<uint32_t>(_vmem.flags) >> kX86MemVSibIndex) & kX86MemVSibBits;
}
//! Set V-SIB type.
ASMJIT_INLINE X86Mem& _setVSib(uint32_t vsib) {
_packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemVSibMask);
_packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, vsib << kX86MemVSibIndex);
return *this;
}
// --------------------------------------------------------------------------
// [Size]
// --------------------------------------------------------------------------
//! Set memory operand size.
ASMJIT_INLINE X86Mem& setSize(uint32_t size) {
_vmem.size = static_cast<uint8_t>(size);
return *this;
}
// --------------------------------------------------------------------------
// [Base]
// --------------------------------------------------------------------------
//! Get whether the memory operand has base register.
ASMJIT_INLINE bool hasBase() const {
return _vmem.base != kInvalidValue;
}
//! Get memory operand base register code, variable id, or `kInvalidValue`.
ASMJIT_INLINE uint32_t getBase() const {
return _vmem.base;
}
//! Set memory operand base register code, variable id, or `kInvalidValue`.
ASMJIT_INLINE X86Mem& setBase(uint32_t base) {
_vmem.base = base;
return *this;
}
// --------------------------------------------------------------------------
// [Index]
// --------------------------------------------------------------------------
//! Get whether the memory operand has index.
ASMJIT_INLINE bool hasIndex() const {
return _vmem.index != kInvalidValue;
}
//! Get memory operand index register code, variable id, or `kInvalidValue`.
ASMJIT_INLINE uint32_t getIndex() const {
return _vmem.index;
}
//! Set memory operand index register code, variable id, or `kInvalidValue`.
ASMJIT_INLINE X86Mem& setIndex(uint32_t index) {
_vmem.index = index;
return *this;
}
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86GpReg& index) {
_vmem.index = index.getRegIndex();
return _setVSib(kX86MemVSibGpz);
}
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86GpReg& index, uint32_t shift) {
_vmem.index = index.getRegIndex();
return _setVSib(kX86MemVSibGpz).setShift(shift);
}
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86XmmReg& index) {
_vmem.index = index.getRegIndex();
return _setVSib(kX86MemVSibXmm);
}
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86XmmReg& index, uint32_t shift) {
_vmem.index = index.getRegIndex();
return _setVSib(kX86MemVSibXmm).setShift(shift);
}
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86YmmReg& index) {
_vmem.index = index.getRegIndex();
return _setVSib(kX86MemVSibYmm);
}
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86YmmReg& index, uint32_t shift) {
_vmem.index = index.getRegIndex();
return _setVSib(kX86MemVSibYmm).setShift(shift);
}
#if !defined(ASMJIT_DISABLE_COMPILER)
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86GpVar& index) {
_vmem.index = ASMJIT_OP_ID(index);
return _setVSib(kX86MemVSibGpz);
}
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86GpVar& index, uint32_t shift) {
_vmem.index = ASMJIT_OP_ID(index);
return _setVSib(kX86MemVSibGpz).setShift(shift);
}
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86XmmVar& index) {
_vmem.index = ASMJIT_OP_ID(index);
return _setVSib(kX86MemVSibXmm);
}
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86XmmVar& index, uint32_t shift) {
_vmem.index = ASMJIT_OP_ID(index);
return _setVSib(kX86MemVSibXmm).setShift(shift);
}
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86YmmVar& index) {
_vmem.index = ASMJIT_OP_ID(index);
return _setVSib(kX86MemVSibYmm);
}
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86YmmVar& index, uint32_t shift) {
_vmem.index = ASMJIT_OP_ID(index);
return _setVSib(kX86MemVSibYmm).setShift(shift);
}
#endif // !ASMJIT_DISABLE_COMPILER
//! Reset memory index.
ASMJIT_INLINE X86Mem& resetIndex() {
_vmem.index = kInvalidValue;
return _setVSib(kX86MemVSibGpz);
}
// --------------------------------------------------------------------------
// [Misc]
// --------------------------------------------------------------------------
//! Get whether the memory operand has base and index register.
ASMJIT_INLINE bool hasBaseOrIndex() const {
return _vmem.base != kInvalidValue || _vmem.index != kInvalidValue;
}
//! Get whether the memory operand has base and index register.
ASMJIT_INLINE bool hasBaseAndIndex() const {
return _vmem.base != kInvalidValue && _vmem.index != kInvalidValue;
}
// --------------------------------------------------------------------------
// [Shift]
// --------------------------------------------------------------------------
//! Get whether the memory operand has shift used.
ASMJIT_INLINE bool hasShift() const {
return (_vmem.flags & kX86MemShiftMask) != 0;
}
//! Get memory operand index scale (0, 1, 2 or 3).
ASMJIT_INLINE uint32_t getShift() const {
return _vmem.flags >> kX86MemShiftIndex;
}
//! Set memory operand index scale (0, 1, 2 or 3).
ASMJIT_INLINE X86Mem& setShift(uint32_t shift) {
_packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemShiftMask);
_packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, shift << kX86MemShiftIndex);
return *this;
}
// --------------------------------------------------------------------------
// [Displacement]
// --------------------------------------------------------------------------
//! Get memory operand relative displacement.
ASMJIT_INLINE int32_t getDisplacement() const {
return _vmem.displacement;
}
//! Set memory operand relative displacement.
ASMJIT_INLINE X86Mem& setDisplacement(int32_t disp) {
_vmem.displacement = disp;
return *this;
}
//! Reset memory operand relative displacement.
ASMJIT_INLINE X86Mem& resetDisplacement(int32_t disp) {
_vmem.displacement = 0;
return *this;
}
//! Adjust memory operand relative displacement by `disp`.
ASMJIT_INLINE X86Mem& adjust(int32_t disp) {
_vmem.displacement += disp;
return *this;
}
//! Get new memory operand adjusted by `disp`.
ASMJIT_INLINE X86Mem adjusted(int32_t disp) const {
X86Mem result(*this);
result.adjust(disp);
return result;
}
// --------------------------------------------------------------------------
// [Operator Overload]
// --------------------------------------------------------------------------
ASMJIT_INLINE X86Mem& operator=(const X86Mem& other) {
_copy(other);
return *this;
}
ASMJIT_INLINE bool operator==(const X86Mem& other) const {
return (_packed[0] == other._packed[0]) & (_packed[1] == other._packed[1]) ;
}
ASMJIT_INLINE bool operator!=(const X86Mem& other) const {
return !(*this == other);
}
// --------------------------------------------------------------------------
// [Static]
// --------------------------------------------------------------------------
static ASMJIT_INLINE uint32_t _getGpdFlags(const Operand& base) {
return (base._vreg.size & 0x4) << (kX86MemGpdIndex - 2);
}
};
#endif // ASMJIT_EXPORTS_X86OPERAND_REGS
// ============================================================================
// [asmjit::X86RegData]
// ============================================================================
struct X86RegData {
X86RipReg rip;
X86GpReg noGp;
X86SegReg seg[7];
X86GpReg gpbLo[16];
X86GpReg gpbHi[4];
X86GpReg gpw[16];
X86GpReg gpd[16];
X86GpReg gpq[16];
X86FpReg fp[8];
X86MmReg mm[8];
X86KReg k[8];
X86XmmReg xmm[32];
X86YmmReg ymm[32];
X86ZmmReg zmm[32];
};
ASMJIT_VAR const X86RegData x86RegData;
// ============================================================================
// [asmjit::x86]
// ============================================================================
namespace x86 {
// ============================================================================
// [asmjit::x86 - Reg]
// ============================================================================
#define ASMJIT_DEF_REG(_Type_, _Name_, _Field_) \
static const _Type_& _Name_ = x86RegData._Field_
ASMJIT_DEF_REG(X86RipReg, rip, rip); //!< RIP register.
ASMJIT_DEF_REG(X86GpReg , noGpReg, noGp); //!< No GP register (for `X86Mem` operand.).
ASMJIT_DEF_REG(X86SegReg, es , seg[1]); //!< Cs segment register.
ASMJIT_DEF_REG(X86SegReg, cs , seg[2]); //!< Ss segment register.
ASMJIT_DEF_REG(X86SegReg, ss , seg[3]); //!< Ds segment register.
ASMJIT_DEF_REG(X86SegReg, ds , seg[4]); //!< Es segment register.
ASMJIT_DEF_REG(X86SegReg, fs , seg[5]); //!< Fs segment register.
ASMJIT_DEF_REG(X86SegReg, gs , seg[6]); //!< Gs segment register.
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 , 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 , 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 , 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(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(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(X86KReg , k0 , k[0]); //!< 64-bit K register.
ASMJIT_DEF_REG(X86KReg , k1 , k[1]); //!< 64-bit K register.
ASMJIT_DEF_REG(X86KReg , k2 , k[2]); //!< 64-bit K register.
ASMJIT_DEF_REG(X86KReg , k3 , k[3]); //!< 64-bit K register.
ASMJIT_DEF_REG(X86KReg , k4 , k[4]); //!< 64-bit K register.
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(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(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+).
#undef ASMJIT_DEF_REG
// This is only defined by `x86operand_regs.cpp` when exporting registers.
#if !defined(ASMJIT_EXPORTS_X86OPERAND_REGS)
//! Create 8-bit Gpb-lo register operand.
static ASMJIT_INLINE X86GpReg gpb_lo(uint32_t index) { return X86GpReg(kX86RegTypeGpbLo, index, 1); }
//! Create 8-bit Gpb-hi register operand.
static ASMJIT_INLINE X86GpReg gpb_hi(uint32_t index) { return X86GpReg(kX86RegTypeGpbHi, index, 1); }
//! Create 16-bit Gpw register operand.
static ASMJIT_INLINE X86GpReg gpw(uint32_t index) { return X86GpReg(kX86RegTypeGpw, index, 2); }
//! Create 32-bit Gpd register operand.
static ASMJIT_INLINE X86GpReg gpd(uint32_t index) { return X86GpReg(kX86RegTypeGpd, index, 4); }
//! Create 64-bit Gpq register operand (X64).
static ASMJIT_INLINE X86GpReg gpq(uint32_t index) { return X86GpReg(kX86RegTypeGpq, index, 8); }
//! Create 80-bit Fp register operand.
static ASMJIT_INLINE X86FpReg fp(uint32_t index) { return X86FpReg(kX86RegTypeFp, index, 10); }
//! Create 64-bit Mm register operand.
static ASMJIT_INLINE X86MmReg mm(uint32_t index) { return X86MmReg(kX86RegTypeMm, index, 8); }
//! Create 64-bit K register operand.
static ASMJIT_INLINE X86KReg k(uint32_t index) { return X86KReg(kX86RegTypeK, index, 8); }
//! Create 128-bit Xmm register operand.
static ASMJIT_INLINE X86XmmReg xmm(uint32_t index) { return X86XmmReg(kX86RegTypeXmm, index, 16); }
//! Create 256-bit Ymm register operand.
static ASMJIT_INLINE X86YmmReg ymm(uint32_t index) { return X86YmmReg(kX86RegTypeYmm, index, 32); }
//! Create 512-bit Zmm register operand.
static ASMJIT_INLINE X86ZmmReg zmm(uint32_t index) { return X86ZmmReg(kX86RegTypeZmm, index, 64); }
// ============================================================================
// [asmjit::x86 - Ptr (Reg)]
// ============================================================================
//! Create `[base.reg + disp]` memory operand with no/custom size information.
static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, int32_t disp = 0, uint32_t size = 0) {
return X86Mem(base, disp, size);
}
//! Create `[base.reg + (index.reg << shift) + disp]` memory operand with no/custom size information.
static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
return X86Mem(base, index, shift, disp, size);
}
//! Create `[base.reg + (xmm.reg << shift) + disp]` memory operand with no/custom size information.
static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86XmmReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
return X86Mem(base, index, shift, disp, size);
}
//! Create `[base.reg + (ymm.reg << shift) + disp]` memory operand with no/custom size information.
static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
return X86Mem(base, index, shift, disp, size);
}
//! Create `[label + disp]` memory operand with no/custom size information.
static ASMJIT_INLINE X86Mem ptr(const Label& label, int32_t disp = 0, uint32_t size = 0) {
return X86Mem(label, disp, size);
}
//! Create `[label + (index.reg << shift) + disp]` memory operand with no/custom size information.
static ASMJIT_INLINE X86Mem ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0, uint32_t size = 0) { \
return X86Mem(label, index, shift, disp, size); \
}
//! Create `[pAbs + disp]` absolute memory operand with no/custom size information.
ASMJIT_API X86Mem ptr_abs(Ptr pAbs, int32_t disp = 0, uint32_t size = 0);
//! Create `[pAbs + (index.reg << shift) + disp]` absolute memory operand with no/custom size information.
ASMJIT_API X86Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0);
//! \internal
#define ASMJIT_EXPAND_PTR_REG(_Prefix_, _Size_) \
/*! Create `[base.reg + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, int32_t disp = 0) { \
return X86Mem(base, disp, _Size_); \
} \
/*! Create `[base.reg + (index.reg << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) { \
return ptr(base, index, shift, disp, _Size_); \
} \
/*! Create `[base.reg + (xmm.reg << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, const X86XmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \
return ptr(base, index, shift, disp, _Size_); \
} \
/*! Create `[base.reg + (ymm.reg << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \
return ptr(base, index, shift, disp, _Size_); \
} \
/*! Create `[label + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, int32_t disp = 0) { \
return ptr(label, disp, _Size_); \
} \
/*! Create `[label + (index.reg << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0) { \
return ptr(label, index, shift, disp, _Size_); \
} \
/*! Create `[pAbs + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, int32_t disp = 0) { \
return ptr_abs(pAbs, disp, _Size_); \
} \
/*! Create `[pAbs + (index.reg << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) { \
return ptr_abs(pAbs, index, shift, disp, _Size_); \
} \
/*! Create `[pAbs + (xmm.reg << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86XmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \
return ptr_abs(pAbs, index, shift, disp, _Size_); \
} \
/*! Create `[pAbs + (ymm.reg << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \
return ptr_abs(pAbs, index, shift, disp, _Size_); \
}
ASMJIT_EXPAND_PTR_REG(byte, 1)
ASMJIT_EXPAND_PTR_REG(word, 2)
ASMJIT_EXPAND_PTR_REG(dword, 4)
ASMJIT_EXPAND_PTR_REG(qword, 8)
ASMJIT_EXPAND_PTR_REG(tword, 10)
ASMJIT_EXPAND_PTR_REG(oword, 16)
ASMJIT_EXPAND_PTR_REG(yword, 32)
ASMJIT_EXPAND_PTR_REG(zword, 64)
#undef ASMJIT_EXPAND_PTR_REG
// ============================================================================
// [asmjit::x86 - Ptr (Var)]
// ============================================================================
#if !defined(ASMJIT_DISABLE_COMPILER)
//! Create `[base.var + disp]` memory operand with no/custom size information.
static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, int32_t disp = 0, uint32_t size = 0) {
return X86Mem(base, disp, size);
}
//! Create `[base.var + (index.var << shift) + disp]` memory operand with no/custom size information.
static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
return X86Mem(base, index, shift, disp, size);
}
//! Create `[base.var + (xmm.var << shift) + disp]` memory operand with no/custom size information.
static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, const X86XmmVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
return X86Mem(base, index, shift, disp, size);
}
//! Create `[base.var + (ymm.var << shift) + disp]` memory operand with no/custom size information.
static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, const X86YmmVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
return X86Mem(base, index, shift, disp, size);
}
//! Create `[label + (index.var << shift) + disp]` memory operand with no/custom size information.
static ASMJIT_INLINE X86Mem ptr(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp = 0, uint32_t size = 0) { \
return X86Mem(label, index, shift, disp, size); \
}
//! Create `[pAbs + (index.var << shift) + disp]` absolute memory operand with no/custom size information.
ASMJIT_API X86Mem ptr_abs(Ptr pAbs, const X86Var& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0);
//! \internal
#define ASMJIT_EXPAND_PTR_VAR(_Prefix_, _Size_) \
/*! Create `[base.var + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, int32_t disp = 0) { \
return X86Mem(base, disp, _Size_); \
} \
/*! Create `[base.var + (index.var << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) { \
return ptr(base, index, shift, disp, _Size_); \
} \
/*! Create `[base.var + (xmm.var << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, const X86XmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \
return ptr(base, index, shift, disp, _Size_); \
} \
/*! Create `[base.var + (ymm.var << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, const X86YmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \
return ptr(base, index, shift, disp, _Size_); \
} \
/*! Create `[label + (index.var << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp = 0) { \
return ptr(label, index, shift, disp, _Size_); \
} \
/*! Create `[pAbs + (index.var << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) { \
return ptr_abs(pAbs, reinterpret_cast<const X86Var&>(index), shift, disp, _Size_); \
} \
/*! Create `[pAbs + (xmm.var << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86XmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \
return ptr_abs(pAbs, reinterpret_cast<const X86Var&>(index), shift, disp, _Size_); \
} \
/*! Create `[pAbs + (ymm.var << shift) + disp]` memory operand. */ \
static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86YmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \
return ptr_abs(pAbs, reinterpret_cast<const X86Var&>(index), shift, disp, _Size_); \
}
ASMJIT_EXPAND_PTR_VAR(byte, 1)
ASMJIT_EXPAND_PTR_VAR(word, 2)
ASMJIT_EXPAND_PTR_VAR(dword, 4)
ASMJIT_EXPAND_PTR_VAR(qword, 8)
ASMJIT_EXPAND_PTR_VAR(tword, 10)
ASMJIT_EXPAND_PTR_VAR(oword, 16)
ASMJIT_EXPAND_PTR_VAR(yword, 32)
ASMJIT_EXPAND_PTR_VAR(zword, 64)
#undef ASMJIT_EXPAND_PTR_VAR
#endif // !ASMJIT_DISABLE_COMPILER
#endif // !ASMJIT_EXPORTS_X86OPERAND_REGS
} // x86 namespace
//! \}
} // asmjit namespace
// [Cleanup]
#undef ASMJIT_OP_ID
// [Api-End]
#include "../apiend.h"
// [Guard]
#endif // _ASMJIT_X86_X86OPERAND_H
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Export]
#define ASMJIT_EXPORTS
#define ASMJIT_EXPORTS_X86OPERAND_REGS
// [Guard]
#include "../build.h"
#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
// [Dependencies - AsmJit]
#include "../x86/x86operand.h"
// [Api-Begin]
#include "../apibegin.h"
namespace asmjit {
#define REG(_Type_, _Index_, _Size_) {{ \
kOperandTypeReg, _Size_, { ((_Type_) << 8) + _Index_ }, kInvalidValue, {{ kInvalidVar, 0 }} \
}}
const X86RegData x86RegData = {
// RIP.
REG(kX86RegTypeRip, 0, 0),
// NpGp.
REG(kInvalidReg, kInvalidReg, 0),
// Segments.
{
REG(kX86RegTypeSeg, 0, 2), // Default.
REG(kX86RegTypeSeg, 1, 2), // ES.
REG(kX86RegTypeSeg, 2, 2), // CS.
REG(kX86RegTypeSeg, 3, 2), // SS.
REG(kX86RegTypeSeg, 4, 2), // DS.
REG(kX86RegTypeSeg, 5, 2), // FS.
REG(kX86RegTypeSeg, 6, 2) // GS.
},
// GpbLo.
{
REG(kX86RegTypeGpbLo, 0, 1),
REG(kX86RegTypeGpbLo, 1, 1),
REG(kX86RegTypeGpbLo, 2, 1),
REG(kX86RegTypeGpbLo, 3, 1),
REG(kX86RegTypeGpbLo, 4, 1),
REG(kX86RegTypeGpbLo, 5, 1),
REG(kX86RegTypeGpbLo, 6, 1),
REG(kX86RegTypeGpbLo, 7, 1),
REG(kX86RegTypeGpbLo, 8, 1),
REG(kX86RegTypeGpbLo, 9, 1),
REG(kX86RegTypeGpbLo, 10, 1),
REG(kX86RegTypeGpbLo, 11, 1),
REG(kX86RegTypeGpbLo, 12, 1),
REG(kX86RegTypeGpbLo, 13, 1),
REG(kX86RegTypeGpbLo, 14, 1),
REG(kX86RegTypeGpbLo, 15, 1)
},
// GpbHi.
{
REG(kX86RegTypeGpbHi, 0, 1),
REG(kX86RegTypeGpbHi, 1, 1),
REG(kX86RegTypeGpbHi, 2, 1),
REG(kX86RegTypeGpbHi, 3, 1)
},
// Gpw.
{
REG(kX86RegTypeGpw, 0, 2),
REG(kX86RegTypeGpw, 1, 2),
REG(kX86RegTypeGpw, 2, 2),
REG(kX86RegTypeGpw, 3, 2),
REG(kX86RegTypeGpw, 4, 2),
REG(kX86RegTypeGpw, 5, 2),
REG(kX86RegTypeGpw, 6, 2),
REG(kX86RegTypeGpw, 7, 2),
REG(kX86RegTypeGpw, 8, 2),
REG(kX86RegTypeGpw, 9, 2),
REG(kX86RegTypeGpw, 10, 2),
REG(kX86RegTypeGpw, 11, 2),
REG(kX86RegTypeGpw, 12, 2),
REG(kX86RegTypeGpw, 13, 2),
REG(kX86RegTypeGpw, 14, 2),
REG(kX86RegTypeGpw, 15, 2)
},
// Gpd.
{
REG(kX86RegTypeGpd, 0, 4),
REG(kX86RegTypeGpd, 1, 4),
REG(kX86RegTypeGpd, 2, 4),
REG(kX86RegTypeGpd, 3, 4),
REG(kX86RegTypeGpd, 4, 4),
REG(kX86RegTypeGpd, 5, 4),
REG(kX86RegTypeGpd, 6, 4),
REG(kX86RegTypeGpd, 7, 4),
REG(kX86RegTypeGpd, 8, 4),
REG(kX86RegTypeGpd, 9, 4),
REG(kX86RegTypeGpd, 10, 4),
REG(kX86RegTypeGpd, 11, 4),
REG(kX86RegTypeGpd, 12, 4),
REG(kX86RegTypeGpd, 13, 4),
REG(kX86RegTypeGpd, 14, 4),
REG(kX86RegTypeGpd, 15, 4)
},
// Gpq.
{
REG(kX86RegTypeGpq, 0, 8),
REG(kX86RegTypeGpq, 1, 8),
REG(kX86RegTypeGpq, 2, 8),
REG(kX86RegTypeGpq, 3, 8),
REG(kX86RegTypeGpq, 4, 8),
REG(kX86RegTypeGpq, 5, 8),
REG(kX86RegTypeGpq, 6, 8),
REG(kX86RegTypeGpq, 7, 8),
REG(kX86RegTypeGpq, 8, 8),
REG(kX86RegTypeGpq, 9, 8),
REG(kX86RegTypeGpq, 10, 8),
REG(kX86RegTypeGpq, 11, 8),
REG(kX86RegTypeGpq, 12, 8),
REG(kX86RegTypeGpq, 13, 8),
REG(kX86RegTypeGpq, 14, 8),
REG(kX86RegTypeGpq, 15, 8)
},
// Fp.
{
REG(kX86RegTypeFp, 0, 10),
REG(kX86RegTypeFp, 1, 10),
REG(kX86RegTypeFp, 2, 10),
REG(kX86RegTypeFp, 3, 10),
REG(kX86RegTypeFp, 4, 10),
REG(kX86RegTypeFp, 5, 10),
REG(kX86RegTypeFp, 6, 10),
REG(kX86RegTypeFp, 7, 10)
},
// Mm.
{
REG(kX86RegTypeMm, 0, 8),
REG(kX86RegTypeMm, 1, 8),
REG(kX86RegTypeMm, 2, 8),
REG(kX86RegTypeMm, 3, 8),
REG(kX86RegTypeMm, 4, 8),
REG(kX86RegTypeMm, 5, 8),
REG(kX86RegTypeMm, 6, 8),
REG(kX86RegTypeMm, 7, 8)
},
// K.
{
REG(kX86RegTypeK, 0, 8),
REG(kX86RegTypeK, 1, 8),
REG(kX86RegTypeK, 2, 8),
REG(kX86RegTypeK, 3, 8),
REG(kX86RegTypeK, 4, 8),
REG(kX86RegTypeK, 5, 8),
REG(kX86RegTypeK, 6, 8),
REG(kX86RegTypeK, 7, 8)
},
// Xmm.
{
REG(kX86RegTypeXmm, 0, 16),
REG(kX86RegTypeXmm, 1, 16),
REG(kX86RegTypeXmm, 2, 16),
REG(kX86RegTypeXmm, 3, 16),
REG(kX86RegTypeXmm, 4, 16),
REG(kX86RegTypeXmm, 5, 16),
REG(kX86RegTypeXmm, 6, 16),
REG(kX86RegTypeXmm, 7, 16),
REG(kX86RegTypeXmm, 8, 16),
REG(kX86RegTypeXmm, 9, 16),
REG(kX86RegTypeXmm, 10, 16),
REG(kX86RegTypeXmm, 11, 16),
REG(kX86RegTypeXmm, 12, 16),
REG(kX86RegTypeXmm, 13, 16),
REG(kX86RegTypeXmm, 14, 16),
REG(kX86RegTypeXmm, 15, 16),
REG(kX86RegTypeXmm, 16, 16),
REG(kX86RegTypeXmm, 17, 16),
REG(kX86RegTypeXmm, 18, 16),
REG(kX86RegTypeXmm, 19, 16),
REG(kX86RegTypeXmm, 20, 16),
REG(kX86RegTypeXmm, 21, 16),
REG(kX86RegTypeXmm, 22, 16),
REG(kX86RegTypeXmm, 23, 16),
REG(kX86RegTypeXmm, 24, 16),
REG(kX86RegTypeXmm, 25, 16),
REG(kX86RegTypeXmm, 26, 16),
REG(kX86RegTypeXmm, 27, 16),
REG(kX86RegTypeXmm, 28, 16),
REG(kX86RegTypeXmm, 29, 16),
REG(kX86RegTypeXmm, 30, 16),
REG(kX86RegTypeXmm, 31, 16)
},
// Ymm.
{
REG(kX86RegTypeYmm, 0, 32),
REG(kX86RegTypeYmm, 1, 32),
REG(kX86RegTypeYmm, 2, 32),
REG(kX86RegTypeYmm, 3, 32),
REG(kX86RegTypeYmm, 4, 32),
REG(kX86RegTypeYmm, 5, 32),
REG(kX86RegTypeYmm, 6, 32),
REG(kX86RegTypeYmm, 7, 32),
REG(kX86RegTypeYmm, 8, 32),
REG(kX86RegTypeYmm, 9, 32),
REG(kX86RegTypeYmm, 10, 32),
REG(kX86RegTypeYmm, 11, 32),
REG(kX86RegTypeYmm, 12, 32),
REG(kX86RegTypeYmm, 13, 32),
REG(kX86RegTypeYmm, 14, 32),
REG(kX86RegTypeYmm, 15, 32),
REG(kX86RegTypeYmm, 16, 32),
REG(kX86RegTypeYmm, 17, 32),
REG(kX86RegTypeYmm, 18, 32),
REG(kX86RegTypeYmm, 19, 32),
REG(kX86RegTypeYmm, 20, 32),
REG(kX86RegTypeYmm, 21, 32),
REG(kX86RegTypeYmm, 22, 32),
REG(kX86RegTypeYmm, 23, 32),
REG(kX86RegTypeYmm, 24, 32),
REG(kX86RegTypeYmm, 25, 32),
REG(kX86RegTypeYmm, 26, 32),
REG(kX86RegTypeYmm, 27, 32),
REG(kX86RegTypeYmm, 28, 32),
REG(kX86RegTypeYmm, 29, 32),
REG(kX86RegTypeYmm, 30, 32),
REG(kX86RegTypeYmm, 31, 32)
},
// Zmm.
{
REG(kX86RegTypeZmm, 0, 64),
REG(kX86RegTypeZmm, 1, 64),
REG(kX86RegTypeZmm, 2, 64),
REG(kX86RegTypeZmm, 3, 64),
REG(kX86RegTypeZmm, 4, 64),
REG(kX86RegTypeZmm, 5, 64),
REG(kX86RegTypeZmm, 6, 64),
REG(kX86RegTypeZmm, 7, 64),
REG(kX86RegTypeZmm, 8, 64),
REG(kX86RegTypeZmm, 9, 64),
REG(kX86RegTypeZmm, 10, 64),
REG(kX86RegTypeZmm, 11, 64),
REG(kX86RegTypeZmm, 12, 64),
REG(kX86RegTypeZmm, 13, 64),
REG(kX86RegTypeZmm, 14, 64),
REG(kX86RegTypeZmm, 15, 64),
REG(kX86RegTypeZmm, 16, 64),
REG(kX86RegTypeZmm, 17, 64),
REG(kX86RegTypeZmm, 18, 64),
REG(kX86RegTypeZmm, 19, 64),
REG(kX86RegTypeZmm, 20, 64),
REG(kX86RegTypeZmm, 21, 64),
REG(kX86RegTypeZmm, 22, 64),
REG(kX86RegTypeZmm, 23, 64),
REG(kX86RegTypeZmm, 24, 64),
REG(kX86RegTypeZmm, 25, 64),
REG(kX86RegTypeZmm, 26, 64),
REG(kX86RegTypeZmm, 27, 64),
REG(kX86RegTypeZmm, 28, 64),
REG(kX86RegTypeZmm, 29, 64),
REG(kX86RegTypeZmm, 30, 64),
REG(kX86RegTypeZmm, 31, 64)
}
};
#undef REG
} // asmjit namespace
// [Api-End]
#include "../apiend.h"
// [Guard]
#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Export]
#define ASMJIT_EXPORTS
// [Guard]
#include "../build.h"
#if !defined(ASMJIT_DISABLE_COMPILER) && (defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64))
// [Dependencies - AsmJit]
#include "../base/containers.h"
#include "../x86/x86scheduler_p.h"
// [Api-Begin]
#include "../apibegin.h"
namespace asmjit {
// ============================================================================
// [Internals]
// ============================================================================
//! \internal
struct X86ScheduleData {
//! Registers read by the instruction.
X86RegMask regsIn;
//! Registers written by the instruction.
X86RegMask regsOut;
//! Flags read by the instruction.
uint8_t flagsIn;
//! Flags written by the instruction.
uint8_t flagsOut;
//! How many `uops` or `cycles` the instruction takes.
uint8_t ops;
//! Instruction latency.
uint8_t latency;
//! Which ports the instruction can run at.
uint16_t ports;
//! \internal
uint16_t reserved;
//! All instructions that this instruction depends on.
PodList<InstNode*>::Link* dependsOn;
//! All instructions that use the result of this instruction.
PodList<InstNode*>::Link* usedBy;
};
// ============================================================================
// [asmjit::X86Scheduler - Construction / Destruction]
// ============================================================================
X86Scheduler::X86Scheduler(X86Compiler* compiler, const X86CpuInfo* cpuInfo) :
_compiler(compiler),
_cpuInfo(cpuInfo) {}
X86Scheduler::~X86Scheduler() {}
// ============================================================================
// [asmjit::X86Scheduler - Run]
// ============================================================================
Error X86Scheduler::run(Node* start, Node* stop) {
/*
ASMJIT_TLOG("[Schedule] === Begin ===");
Zone zone(8096 - kZoneOverhead);
Node* node_ = start;
while (node_ != stop) {
Node* next = node_->getNext();
ASMJIT_ASSERT(node_->getType() == kNodeTypeInst);
printf(" %s\n", X86Util::getInstInfo(static_cast<InstNode*>(node_)->getInstId()).getInstName());
node_ = next;
}
ASMJIT_TLOG("[Schedule] === End ===");
*/
return kErrorOk;
}
} // asmjit namespace
// [Api-End]
#include "../apiend.h"
// [Guard]
#endif // !ASMJIT_DISABLE_COMPILER && (ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64)
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Guard]
#ifndef _ASMJIT_X86_X86SCHEDULER_P_H
#define _ASMJIT_X86_X86SCHEDULER_P_H
#include "../build.h"
#if !defined(ASMJIT_DISABLE_COMPILER)
// [Dependencies - AsmJit]
#include "../x86/x86compiler.h"
#include "../x86/x86context_p.h"
#include "../x86/x86cpuinfo.h"
#include "../x86/x86inst.h"
// [Api-Begin]
#include "../apibegin.h"
namespace asmjit {
// ============================================================================
// [asmjit::X86Scheduler]
// ============================================================================
//! \internal
//!
//! X86 scheduler.
struct X86Scheduler {
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
X86Scheduler(X86Compiler* compiler, const X86CpuInfo* cpuInfo);
~X86Scheduler();
// --------------------------------------------------------------------------
// [Run]
// --------------------------------------------------------------------------
Error run(Node* start, Node* stop);
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
//! Attached compiler.
X86Compiler* _compiler;
//! CPU information used for scheduling.
const X86CpuInfo* _cpuInfo;
};
} // asmjit namespace
// [Api-End]
#include "../apiend.h"
// [Guard]
#endif // !ASMJIT_DISABLE_COMPILER
#endif // _ASMJIT_X86_X86SCHEDULER_P_H
-------------------------------------------------------------------------------------
Changes in version 1.2 (13 November 2005)
- irrXML now supports CDATA.
- some small bug fixes have been made, making irrXML compatible for .NET users who
have to struggle with the famous bool return bug in the .NET framework.
- There are two new method overloads: getAttributeValueAsInt() and
getAttributeValueAsFloat() now also take the index of the attribute as parameter.
Thanks to Patrik Müller who suggested and implemented this initially, the same
for the CDATA support.
-------------------------------------------------------------------------------------
Changes in version 1.1 (02 July 2005)
- irrxml is now also able to parse embedded text correctly when it is shorter than
2 characters.
- irrxml now treats whitespace quite intelligent and doesn't report it when it is
obviously used for formatting the xml file. (Text won't be reported when it only contains
whitespace and is shorter than 3 characters)
- irrxml won't crash anymore when the xml file is malformatted and an attribute has
an opening but no closing attribute.
- Removed a documentation which claimed that the xml parser doesn't work as the xml standard
when replacing special characters, which wasn't true.
-------------------------------------------------------------------------------------
Changes in version 1.0 (14 May 2005)
- Initial release
Linux Users: There are some tools at the web for reading .chm files (try http://xchm.sourceforge.net/).
You can find a html version of this documentation at http://xml.irrlicht3d.org/docu/index.html
\ No newline at end of file
# Project: irrXML
# Makefile created by Dev-C++ 4.9.8.0
CPP = g++
OBJ = ../src/irrXML.o test.o
LINKOBJ = ../src/irrXML.o test.o
LIBS = --no-export-all-symbols --add-stdcall-alias
CXXINCS = -I"../src"
BIN = example
CXXFLAGS = $(CXXINCS)
all: $(BIN)
clean:
rm -f $(OBJ) $(BIN)
$(BIN): $(LINKOBJ)
$(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)
../src/irrXML.o: ../src/irrXML.cpp
$(CPP) -c ../src/irrXML.cpp -o ../src/irrXML.o $(CXXFLAGS)
test.o: test.cpp
$(CPP) -c test.cpp -o test.o $(CXXFLAGS)
<?xml version="1.0"?>
<config>
<!--This is a config file for the Irrlicht Engine Mesh Viewer.-->
<startUpModel file="../../media/dwarf.x" />
<messageText caption="Irrlicht Engine Mesh Viewer">Welcome to the Mesh Viewer of the &quot;Irrlicht Engine&quot;. This program is able to load and display all 3D geometry and models, the Irrlicht Engine can.
Controls:
- Left mouse to rotate
- Right mouse to move
- Both buttons to zoom
Supported formats are:
- 3D Studio (.3ds)
- Cartography shop 4 (.csm)
- DirectX (.x)
- Maya (.obj)
- Milkshape (.ms3d)
- My3D (.my3D)
- OCT (.oct)
- Pulsar LMTools (.lmts)
- Quake 3 levels (.bsp)
- Quake 2 models (.md2)
Please note that this program is also a demo of the user interface capabilities of the engine, so for example the combo box in the toolbar has no function.
</messageText>
</config>
\ No newline at end of file
[Project]
FileName=C:\Development\Irrlicht\irrxml\example\irrXML.dev
Name=irrXML
Ver=1
IsCpp=1
Type=1
Compiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_CONSOLE -D_MBCS
CppCompiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_CONSOLE -D_MBCS
Includes=../src
Linker=-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32
Libs=
UnitCount=9
Folders=parser
[Unit1]
FileName=../src/CXMLReaderImpl.h
Folder=parser
Compile=1
CompileCpp=1
Link=1
Priority=1000
[Unit2]
FileName=../src/fast_atof.h
Folder=parser
Compile=1
CompileCpp=1
Link=1
Priority=1000
[Unit3]
FileName=../src/heapsort.h
Folder=parser
Compile=1
CompileCpp=1
Link=1
Priority=1000
[Unit4]
FileName=../src/irrArray.h
Folder=parser
Compile=1
CompileCpp=1
Link=1
Priority=1000
[Unit5]
FileName=../src/irrString.h
Folder=parser
Compile=1
CompileCpp=1
Link=1
Priority=1000
[Unit6]
FileName=../src/irrTypes.h
Folder=parser
Compile=1
CompileCpp=1
Link=1
Priority=1000
[Unit7]
FileName=../src/irrXML.cpp
Folder=parser
Compile=1
CompileCpp=1
Link=1
Priority=1000
[Unit8]
FileName=../src/irrXML.h
Folder=parser
Compile=1
CompileCpp=1
Link=1
Priority=1000
[Unit9]
FileName=./test.cpp
Folder=
Compile=1
CompileCpp=1
Link=1
Priority=1000
# Microsoft Developer Studio Project File - Name="irrXML" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** NICHT BEARBEITEN **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=irrXML - Win32 Debug
!MESSAGE Dies ist kein gltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fhren Sie den Befehl
!MESSAGE
!MESSAGE NMAKE /f "irrXML.mak".
!MESSAGE
!MESSAGE Sie knnen beim Ausfhren von NMAKE eine Konfiguration angeben
!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
!MESSAGE
!MESSAGE NMAKE /f "irrXML.mak" CFG="irrXML - Win32 Debug"
!MESSAGE
!MESSAGE Fr die Konfiguration stehen zur Auswahl:
!MESSAGE
!MESSAGE "irrXML - Win32 Release" (basierend auf "Win32 (x86) Console Application")
!MESSAGE "irrXML - Win32 Debug" (basierend auf "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "irrXML - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "../src" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0xc07 /d "NDEBUG"
# ADD RSC /l 0xc07 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "irrXML - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../src" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0xc07 /d "_DEBUG"
# ADD RSC /l 0xc07 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "irrXML - Win32 Release"
# Name "irrXML - Win32 Debug"
# Begin Group "parser"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\src\CXMLReaderImpl.h
# End Source File
# Begin Source File
SOURCE=..\src\fast_atof.h
# End Source File
# Begin Source File
SOURCE=..\src\heapsort.h
# End Source File
# Begin Source File
SOURCE=..\src\irrArray.h
# End Source File
# Begin Source File
SOURCE=..\src\irrString.h
# End Source File
# Begin Source File
SOURCE=..\src\irrTypes.h
# End Source File
# Begin Source File
SOURCE=..\src\irrXML.cpp
# End Source File
# Begin Source File
SOURCE=..\src\irrXML.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\test.cpp
# End Source File
# End Target
# End Project
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELSCHT WERDEN!
###############################################################################
Project: "irrXML"=.\irrXML.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "irrxml", "irrxml.vcproj", "{2CDC9E2F-2CE6-4917-8BB9-DBA8E44C9A82}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{2CDC9E2F-2CE6-4917-8BB9-DBA8E44C9A82}.Debug.ActiveCfg = Debug|Win32
{2CDC9E2F-2CE6-4917-8BB9-DBA8E44C9A82}.Debug.Build.0 = Debug|Win32
{2CDC9E2F-2CE6-4917-8BB9-DBA8E44C9A82}.Release.ActiveCfg = Release|Win32
{2CDC9E2F-2CE6-4917-8BB9-DBA8E44C9A82}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="irrxml"
ProjectGUID="{2CDC9E2F-2CE6-4917-8BB9-DBA8E44C9A82}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../src"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/irrxml.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/irrxml.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../src"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/irrxml.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="parser"
Filter="">
<File
RelativePath="..\src\CXMLReaderImpl.h">
</File>
<File
RelativePath="..\src\fast_atof.h">
</File>
<File
RelativePath="..\src\heapsort.h">
</File>
<File
RelativePath="..\src\irrArray.h">
</File>
<File
RelativePath="..\src\irrString.h">
</File>
<File
RelativePath="..\src\irrTypes.h">
</File>
<File
RelativePath="..\src\irrXML.cpp">
</File>
<File
RelativePath="..\src\irrXML.h">
</File>
</Filter>
<File
RelativePath=".\test.cpp">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
#include <irrXML.h>
using namespace irr;
using namespace io;
#include <string> // we use STL strings to store data in this example
int main()
{
IrrXMLReader* xml = createIrrXMLReader("config.xml");
// strings for storing the data we want to get out of the file
std::string modelFile;
std::string messageText;
std::string caption;
// parse the file until end reached
while(xml && xml->read())
{
switch(xml->getNodeType())
{
case EXN_TEXT:
// in this xml file, the only text which occurs is the messageText
messageText = xml->getNodeData();
break;
case EXN_ELEMENT:
{
if (!strcmp("startUpModel", xml->getNodeName()))
modelFile = xml->getAttributeValue("file");
else
if (!strcmp("messageText", xml->getNodeName()))
caption = xml->getAttributeValue("caption");
}
break;
}
}
// delete the xml parser after usage
delete xml;
return 0;
}
// Copyright (C) 2002-2005 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine" and the "irrXML" project.
// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h
#ifndef __ICXML_READER_IMPL_H_INCLUDED__
#define __ICXML_READER_IMPL_H_INCLUDED__
#include "irrXML.h"
#include "irrString.h"
#include "irrArray.h"
#include "fast_atof.h"
#ifdef _DEBUG
#define IRR_DEBUGPRINT(x) printf((x));
#else // _DEBUG
#define IRR_DEBUGPRINT(x)
#endif // _DEBUG
namespace irr
{
namespace io
{
//! implementation of the IrrXMLReader
template<class char_type, class superclass>
class CXMLReaderImpl : public IIrrXMLReader<char_type, superclass>
{
public:
//! Constructor
CXMLReaderImpl(IFileReadCallBack* callback, bool deleteCallBack = true)
: TextData(0), P(0), TextSize(0), TextBegin(0), CurrentNodeType(EXN_NONE),
SourceFormat(ETF_ASCII), TargetFormat(ETF_ASCII)
{
if (!callback)
return;
storeTargetFormat();
// read whole xml file
readFile(callback);
// clean up
if (deleteCallBack)
delete callback;
// create list with special characters
createSpecialCharacterList();
// set pointer to text begin
P = TextBegin;
}
//! Destructor
virtual ~CXMLReaderImpl()
{
delete [] TextData;
}
//! Reads forward to the next xml node.
//! \return Returns false, if there was no further node.
virtual bool read()
{
// if not end reached, parse the node
if (P && (unsigned int)(P - TextBegin) < TextSize - 1 && *P != 0)
{
parseCurrentNode();
return true;
}
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return false;
}
//! Returns the type of the current XML node.
virtual EXML_NODE getNodeType() const
{
return CurrentNodeType;
}
//! Returns attribute count of the current XML node.
virtual int getAttributeCount() const
{
return Attributes.size();
}
//! Returns name of an attribute.
virtual const char_type* getAttributeName(int idx) const
{
if (idx < 0 || idx >= (int)Attributes.size())
return 0;
return Attributes[idx].Name.c_str();
}
//! Returns the value of an attribute.
virtual const char_type* getAttributeValue(int idx) const
{
if (idx < 0 || idx >= (int)Attributes.size())
return 0;
return Attributes[idx].Value.c_str();
}
//! Returns the value of an attribute.
virtual const char_type* getAttributeValue(const char_type* name) const
{
const SAttribute* attr = getAttributeByName(name);
if (!attr)
return 0;
return attr->Value.c_str();
}
//! Returns the value of an attribute
virtual const char_type* getAttributeValueSafe(const char_type* name) const
{
const SAttribute* attr = getAttributeByName(name);
if (!attr)
return EmptyString.c_str();
return attr->Value.c_str();
}
//! Returns the value of an attribute as integer.
int getAttributeValueAsInt(const char_type* name) const
{
return (int)getAttributeValueAsFloat(name);
}
//! Returns the value of an attribute as integer.
int getAttributeValueAsInt(int idx) const
{
return (int)getAttributeValueAsFloat(idx);
}
//! Returns the value of an attribute as float.
float getAttributeValueAsFloat(const char_type* name) const
{
const SAttribute* attr = getAttributeByName(name);
if (!attr)
return 0;
core::stringc c = attr->Value.c_str();
return core::fast_atof(c.c_str());
}
//! Returns the value of an attribute as float.
float getAttributeValueAsFloat(int idx) const
{
const char_type* attrvalue = getAttributeValue(idx);
if (!attrvalue)
return 0;
core::stringc c = attrvalue;
return core::fast_atof(c.c_str());
}
//! Returns the name of the current node.
virtual const char_type* getNodeName() const
{
return NodeName.c_str();
}
//! Returns data of the current node.
virtual const char_type* getNodeData() const
{
return NodeName.c_str();
}
//! Returns if an element is an empty element, like <foo />
virtual bool isEmptyElement() const
{
return IsEmptyElement;
}
//! Returns format of the source xml file.
virtual ETEXT_FORMAT getSourceFormat() const
{
return SourceFormat;
}
//! Returns format of the strings returned by the parser.
virtual ETEXT_FORMAT getParserFormat() const
{
return TargetFormat;
}
private:
// Reads the current xml node
void parseCurrentNode()
{
char_type* start = P;
// more forward until '<' found
while(*P != L'<' && *P)
++P;
if (!*P)
return;
if (P - start > 0)
{
// we found some text, store it
if (setText(start, P))
return;
}
++P;
// based on current token, parse and report next element
switch(*P)
{
case L'/':
parseClosingXMLElement();
break;
case L'?':
ignoreDefinition();
break;
case L'!':
if (!parseCDATA())
parseComment();
break;
default:
parseOpeningXMLElement();
break;
}
}
//! sets the state that text was found. Returns true if set should be set
bool setText(char_type* start, char_type* end)
{
// check if text is more than 2 characters, and if not, check if there is
// only white space, so that this text won't be reported
if (end - start < 3)
{
char_type* p = start;
for(; p != end; ++p)
if (!isWhiteSpace(*p))
break;
if (p == end)
return false;
}
// set current text to the parsed text, and replace xml special characters
core::string<char_type> s(start, (int)(end - start));
NodeName = replaceSpecialCharacters(s);
// current XML node type is text
CurrentNodeType = EXN_TEXT;
return true;
}
//! ignores an xml definition like <?xml something />
void ignoreDefinition()
{
CurrentNodeType = EXN_UNKNOWN;
// move until end marked with '>' reached
while(*P != L'>')
++P;
++P;
}
//! parses a comment
void parseComment()
{
CurrentNodeType = EXN_COMMENT;
P += 1;
char_type *pCommentBegin = P;
int count = 1;
// move until end of comment reached
while(count)
{
if (*P == L'>')
--count;
else
if (*P == L'<')
++count;
++P;
}
P -= 3;
NodeName = core::string<char_type>(pCommentBegin+2, (int)(P - pCommentBegin-2));
P += 3;
}
//! parses an opening xml element and reads attributes
void parseOpeningXMLElement()
{
CurrentNodeType = EXN_ELEMENT;
IsEmptyElement = false;
Attributes.clear();
// find name
const char_type* startName = P;
// find end of element
while(*P != L'>' && !isWhiteSpace(*P))
++P;
const char_type* endName = P;
// find Attributes
while(*P != L'>')
{
if (isWhiteSpace(*P))
++P;
else
{
if (*P != L'/')
{
// we've got an attribute
// read the attribute names
const char_type* attributeNameBegin = P;
while(!isWhiteSpace(*P) && *P != L'=')
++P;
const char_type* attributeNameEnd = P;
++P;
// read the attribute value
// check for quotes and single quotes, thx to murphy
while( (*P != L'\"') && (*P != L'\'') && *P)
++P;
if (!*P) // malformatted xml file
return;
const char_type attributeQuoteChar = *P;
++P;
const char_type* attributeValueBegin = P;
while(*P != attributeQuoteChar && *P)
++P;
if (!*P) // malformatted xml file
return;
const char_type* attributeValueEnd = P;
++P;
SAttribute attr;
attr.Name = core::string<char_type>(attributeNameBegin,
(int)(attributeNameEnd - attributeNameBegin));
core::string<char_type> s(attributeValueBegin,
(int)(attributeValueEnd - attributeValueBegin));
attr.Value = replaceSpecialCharacters(s);
Attributes.push_back(attr);
}
else
{
// tag is closed directly
++P;
IsEmptyElement = true;
break;
}
}
}
// check if this tag is closing directly
if (endName > startName && *(endName-1) == L'/')
{
// directly closing tag
IsEmptyElement = true;
endName--;
}
NodeName = core::string<char_type>(startName, (int)(endName - startName));
++P;
}
//! parses an closing xml tag
void parseClosingXMLElement()
{
CurrentNodeType = EXN_ELEMENT_END;
IsEmptyElement = false;
Attributes.clear();
++P;
const char_type* pBeginClose = P;
while(*P != L'>')
++P;
NodeName = core::string<char_type>(pBeginClose, (int)(P - pBeginClose));
++P;
}
//! parses a possible CDATA section, returns false if begin was not a CDATA section
bool parseCDATA()
{
if (*(P+1) != L'[')
return false;
CurrentNodeType = EXN_CDATA;
// skip '<![CDATA['
int count=0;
while( *P && count<8 )
{
++P;
++count;
}
if (!*P)
return true;
char_type *cDataBegin = P;
char_type *cDataEnd = 0;
// find end of CDATA
while(*P && !cDataEnd)
{
if (*P == L'>' &&
(*(P-1) == L']') &&
(*(P-2) == L']'))
{
cDataEnd = P - 2;
}
++P;
}
if ( cDataEnd )
NodeName = core::string<char_type>(cDataBegin, (int)(cDataEnd - cDataBegin));
else
NodeName = "";
return true;
}
// structure for storing attribute-name pairs
struct SAttribute
{
core::string<char_type> Name;
core::string<char_type> Value;
};
// finds a current attribute by name, returns 0 if not found
const SAttribute* getAttributeByName(const char_type* name) const
{
if (!name)
return 0;
core::string<char_type> n = name;
for (int i=0; i<(int)Attributes.size(); ++i)
if (Attributes[i].Name == n)
return &Attributes[i];
return 0;
}
// replaces xml special characters in a string and creates a new one
core::string<char_type> replaceSpecialCharacters(
core::string<char_type>& origstr)
{
int pos = origstr.findFirst(L'&');
int oldPos = 0;
if (pos == -1)
return origstr;
core::string<char_type> newstr;
while(pos != -1 && pos < origstr.size()-2)
{
// check if it is one of the special characters
int specialChar = -1;
for (int i=0; i<(int)SpecialCharacters.size(); ++i)
{
const char_type* p = &origstr.c_str()[pos]+1;
if (equalsn(&SpecialCharacters[i][1], p, SpecialCharacters[i].size()-1))
{
specialChar = i;
break;
}
}
if (specialChar != -1)
{
newstr.append(origstr.subString(oldPos, pos - oldPos));
newstr.append(SpecialCharacters[specialChar][0]);
pos += SpecialCharacters[specialChar].size();
}
else
{
newstr.append(origstr.subString(oldPos, pos - oldPos + 1));
pos += 1;
}
// find next &
oldPos = pos;
pos = origstr.findNext(L'&', pos);
}
if (oldPos < origstr.size()-1)
newstr.append(origstr.subString(oldPos, origstr.size()-oldPos));
return newstr;
}
//! reads the xml file and converts it into the wanted character format.
bool readFile(IFileReadCallBack* callback)
{
int size = callback->getSize();
size += 4; // We need two terminating 0's at the end.
// For ASCII we need 1 0's, for UTF-16 2, for UTF-32 4.
char* data8 = new char[size];
if (!callback->read(data8, size-4))
{
delete [] data8;
return false;
}
// add zeros at end
data8[size-1] = 0;
data8[size-2] = 0;
data8[size-3] = 0;
data8[size-4] = 0;
char16* data16 = reinterpret_cast<char16*>(data8);
char32* data32 = reinterpret_cast<char32*>(data8);
// now we need to convert the data to the desired target format
// based on the byte order mark.
const unsigned char UTF8[] = {0xEF, 0xBB, 0xBF}; // 0xEFBBBF;
const int UTF16_BE = 0xFFFE;
const int UTF16_LE = 0xFEFF;
const int UTF32_BE = 0xFFFE0000;
const int UTF32_LE = 0x0000FEFF;
// check source for all utf versions and convert to target data format
if (size >= 4 && data32[0] == (char32)UTF32_BE)
{
// UTF-32, big endian
SourceFormat = ETF_UTF32_BE;
convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header
}
else
if (size >= 4 && data32[0] == (char32)UTF32_LE)
{
// UTF-32, little endian
SourceFormat = ETF_UTF32_LE;
convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header
}
else
if (size >= 2 && data16[0] == UTF16_BE)
{
// UTF-16, big endian
SourceFormat = ETF_UTF16_BE;
convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header
}
else
if (size >= 2 && data16[0] == UTF16_LE)
{
// UTF-16, little endian
SourceFormat = ETF_UTF16_LE;
convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header
}
else
if (size >= 3 && data8[0] == UTF8[0] && data8[1] == UTF8[1] && data8[2] == UTF8[2])
{
// UTF-8
SourceFormat = ETF_UTF8;
convertTextData(data8+3, data8, size); // data8+3 because we need to skip the header
}
else
{
// ASCII
SourceFormat = ETF_ASCII;
convertTextData(data8, data8, size);
}
return true;
}
//! converts the text file into the desired format.
//! \param source: begin of the text (without byte order mark)
//! \param pointerToStore: pointer to text data block which can be
//! stored or deleted based on the nesessary conversion.
//! \param sizeWithoutHeader: Text size in characters without header
template<class src_char_type>
void convertTextData(src_char_type* source, char* pointerToStore, int sizeWithoutHeader)
{
// convert little to big endian if necessary
if (sizeof(src_char_type) > 1 &&
isLittleEndian(TargetFormat) != isLittleEndian(SourceFormat))
convertToLittleEndian(source);
// check if conversion is necessary:
if (sizeof(src_char_type) == sizeof(char_type))
{
// no need to convert
TextBegin = (char_type*)source;
TextData = (char_type*)pointerToStore;
TextSize = sizeWithoutHeader;
}
else
{
// convert source into target data format.
// TODO: implement a real conversion. This one just
// copies bytes. This is a problem when there are
// unicode symbols using more than one character.
TextData = new char_type[sizeWithoutHeader];
for (int i=0; i<sizeWithoutHeader; ++i)
TextData[i] = (char_type)source[i];
TextBegin = TextData;
TextSize = sizeWithoutHeader;
// delete original data because no longer needed
delete [] pointerToStore;
}
}
//! converts whole text buffer to little endian
template<class src_char_type>
void convertToLittleEndian(src_char_type* t)
{
if (sizeof(src_char_type) == 4)
{
// 32 bit
while(*t)
{
*t = ((*t & 0xff000000) >> 24) |
((*t & 0x00ff0000) >> 8) |
((*t & 0x0000ff00) << 8) |
((*t & 0x000000ff) << 24);
++t;
}
}
else
{
// 16 bit
while(*t)
{
*t = (*t >> 8) | (*t << 8);
++t;
}
}
}
//! returns if a format is little endian
inline bool isLittleEndian(ETEXT_FORMAT f)
{
return f == ETF_ASCII ||
f == ETF_UTF8 ||
f == ETF_UTF16_LE ||
f == ETF_UTF32_LE;
}
//! returns true if a character is whitespace
inline bool isWhiteSpace(char_type c)
{
return (c==' ' || c=='\t' || c=='\n' || c=='\r');
}
//! generates a list with xml special characters
void createSpecialCharacterList()
{
// list of strings containing special symbols,
// the first character is the special character,
// the following is the symbol string without trailing &.
SpecialCharacters.push_back("&amp;");
SpecialCharacters.push_back("<lt;");
SpecialCharacters.push_back(">gt;");
SpecialCharacters.push_back("\"quot;");
SpecialCharacters.push_back("'apos;");
}
//! compares the first n characters of the strings
bool equalsn(const char_type* str1, const char_type* str2, int len)
{
int i;
for(i=0; str1[i] && str2[i] && i < len; ++i)
if (str1[i] != str2[i])
return false;
// if one (or both) of the strings was smaller then they
// are only equal if they have the same lenght
return (i == len) || (str1[i] == 0 && str2[i] == 0);
}
//! stores the target text format
void storeTargetFormat()
{
// get target format. We could have done this using template specialization,
// but VisualStudio 6 don't like it and we want to support it.
switch(sizeof(char_type))
{
case 1:
TargetFormat = ETF_UTF8;
break;
case 2:
TargetFormat = ETF_UTF16_LE;
break;
case 4:
TargetFormat = ETF_UTF32_LE;
break;
default:
TargetFormat = ETF_ASCII; // should never happen.
}
}
// instance variables:
char_type* TextData; // data block of the text file
char_type* P; // current point in text to parse
char_type* TextBegin; // start of text to parse
unsigned int TextSize; // size of text to parse in characters, not bytes
EXML_NODE CurrentNodeType; // type of the currently parsed node
ETEXT_FORMAT SourceFormat; // source format of the xml file
ETEXT_FORMAT TargetFormat; // output format of this parser
core::string<char_type> NodeName; // name of the node currently in
core::string<char_type> EmptyString; // empty string to be returned by getSafe() methods
bool IsEmptyElement; // is the currently parsed node empty?
core::array< core::string<char_type> > SpecialCharacters; // see createSpecialCharacterList()
core::array<SAttribute> Attributes; // attributes of current element
}; // end CXMLReaderImpl
} // end namespace
} // end namespace
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment