Commit 97ce448c authored by peastman's avatar peastman
Browse files

Merge pull request #806 from peastman/jit32

Updated to latest asmjit, which supports 32 bit mode
parents fabb38d1 01da1b51
......@@ -73,14 +73,19 @@ ASMJIT_VAR const uint32_t _x86CondToJcc[20];
ASMJIT_VAR const uint32_t _x86CondToSetcc[20];
// ============================================================================
// [asmjit::kX86InstId]
// [asmjit::X86InstId]
// ============================================================================
//! X86/X64 instruction codes.
//! 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.
ASMJIT_ENUM(kX86InstId) {
//! 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
......@@ -111,7 +116,7 @@ ASMJIT_ENUM(kX86InstId) {
kX86InstIdBlsr, // BMI
kX86InstIdBsf, // X86/X64
kX86InstIdBsr, // X86/X64
kX86InstIdBswap, // X86/X64 (i486)
kX86InstIdBswap, // X86/X64 (i486+)
kX86InstIdBt, // X86/X64
kX86InstIdBtc, // X86/X64
kX86InstIdBtr, // X86/X64
......@@ -125,36 +130,36 @@ ASMJIT_ENUM(kX86InstId) {
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)
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
......@@ -164,12 +169,12 @@ ASMJIT_ENUM(kX86InstId) {
kX86InstIdCmpsW, // CMPS - X86/X64
kX86InstIdCmpsd, // SSE2
kX86InstIdCmpss, // SSE
kX86InstIdCmpxchg, // X86/X64 (i486)
kX86InstIdCmpxchg, // X86/X64 (i486+)
kX86InstIdCmpxchg16b, // X64 only
kX86InstIdCmpxchg8b, // X86/X64 (i586)
kX86InstIdCmpxchg8b, // X86/X64 (i586+)
kX86InstIdComisd, // SSE2
kX86InstIdComiss, // SSE
kX86InstIdCpuid, // X86/X64 (i486)
kX86InstIdCpuid, // X86/X64 (i486/i586+)
kX86InstIdCqo, // X64 only
kX86InstIdCrc32, // SSE4.2
kX86InstIdCvtdq2pd, // SSE2
......@@ -209,6 +214,7 @@ ASMJIT_ENUM(kX86InstId) {
kX86InstIdEmms, // MMX
kX86InstIdEnter, // X86/X64
kX86InstIdExtractps, // SSE4.1
kX86InstIdExtrq, // SSE4a
kX86InstIdF2xm1, // FPU
kX86InstIdFabs, // FPU
kX86InstIdFadd, // FPU
......@@ -313,6 +319,7 @@ ASMJIT_ENUM(kX86InstId) {
kX86InstIdImul, // X86/X64
kX86InstIdInc, // X86/X64
kX86InstIdInsertps, // SSE4.1
kX86InstIdInsertq, // SSE4a
kX86InstIdInt, // X86/X64
kX86InstIdJa, // X86/X64 (jcc)
kX86InstIdJae, // X86/X64 (jcc)
......@@ -393,6 +400,8 @@ ASMJIT_ENUM(kX86InstId) {
kX86InstIdMovntpd, // SSE2
kX86InstIdMovntps, // SSE
kX86InstIdMovntq, // MMX-Ext
kX86InstIdMovntsd, // SSE4a
kX86InstIdMovntss, // SSE4a
kX86InstIdMovq, // MMX/SSE/SSE2
kX86InstIdMovq2dq, // SSE2
kX86InstIdMovsB, // MOVS - X86/X64
......@@ -1125,11 +1134,19 @@ ASMJIT_ENUM(kX86InstId) {
kX86InstIdVzeroupper, // AVX
kX86InstIdWrfsbase, // FSGSBASE (x64)
kX86InstIdWrgsbase, // FSGSBASE (x64)
kX86InstIdXadd, // X86/X64 (i486)
kX86InstIdXchg, // X86/X64 (i386)
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,
......@@ -1142,34 +1159,59 @@ ASMJIT_ENUM(kX86InstId) {
};
// ============================================================================
// [asmjit::kX86InstOptions]
// [asmjit::X86InstOptions]
// ============================================================================
//! X86/X64 instruction emit options, mainly for internal purposes.
ASMJIT_ENUM(kX86InstOptions) {
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 = 0x10,
kX86InstOptionLock = 0x00000010,
//! Force REX prefix to be emitted.
//! Force REX prefix (X64).
//!
//! This option should be used carefully, because there are unencodable
//! combinations. If you want to access ah, bh, ch or dh registers the REX
//! prefix can't be emitted, otherwise illegal instruction error will be
//! returned.
kX86InstOptionRex = 0x40,
//! Force three-byte VEX prefix to be emitted (instead of more compact
//! two-byte VEX prefix).
//! 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
//!
//! Ignored if the instruction doesn't use VEX prefix.
kX86InstOptionVex3 = 0x80
//! 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::kX86InstGroup]
// [asmjit::X86InstEncodingId]
// ============================================================================
//! \internal
......@@ -1177,294 +1219,373 @@ ASMJIT_ENUM(kX86InstOptions) {
//! X86/X64 instruction groups.
//!
//! This group is specific to AsmJit and only used by `X86Assembler`.
ASMJIT_ENUM(kX86InstGroup) {
ASMJIT_ENUM(X86InstEncodingId) {
//! Never used.
kX86InstGroupNone,
kX86InstGroupX86Op,
kX86InstGroupX86Op_66H,
kX86InstGroupX86Rm,
kX86InstGroupX86Rm_B,
kX86InstGroupX86RmReg,
kX86InstGroupX86RegRm,
kX86InstGroupX86M,
kX86InstEncodingIdNone = 0,
kX86InstEncodingIdX86Op,
kX86InstEncodingIdX86Op_66H,
kX86InstEncodingIdX86Rm,
kX86InstEncodingIdX86Rm_B,
kX86InstEncodingIdX86RmReg,
kX86InstEncodingIdX86RegRm,
kX86InstEncodingIdX86M,
//! Adc/Add/And/Cmp/Or/Sbb/Sub/Xor.
kX86InstGroupX86Arith,
kX86InstEncodingIdX86Arith,
//! Bswap.
kX86InstGroupX86BSwap,
kX86InstEncodingIdX86BSwap,
//! Bt/Btc/Btr/Bts.
kX86InstGroupX86BTest,
kX86InstEncodingIdX86BTest,
//! Call.
kX86InstGroupX86Call,
kX86InstEncodingIdX86Call,
//! Enter.
kX86InstGroupX86Enter,
kX86InstEncodingIdX86Enter,
//! Imul.
kX86InstGroupX86Imul,
kX86InstEncodingIdX86Imul,
//! Inc/Dec.
kX86InstGroupX86IncDec,
kX86InstEncodingIdX86IncDec,
//! Int.
kX86InstGroupX86Int,
kX86InstEncodingIdX86Int,
//! Jcc.
kX86InstGroupX86Jcc,
kX86InstEncodingIdX86Jcc,
//! Jcxz/Jecxz/Jrcxz.
kX86InstGroupX86Jecxz,
kX86InstEncodingIdX86Jecxz,
//! Jmp.
kX86InstGroupX86Jmp,
kX86InstEncodingIdX86Jmp,
//! Lea.
kX86InstGroupX86Lea,
kX86InstEncodingIdX86Lea,
//! Mov.
kX86InstGroupX86Mov,
kX86InstEncodingIdX86Mov,
//! Movsx/Movzx.
kX86InstGroupX86MovSxZx,
kX86InstEncodingIdX86MovSxZx,
//! Movsxd.
kX86InstGroupX86MovSxd,
kX86InstEncodingIdX86MovSxd,
//! Mov having absolute memory operand (x86/x64).
kX86InstGroupX86MovPtr,
kX86InstEncodingIdX86MovPtr,
//! Push.
kX86InstGroupX86Push,
kX86InstEncodingIdX86Push,
//! Pop.
kX86InstGroupX86Pop,
kX86InstEncodingIdX86Pop,
//! Rep/Repe/Repne LodsX/MovsX/StosX/CmpsX/ScasX.
kX86InstGroupX86Rep,
kX86InstEncodingIdX86Rep,
//! Ret.
kX86InstGroupX86Ret,
kX86InstEncodingIdX86Ret,
//! Rcl/Rcr/Rol/Ror/Sal/Sar/Shl/Shr.
kX86InstGroupX86Rot,
kX86InstEncodingIdX86Rot,
//! Setcc.
kX86InstGroupX86Set,
kX86InstEncodingIdX86Set,
//! Shld/Rhrd.
kX86InstGroupX86Shlrd,
kX86InstEncodingIdX86Shlrd,
//! Test.
kX86InstGroupX86Test,
kX86InstEncodingIdX86Test,
//! Xadd.
kX86InstGroupX86Xadd,
kX86InstEncodingIdX86Xadd,
//! Xchg.
kX86InstGroupX86Xchg,
kX86InstEncodingIdX86Xchg,
//! Fincstp/Finit/FldX/Fnclex/Fninit/Fnop/Fpatan/Fprem/Fprem1/Fptan/Frndint/Fscale/Fsin/Fsincos/Fsqrt/Ftst/Fucompp/Fxam/Fxtract/Fyl2x/Fyl2xp1.
kX86InstGroupFpuOp,
kX86InstEncodingIdFpuOp,
//! Fadd/Fdiv/Fdivr/Fmul/Fsub/Fsubr.
kX86InstGroupFpuArith,
kX86InstEncodingIdFpuArith,
//! Fcom/Fcomp.
kX86InstGroupFpuCom,
kX86InstEncodingIdFpuCom,
//! Fld/Fst/Fstp.
kX86InstGroupFpuFldFst,
kX86InstEncodingIdFpuFldFst,
//! Fiadd/Ficom/Ficomp/Fidiv/Fidivr/Fild/Fimul/Fist/Fistp/Fisttp/Fisub/Fisubr.
kX86InstGroupFpuM,
kX86InstEncodingIdFpuM,
//! Fcmov/Fcomi/Fcomip/Ffree/Fucom/Fucomi/Fucomip/Fucomp/Fxch.
kX86InstGroupFpuR,
kX86InstEncodingIdFpuR,
//! Faddp/Fdivp/Fdivrp/Fmulp/Fsubp/Fsubrp.
kX86InstGroupFpuRDef,
kX86InstEncodingIdFpuRDef,
//! Fnstsw/Fstsw.
kX86InstGroupFpuStsw,
kX86InstEncodingIdFpuStsw,
//! Mm/Xmm instruction.
kX86InstGroupExtRm,
kX86InstEncodingIdExtRm,
//! Mm/Xmm instruction (propagates 66H if the instruction uses Xmm register).
kX86InstGroupExtRm_P,
kX86InstEncodingIdExtRm_P,
//! Mm/Xmm instruction (propagates REX.W if GPQ is used).
kX86InstGroupExtRm_Q,
kX86InstEncodingIdExtRm_Q,
//! Mm/Xmm instruction (propagates 66H and REX.W).
kX86InstGroupExtRm_PQ,
kX86InstEncodingIdExtRm_PQ,
//! Mm/Xmm instruction having Rm/Ri encodings.
kX86InstGroupExtRmRi,
kX86InstEncodingIdExtRmRi,
//! Mm/Xmm instruction having Rm/Ri encodings (propagates 66H if the instruction uses Xmm register).
kX86InstGroupExtRmRi_P,
kX86InstEncodingIdExtRmRi_P,
//! Mm/Xmm instruction having Rmi encoding.
kX86InstGroupExtRmi,
kX86InstEncodingIdExtRmi,
//! Mm/Xmm instruction having Rmi encoding (propagates 66H if the instruction uses Xmm register).
kX86InstGroupExtRmi_P,
kX86InstEncodingIdExtRmi_P,
//! Crc32.
kX86InstGroupExtCrc,
kX86InstEncodingIdExtCrc,
//! Pextrb/Pextrw/Pextrd/Pextrq/Extractps.
kX86InstGroupExtExtract,
kX86InstEncodingIdExtExtract,
//! Lfence/Mfence/Sfence.
kX86InstGroupExtFence,
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.
kX86InstGroupExtMov,
kX86InstEncodingIdExtMov,
//! Mov Mm/Xmm.
kX86InstGroupExtMovNoRexW,
kX86InstEncodingIdExtMovNoRexW,
//! Movbe.
kX86InstGroupExtMovBe,
kX86InstEncodingIdExtMovBe,
//! Movd.
kX86InstGroupExtMovD,
kX86InstEncodingIdExtMovD,
//! Movq.
kX86InstGroupExtMovQ,
kX86InstEncodingIdExtMovQ,
//! Prefetch.
kX86InstGroupExtPrefetch,
kX86InstEncodingIdExtPrefetch,
//! Extrq (SSE4a).
kX86InstEncodingIdExtExtrq,
//! Insrq (SSE4a).
kX86InstEncodingIdExtInsertq,
//! 3dNow instruction.
kX86InstGroup3dNow,
kX86InstEncodingId3dNow,
//! AVX instruction without operands.
kX86InstGroupAvxOp,
kX86InstEncodingIdAvxOp,
//! AVX instruction encoded as 'M'.
kX86InstGroupAvxM,
kX86InstEncodingIdAvxM,
//! AVX instruction encoded as 'MR'.
kX86InstGroupAvxMr,
kX86InstEncodingIdAvxMr,
//! AVX instruction encoded as 'MR' (Propagates AVX.L if Ymm used).
kX86InstGroupAvxMr_P,
kX86InstEncodingIdAvxMr_P,
//! AVX instruction encoded as 'MRI'.
kX86InstGroupAvxMri,
kX86InstEncodingIdAvxMri,
//! AVX instruction encoded as 'MRI' (Propagates AVX.L if Ymm used).
kX86InstGroupAvxMri_P,
kX86InstEncodingIdAvxMri_P,
//! AVX instruction encoded as 'RM'.
kX86InstGroupAvxRm,
kX86InstEncodingIdAvxRm,
//! AVX instruction encoded as 'RM' (Propagates AVX.L if Ymm used).
kX86InstGroupAvxRm_P,
kX86InstEncodingIdAvxRm_P,
//! AVX instruction encoded as 'RMI'.
kX86InstGroupAvxRmi,
kX86InstEncodingIdAvxRmi,
//! AVX instruction encoded as 'RMI' (Propagates AVX.L if Ymm used).
kX86InstGroupAvxRmi_P,
kX86InstEncodingIdAvxRmi_P,
//! AVX instruction encoded as 'RVM'.
kX86InstGroupAvxRvm,
kX86InstEncodingIdAvxRvm,
//! AVX instruction encoded as 'RVM' (Propagates AVX.L if Ymm used).
kX86InstGroupAvxRvm_P,
kX86InstEncodingIdAvxRvm_P,
//! AVX instruction encoded as 'RVMR'.
kX86InstGroupAvxRvmr,
kX86InstEncodingIdAvxRvmr,
//! AVX instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used).
kX86InstGroupAvxRvmr_P,
kX86InstEncodingIdAvxRvmr_P,
//! AVX instruction encoded as 'RVMI'.
kX86InstGroupAvxRvmi,
kX86InstEncodingIdAvxRvmi,
//! AVX instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used).
kX86InstGroupAvxRvmi_P,
kX86InstEncodingIdAvxRvmi_P,
//! AVX instruction encoded as 'RMV'.
kX86InstGroupAvxRmv,
kX86InstEncodingIdAvxRmv,
//! AVX instruction encoded as 'RMVI'.
kX86InstGroupAvxRmvi,
kX86InstEncodingIdAvxRmvi,
//! AVX instruction encoded as 'RM' or 'MR'.
kX86InstGroupAvxRmMr,
kX86InstEncodingIdAvxRmMr,
//! AVX instruction encoded as 'RM' or 'MR' (Propagates AVX.L if Ymm used).
kX86InstGroupAvxRmMr_P,
kX86InstEncodingIdAvxRmMr_P,
//! AVX instruction encoded as 'RVM' or 'RMI'.
kX86InstGroupAvxRvmRmi,
kX86InstEncodingIdAvxRvmRmi,
//! AVX instruction encoded as 'RVM' or 'RMI' (Propagates AVX.L if Ymm used).
kX86InstGroupAvxRvmRmi_P,
kX86InstEncodingIdAvxRvmRmi_P,
//! AVX instruction encoded as 'RVM' or 'MR'.
kX86InstGroupAvxRvmMr,
kX86InstEncodingIdAvxRvmMr,
//! AVX instruction encoded as 'RVM' or 'MVR'.
kX86InstGroupAvxRvmMvr,
kX86InstEncodingIdAvxRvmMvr,
//! AVX instruction encoded as 'RVM' or 'MVR' (Propagates AVX.L if Ymm used).
kX86InstGroupAvxRvmMvr_P,
kX86InstEncodingIdAvxRvmMvr_P,
//! AVX instruction encoded as 'RVM' or 'VMI'.
kX86InstGroupAvxRvmVmi,
kX86InstEncodingIdAvxRvmVmi,
//! AVX instruction encoded as 'RVM' or 'VMI' (Propagates AVX.L if Ymm used).
kX86InstGroupAvxRvmVmi_P,
kX86InstEncodingIdAvxRvmVmi_P,
//! AVX instruction encoded as 'VM'.
kX86InstGroupAvxVm,
kX86InstEncodingIdAvxVm,
//! AVX instruction encoded as 'VMI'.
kX86InstGroupAvxVmi,
kX86InstEncodingIdAvxVmi,
//! AVX instruction encoded as 'VMI' (Propagates AVX.L if Ymm used).
kX86InstGroupAvxVmi_P,
kX86InstEncodingIdAvxVmi_P,
//! AVX instruction encoded as 'RVRM' or 'RVMR'.
kX86InstGroupAvxRvrmRvmr,
kX86InstEncodingIdAvxRvrmRvmr,
//! AVX instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used).
kX86InstGroupAvxRvrmRvmr_P,
kX86InstEncodingIdAvxRvrmRvmr_P,
//! Vmovss/Vmovsd.
kX86InstGroupAvxMovSsSd,
kX86InstEncodingIdAvxMovSsSd,
//! AVX2 gather family instructions (VSIB).
kX86InstGroupAvxGather,
kX86InstEncodingIdAvxGather,
//! AVX2 gather family instructions (VSIB), differs only in mem operand.
kX86InstGroupAvxGatherEx,
kX86InstEncodingIdAvxGatherEx,
//! FMA4 instruction in form [R, R, R/M, R/M].
kX86InstGroupFma4,
kX86InstEncodingIdFma4,
//! FMA4 instruction in form [R, R, R/M, R/M] (Propagates AVX.L if Ymm used).
kX86InstGroupFma4_P,
kX86InstEncodingIdFma4_P,
//! XOP instruction encoded as 'RM'.
kX86InstGroupXopRm,
kX86InstEncodingIdXopRm,
//! XOP instruction encoded as 'RM' (Propagates AVX.L if Ymm used).
kX86InstGroupXopRm_P,
kX86InstEncodingIdXopRm_P,
//! XOP instruction encoded as 'RVM' or 'RMV'.
kX86InstGroupXopRvmRmv,
kX86InstEncodingIdXopRvmRmv,
//! XOP instruction encoded as 'RVM' or 'RMI'.
kX86InstGroupXopRvmRmi,
kX86InstEncodingIdXopRvmRmi,
//! XOP instruction encoded as 'RVMR'.
kX86InstGroupXopRvmr,
kX86InstEncodingIdXopRvmr,
//! XOP instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used).
kX86InstGroupXopRvmr_P,
kX86InstEncodingIdXopRvmr_P,
//! XOP instruction encoded as 'RVMI'.
kX86InstGroupXopRvmi,
kX86InstEncodingIdXopRvmi,
//! XOP instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used).
kX86InstGroupXopRvmi_P,
kX86InstEncodingIdXopRvmi_P,
//! XOP instruction encoded as 'RVRM' or 'RVMR'.
kX86InstGroupXopRvrmRvmr,
kX86InstEncodingIdXopRvrmRvmr,
//! XOP instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used).
kX86InstGroupXopRvrmRvmr_P,
kX86InstEncodingIdXopRvrmRvmr_P,
//! Count of X86 instruction groups.
_kX86InstGroupCount
_kX86InstEncodingIdCount
};
// ============================================================================
// [asmjit::kX86InstOpCode]
// [asmjit::X86InstOpCodeFlags]
// ============================================================================
//! \internal
//!
//! Instruction OpCode encoding used by asmjit 'X86InstInfo' table.
//! 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.
//!
//! The schema was inspired by AVX/AVX2 features.
ASMJIT_ENUM(kX86InstOpCode) {
// 'MMMMM' field in AVX/XOP instruction.
// 'OpCode' leading bytes in legacy encoding.
//! - `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_0F01 = 0x0FU << kX86InstOpCode_MM_Shift, // Ext/Not part of AVX.
kX86InstOpCode_MM_00011 = 0x03U << kX86InstOpCode_MM_Shift,
kX86InstOpCode_MM_01000 = 0x08U << kX86InstOpCode_MM_Shift,
kX86InstOpCode_MM_01001 = 0x09U << kX86InstOpCode_MM_Shift,
// 'PP' field in AVX/XOP instruction.
// 'Mandatory Prefix' in legacy encoding.
kX86InstOpCode_PP_Shift = 21,
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, // Ext/Not part of AVX.
// 'L' field in AVX/XOP instruction.
kX86InstOpCode_L_Shift = 24,
kX86InstOpCode_L_Mask = 0x01U << kX86InstOpCode_L_Shift,
kX86InstOpCode_L_False = 0x00U << kX86InstOpCode_L_Shift,
kX86InstOpCode_L_True = 0x01U << kX86InstOpCode_L_Shift,
// 'O' field.
kX86InstOpCode_O_Shift = 29,
kX86InstOpCode_O_Mask = 0x07U << kX86InstOpCode_O_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::kX86InstFlags]
// [asmjit::X86InstFlags]
// ============================================================================
//! \internal
//!
//! X86/X64 instruction type flags.
ASMJIT_ENUM(kX86InstFlags) {
//! X86/X64 instruction flags.
ASMJIT_ENUM(X86InstFlags) {
//! No flags.
kX86InstFlagNone = 0x0000,
kX86InstFlagNone = 0x00000000,
//! Instruction is a control-flow instruction.
//!
//! Control flow instructions are jmp, jcc, call and ret.
kX86InstFlagFlow = 0x0001,
kX86InstFlagFlow = 0x00000001,
//! Instruction is a compare/test like instruction.
kX86InstFlagTest = 0x0002,
kX86InstFlagTest = 0x00000002,
//! Instruction is a move like instruction.
//!
......@@ -1479,76 +1600,84 @@ ASMJIT_ENUM(kX86InstFlags) {
//! 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 = 0x0004,
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 = 0x0008,
kX86InstFlagXchg = 0x00000008,
//! Instruction accesses Fp register(s).
kX86InstFlagFp = 0x0010,
kX86InstFlagFp = 0x00000010,
//! Instruction can be prefixed by using the LOCK prefix.
kX86InstFlagLock = 0x0020,
kX86InstFlagLock = 0x00000020,
//! Instruction is special, this is for `Compiler`.
kX86InstFlagSpecial = 0x0040,
//! Instruction requires special handling, used by \ref Compiler.
kX86InstFlagSpecial = 0x00000040,
//! Instruction always performs memory access.
//!
//! This flag is always combined with `kX86InstFlagSpecial` and signalizes
//! 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 = 0x0080,
kX86InstFlagSpecialMem = 0x00000080,
//! Instruction memory operand can refer to 16-bit address (used by FPU).
kX86InstFlagMem2 = 0x0100,
kX86InstFlagMem2 = 0x00000100,
//! Instruction memory operand can refer to 32-bit address (used by FPU).
kX86InstFlagMem4 = 0x0200,
kX86InstFlagMem4 = 0x00000200,
//! Instruction memory operand can refer to 64-bit address (used by FPU).
kX86InstFlagMem8 = 0x0400,
kX86InstFlagMem8 = 0x00000400,
//! Instruction memory operand can refer to 80-bit address (used by FPU).
kX86InstFlagMem10 = 0x0800,
//! \internal
//!
//! Combination of `kX86InstFlagMem2` and `kX86InstFlagMem4`.
kX86InstFlagMem2_4 = kX86InstFlagMem2 | kX86InstFlagMem4,
//! \internal
//!
//! Combination of `kX86InstFlagMem2`, `kX86InstFlagMem4` and `kX86InstFlagMem8`.
kX86InstFlagMem2_4_8 = kX86InstFlagMem2_4 | kX86InstFlagMem8,
//! \internal
//!
//! Combination of `kX86InstFlagMem4` and `kX86InstFlagMem8`.
kX86InstFlagMem4_8 = kX86InstFlagMem4 | kX86InstFlagMem8,
//! \internal
//!
//! Combination of `kX86InstFlagMem4`, `kX86InstFlagMem8` and `kX86InstFlagMem10`.
kX86InstFlagMem4_8_10 = kX86InstFlagMem4_8 | kX86InstFlagMem10,
kX86InstFlagMem10 = 0x00000800,
//! Zeroes the rest of the register if the source operand is memory.
//!
//! Special behavior related to some SIMD load instructions.
kX86InstFlagZ = 0x1000,
//! REX.W/VEX.W by default.
kX86InstFlagW = 0x8000
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::kX86InstOp]
// [asmjit::X86InstOp]
// ============================================================================
//! \internal
//!
//! X86/X64 instruction operand flags.
ASMJIT_ENUM(kX86InstOp) {
ASMJIT_ENUM(X86InstOp) {
//! Instruction operand can be 8-bit Gpb register.
kX86InstOpGb = 0x0001,
//! Instruction operand can be 16-bit Gpw register.
......@@ -1557,10 +1686,15 @@ ASMJIT_ENUM(kX86InstOp) {
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 Mmx register.
//! 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.
......@@ -1569,52 +1703,27 @@ ASMJIT_ENUM(kX86InstOp) {
kX86InstOpZmm = 0x0400,
//! Instruction operand can be memory.
kX86InstOpMem = 0x2000,
kX86InstOpMem = 0x1000,
//! Instruction operand can be immediate.
kX86InstOpImm = 0x4000,
kX86InstOpImm = 0x2000,
//! Instruction operand can be label.
kX86InstOpLabel = 0x8000,
//! \internal
//!
//! Combined flags.
kX86InstOpLabel = 0x4000,
//! Instruction operand doesn't have to be used.
//!
//! \{
kX86InstOpGwb = kX86InstOpGw | kX86InstOpGb,
kX86InstOpGqd = kX86InstOpGq | kX86InstOpGd,
kX86InstOpGqdw = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw,
kX86InstOpGqdwb = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw | kX86InstOpGb,
kX86InstOpGbMem = kX86InstOpGb | kX86InstOpMem,
kX86InstOpGwMem = kX86InstOpGw | kX86InstOpMem,
kX86InstOpGdMem = kX86InstOpGd | kX86InstOpMem,
kX86InstOpGqMem = kX86InstOpGq | kX86InstOpMem,
kX86InstOpGwbMem = kX86InstOpGwb | kX86InstOpMem,
kX86InstOpGqdMem = kX86InstOpGqd | kX86InstOpMem,
kX86InstOpGqdwMem = kX86InstOpGqdw | kX86InstOpMem,
kX86InstOpGqdwbMem = kX86InstOpGqdwb | kX86InstOpMem,
kX86InstOpFpMem = kX86InstOpFp | kX86InstOpMem,
kX86InstOpMmMem = kX86InstOpMm | kX86InstOpMem,
kX86InstOpXmmMem = kX86InstOpXmm | kX86InstOpMem,
kX86InstOpYmmMem = kX86InstOpYmm | kX86InstOpMem,
kX86InstOpMmXmm = kX86InstOpMm | kX86InstOpXmm,
kX86InstOpMmXmmMem = kX86InstOpMmXmm | kX86InstOpMem,
kX86InstOpXmmYmm = kX86InstOpXmm | kX86InstOpYmm,
kX86InstOpXmmYmmMem = kX86InstOpXmmYmm | kX86InstOpMem
//! \}
//! \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::kX86Cond]
// [asmjit::X86Cond]
// ============================================================================
//! X86/X64 Condition codes.
ASMJIT_ENUM(kX86Cond) {
ASMJIT_ENUM(X86Cond) {
kX86CondA = 0x07, // CF==0 & ZF==0 (unsigned)
kX86CondAE = 0x03, // CF==0 (unsigned)
kX86CondB = 0x02, // CF==1 (unsigned)
......@@ -1647,28 +1756,31 @@ ASMJIT_ENUM(kX86Cond) {
kX86CondZ = 0x04, // ZF==1
// Simplified condition codes.
kX86CondOverflow = 0x00,
kX86CondNotOverflow = 0x01,
kX86CondBelow = 0x02, //!< Unsigned comparison.
kX86CondAboveEqual = 0x03, //!< Unsigned comparison.
kX86CondEqual = 0x04,
kX86CondNotEqual = 0x05,
kX86CondBelowEqual = 0x06, //!< Unsigned comparison.
kX86CondAbove = 0x07, //!< Unsigned comparison.
kX86CondSign = 0x08,
kX86CondNotSign = 0x09,
kX86CondParityEven = 0x0A,
kX86CondParityOdd = 0x0B,
kX86CondLess = 0x0C, //!< Signed comparison.
kX86CondGreaterEqual = 0x0D, //!< Signed comparison.
kX86CondLessEqual = 0x0E, //!< Signed comparison.
kX86CondGreater = 0x0F, //!< Signed comparison.
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 = 0x04,
kX86CondNotZero = 0x05,
kX86CondNegative = 0x08,
kX86CondPositive = 0x09,
kX86CondZero = kX86CondZ,
kX86CondNotZero = kX86CondNZ,
kX86CondNegative = kX86CondS,
kX86CondPositive = kX86CondNS,
// Fpu-only.
kX86CondFpuUnordered = 0x10,
......@@ -1679,24 +1791,24 @@ ASMJIT_ENUM(kX86Cond) {
};
// ============================================================================
// [asmjit::kX86EFlags]
// [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 the API and
//! definitions are public.
//! instruction reordering, but can be used by third parties as it's part of
//! AsmJit API.
//!
//! \note Flags defined here doesn't correspond to real flags used by X86/X64
//! architecture defined in Intel's Manual Section `3.4.3 - EFLAGS Register`.
//! \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 8-bit integer.
ASMJIT_ENUM(kX86EFlags) {
//! \note Flags are designed to fit in an 8-bit integer.
ASMJIT_ENUM(X86EFlags) {
// --------------------------------------------------------------------------
// src-gendefs.js relies on the values of these masks, to modify them the
// tool has to be changed as well.
// 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).
......@@ -1743,16 +1855,16 @@ ASMJIT_ENUM(kX86EFlags) {
//! `lods` and `stos`.
kX86EFlagD = 0x40,
//! Any other flag that AsmJit doesn't use to keep track of it.
//! Any other flag that AsmJit doesn't use to keep track of.
kX86EFlagX = 0x80
};
// ============================================================================
// [asmjit::kX86FpSw]
// [asmjit::X86FpSw]
// ============================================================================
//! X86/X64 FPU status Word.
ASMJIT_ENUM(kX86FpSw) {
//! X86/X64 FPU status word.
ASMJIT_ENUM(X86FpSw) {
kX86FpSw_Invalid = 0x0001,
kX86FpSw_Denormalized = 0x0002,
kX86FpSw_DivByZero = 0x0004,
......@@ -1770,11 +1882,11 @@ ASMJIT_ENUM(kX86FpSw) {
};
// ============================================================================
// [asmjit::kX86FpCw]
// [asmjit::X86FpCw]
// ============================================================================
//! X86/X64 FPU control Word.
ASMJIT_ENUM(kX86FpCw) {
//! X86/X64 FPU control word.
ASMJIT_ENUM(X86FpCw) {
kX86FpCw_EM_Mask = 0x003F, // Bits 0-5.
kX86FpCw_EM_Invalid = 0x0001,
kX86FpCw_EM_Denormal = 0x0002,
......@@ -1801,13 +1913,72 @@ ASMJIT_ENUM(kX86FpCw) {
};
// ============================================================================
// [asmjit::kX86Prefetch]
// [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(kX86Prefetch) {
ASMJIT_ENUM(X86Prefetch) {
//! Prefetch using NT hint.
kX86PrefetchNta = 0,
kX86PrefetchNTA = 0,
//! Prefetch to L0 cache.
kX86PrefetchT0 = 1,
//! Prefetch to L1 cache.
......@@ -1828,32 +1999,32 @@ ASMJIT_ENUM(kX86Prefetch) {
//! used by few instructions.
struct X86InstExtendedInfo {
// --------------------------------------------------------------------------
// [Accessors - InstGroup]
// [Accessors - Instruction Encoding]
// --------------------------------------------------------------------------
//! Get instruction group, see \ref kX86InstGroup.
ASMJIT_INLINE uint32_t getInstGroup() const {
return _instGroup;
//! Get instruction encoding, see \ref kX86InstEncoding.
ASMJIT_INLINE uint32_t getEncodingId() const {
return _encodingId;
}
// --------------------------------------------------------------------------
// [Accessors - InstFlags]
// [Accessors - Instruction Flags]
// --------------------------------------------------------------------------
//! Get whether the instruction has flag `flag`, see `kX86InstFlags`.
//! Get whether the instruction has a `flag`, see `X86InstFlags`.
ASMJIT_INLINE bool hasInstFlag(uint32_t flag) const {
return (_instFlags & flag) != 0;
}
//! Get instruction flags, see `kX86InstFlags`.
//! 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 modifies instruction pointer,
//! typically jmp, jcc, call, or ret.
//! 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;
}
......@@ -1893,14 +2064,13 @@ struct X86InstExtendedInfo {
return (getInstFlags() & kX86InstFlagLock) != 0;
}
//! Get whether the instruction is special type (this is used by
//! `Compiler` to manage additional variables or functionality).
//! 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.
//! Get whether the instruction is special type and it performs memory access.
ASMJIT_INLINE bool isSpecialMem() const {
return (getInstFlags() & kX86InstFlagSpecialMem) != 0;
}
......@@ -1917,25 +2087,28 @@ struct X86InstExtendedInfo {
// [Accessors - EFlags]
// --------------------------------------------------------------------------
//! Get EFLAGS that the instruction reads.
//! Get EFLAGS that the instruction reads, see \ref X86EFlags.
ASMJIT_INLINE uint32_t getEFlagsIn() const {
return _eflagsIn;
}
//! Get EFLAGS that the instruction writes.
//! Get EFLAGS that the instruction writes, see \ref X86EFlags.
ASMJIT_INLINE uint32_t getEFlagsOut() const {
return _eflagsOut;
}
// --------------------------------------------------------------------------
// [Accessors - Move-Size]
// [Accessors - Write Index/Size]
// --------------------------------------------------------------------------
//! Get size of move instruction in bytes.
//!
//! See \ref X86InstInfo::getMoveSize() for more details.
ASMJIT_INLINE uint32_t getMoveSize() const {
return _moveSize;
//! 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;
}
// --------------------------------------------------------------------------
......@@ -1954,7 +2127,7 @@ struct X86InstExtendedInfo {
// [Accessors - OpCode]
// --------------------------------------------------------------------------
//! Get the secondary instruction opcode, see \ref kX86InstOpCode.
//! Get the secondary instruction opcode, see \ref X86InstOpCodeFlags.
//!
//! See \ref X86InstInfo::getSecondaryOpCode() for more details.
ASMJIT_INLINE uint32_t getSecondaryOpCode() const {
......@@ -1965,26 +2138,39 @@ struct X86InstExtendedInfo {
// [Members]
// --------------------------------------------------------------------------
//! Instruction group.
uint8_t _instGroup;
//! Instruction encoding ID.
uint8_t _encodingId;
//! Destination index of WRITE operation, default 0.
uint8_t _writeIndex;
//! Count of bytes overwritten by a move instruction.
//! 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.
//!
//! Only used with `kX86InstFlagMove` flag. If this value is zero move depends
//! on size of the destination register.
uint8_t _moveSize;
//! 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 modified by the instruction.
//! EFlags written by the instruction.
uint8_t _eflagsOut;
//! Instruction flags.
uint16_t _instFlags;
//! \internal
uint8_t _reserved;
//! Operands' flags.
//! Operands' flags, up to 5 operands.
uint16_t _opFlags[5];
//! Instruction flags.
uint32_t _instFlags;
//! Secondary opcode.
uint32_t _secondaryOpCode;
};
......@@ -2026,41 +2212,54 @@ struct X86InstInfo {
}
// --------------------------------------------------------------------------
// [Accessors - Group]
// [Accessors - Instruction Encoding]
// --------------------------------------------------------------------------
//! Get instruction group, see \ref kX86InstGroup.
ASMJIT_INLINE uint32_t getInstGroup() const {
return getExtendedInfo().getInstGroup();
//! Get instruction group, see \ref X86InstEncodingId.
ASMJIT_INLINE uint32_t getEncodingId() const {
return getExtendedInfo().getEncodingId();
}
// --------------------------------------------------------------------------
// [Accessors - Flags]
// [Accessors - Instruction Flags]
// --------------------------------------------------------------------------
//! Get instruction flags, see `kX86InstFlags`.
//! Get instruction flags, see `X86InstFlags`.
ASMJIT_INLINE uint32_t getInstFlags() const {
return getExtendedInfo().getInstFlags();
}
//! Get whether the instruction has flag `flag`, see `kX86InstFlags`.
//! Get whether the instruction has flag `flag`, see `X86InstFlags`.
ASMJIT_INLINE bool hasInstFlag(uint32_t flag) const {
return (getInstFlags() & flag) != 0;
}
// --------------------------------------------------------------------------
// [Accessors - Move-Size]
// [Accessors - EFlags]
// --------------------------------------------------------------------------
//! Get size of move instruction in bytes.
//!
//! If zero, the size of MOV instruction is determined by the size of the
//! destination register (applies mostly for x86 arithmetic). This value is
//! useful for register allocator when determining if a variable is going to
//! be overwritten or not. Basically if the move size is equal or greater
//! than a variable itself it is considered overwritten.
ASMJIT_INLINE uint32_t getMoveSize() const {
return getExtendedInfo().getMoveSize();
//! 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();
}
// --------------------------------------------------------------------------
......@@ -2076,12 +2275,12 @@ struct X86InstInfo {
// [Accessors - OpCode]
// --------------------------------------------------------------------------
//! Get the primary instruction opcode, see \ref kX86InstOpCode.
//! Get the primary instruction opcode, see \ref X86InstOpCodeFlags.
ASMJIT_INLINE uint32_t getPrimaryOpCode() const {
return _primaryOpCode;
}
//! Get the secondary instruction opcode, see \ref kX86InstOpCode.
//! Get the secondary instruction opcode, see \ref X86InstOpCodeFlags.
ASMJIT_INLINE uint32_t getSecondaryOpCode() const {
return getExtendedInfo().getSecondaryOpCode();
}
......@@ -2141,25 +2340,25 @@ struct X86Util {
//! Get the equivalent of negated condition code.
static ASMJIT_INLINE uint32_t negateCond(uint32_t cond) {
ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_x86ReverseCond));
return static_cast<kX86Cond>(cond ^ static_cast<uint32_t>(cond < kX86CondNone));
return cond ^ static_cast<uint32_t>(cond < kX86CondNone);
}
//! Translate condition code `cc` to `cmovcc` instruction code.
//! \sa \ref kX86InstId, \ref _kX86InstIdCmovcc.
//! \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 kX86InstId, \ref _kX86InstIdJcc.
//! \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 kX86InstId, \ref _kX86InstIdSetcc.
//! \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];
......
......@@ -23,7 +23,7 @@
//!
//! 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 _OP_ID(_Op_) reinterpret_cast<const Operand&>(_Op_).getId()
#define ASMJIT_OP_ID(_Op_) reinterpret_cast<const Operand&>(_Op_).getId()
namespace asmjit {
......@@ -32,49 +32,70 @@ namespace asmjit {
// ============================================================================
struct X86Reg;
struct X86RipReg;
struct X86SegReg;
struct X86GpReg;
struct X86FpReg;
struct X86MmReg;
struct X86KReg;
struct X86XmmReg;
struct X86YmmReg;
struct X86SegReg;
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::kX86RegClass]
// [asmjit::X86RegClass]
// ============================================================================
//! X86/X64 variable class.
ASMJIT_ENUM(kX86RegClass) {
ASMJIT_ENUM(X86RegClass) {
// --------------------------------------------------------------------------
// [Regs & Vars]
// --------------------------------------------------------------------------
//! X86/X64 Gp register class (compatible with universal \ref kRegClassGp).
kX86RegClassGp = kRegClassGp,
//! X86/X64 Fp register class.
kX86RegClassFp = 1,
//! X86/X64 Mm register class.
kX86RegClassMm = 2,
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 = 4
kX86RegClassCount = 5
};
// ============================================================================
// [asmjit::kX86RegType]
// [asmjit::X86RegType]
// ============================================================================
//! X86/X64 register type.
ASMJIT_ENUM(kX86RegType) {
ASMJIT_ENUM(X86RegType) {
//! Gpb-lo register (AL, BL, CL, DL, ...).
kX86RegTypeGpbLo = 0x01,
//! Gpb-hi register (AH, BH, CH, DH only).
......@@ -89,27 +110,32 @@ ASMJIT_ENUM(kX86RegType) {
kX86RegTypeGpw = 0x10,
//! Gpd register.
kX86RegTypeGpd = 0x20,
//! Gpq register.
//! Gpq register (X64).
kX86RegTypeGpq = 0x30,
//! Fp register.
kX86RegTypeFp = 0x50,
//! Mm register.
kX86RegTypeMm = 0x60,
kX86RegTypeFp = 0x40,
//! Mm register (MMX+).
kX86RegTypeMm = 0x50,
//! Xmm register.
//! K register (AVX512+).
kX86RegTypeK = 0x60,
//! Xmm register (SSE+).
kX86RegTypeXmm = 0x70,
//! Ymm register.
//! Ymm register (AVX+).
kX86RegTypeYmm = 0x80,
//! Zmm register.
//! Zmm register (AVX512+).
kX86RegTypeZmm = 0x90,
//! Instruction pointer (RIP).
kX86RegTypeRip = 0xE0,
//! Segment register.
kX86RegTypeSeg = 0xF0
};
// ============================================================================
// [asmjit::kX86RegIndex]
// [asmjit::X86RegIndex]
// ============================================================================
//! X86/X64 register indexes.
......@@ -117,7 +143,7 @@ ASMJIT_ENUM(kX86RegType) {
//! \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(kX86RegIndex) {
ASMJIT_ENUM(X86RegIndex) {
//! Index of Al/Ah/Ax/Eax/Rax registers.
kX86RegIndexAx = 0,
//! Index of Cl/Ch/Cx/Ecx/Rcx registers.
......@@ -153,11 +179,11 @@ ASMJIT_ENUM(kX86RegIndex) {
};
// ============================================================================
// [asmjit::kX86Seg]
// [asmjit::X86Seg]
// ============================================================================
//! X86/X64 segment codes.
ASMJIT_ENUM(kX86Seg) {
ASMJIT_ENUM(X86Seg) {
//! No/Default segment.
kX86SegDefault = 0,
//! Es segment.
......@@ -184,27 +210,29 @@ ASMJIT_ENUM(kX86Seg) {
};
// ============================================================================
// [asmjit::kX86MemVSib]
// [asmjit::X86MemVSib]
// ============================================================================
//! X86/X64 index register legacy and AVX2 (VSIB) support.
ASMJIT_ENUM(kX86MemVSib) {
//! Memory operand uses Gp or no index register.
ASMJIT_ENUM(X86MemVSib) {
//! Memory operand uses Gpd/Gpq index (or no index register).
kX86MemVSibGpz = 0,
//! Memory operand uses Xmm or no index register.
//! Memory operand uses Xmm index (or no index register).
kX86MemVSibXmm = 1,
//! Memory operand uses Ymm or no index register.
kX86MemVSibYmm = 2
//! Memory operand uses Ymm index (or no index register).
kX86MemVSibYmm = 2,
//! Memory operand uses Zmm index (or no index register).
kX86MemVSibZmm = 3
};
// ============================================================================
// [asmjit::kX86MemFlags]
// [asmjit::X86MemFlags]
// ============================================================================
//! \internal
//!
//! X86/X64 specific memory flags.
ASMJIT_ENUM(kX86MemFlags) {
ASMJIT_ENUM(X86MemFlags) {
kX86MemSegBits = 0x7,
kX86MemSegIndex = 0,
kX86MemSegMask = kX86MemSegBits << kX86MemSegIndex,
......@@ -223,7 +251,21 @@ ASMJIT_ENUM(kX86MemFlags) {
};
// This is only defined by `x86operand_regs.cpp` when exporting registers.
#if !defined(ASMJIT_EXPORTS_X86OPERAND_REGS)
#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]
......@@ -231,12 +273,29 @@ ASMJIT_ENUM(kX86MemFlags) {
//! \internal
//!
//! X86/X64 registers count (Gp, Fp, Mm, Xmm).
//! 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;
}
......@@ -245,61 +304,87 @@ struct X86RegCount {
// [Get]
// --------------------------------------------------------------------------
ASMJIT_INLINE uint32_t get(uint32_t c) const {
ASMJIT_ASSERT(c < kX86RegClassCount);
return _regs[c];
//! 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]; }
ASMJIT_INLINE uint32_t getFp() const { return _regs[kX86RegClassFp]; }
//! 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]
// --------------------------------------------------------------------------
ASMJIT_INLINE void set(uint32_t c, uint32_t n) {
ASMJIT_ASSERT(c < kX86RegClassCount);
ASMJIT_ASSERT(n < 0x100);
//! Set register count by `classId`.
ASMJIT_INLINE void set(uint32_t classId, uint32_t n) {
ASMJIT_ASSERT(classId < _kX86RegClassManagedCount);
ASMJIT_ASSERT(n <= 0xFF);
_regs[c] = static_cast<uint8_t>(n);
_regs[classId] = static_cast<uint8_t>(n);
}
//! Set Gp register count.
ASMJIT_INLINE void setGp(uint32_t n) { set(kX86RegClassGp, n); }
ASMJIT_INLINE void setFp(uint32_t n) { set(kX86RegClassFp, 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]
// --------------------------------------------------------------------------
ASMJIT_INLINE void add(uint32_t c, uint32_t n = 1) {
ASMJIT_ASSERT(c < kX86RegClassCount);
ASMJIT_ASSERT(n < 0x100);
//! 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[c] += static_cast<uint8_t>(n);
_regs[classId] += static_cast<uint8_t>(n);
}
//! Add Gp register count.
ASMJIT_INLINE void addGp(uint32_t n) { add(kX86RegClassGp, n); }
ASMJIT_INLINE void addFp(uint32_t n) { add(kX86RegClassFp, 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]
// --------------------------------------------------------------------------
ASMJIT_INLINE void makeIndex(const X86RegCount& count) {
uint8_t a = count._regs[0];
uint8_t b = count._regs[1];
uint8_t c = count._regs[2];
//! 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);
_regs[0] = 0;
_regs[1] = a;
_regs[2] = a + b;
_regs[3] = a + b + c;
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);
}
// --------------------------------------------------------------------------
......@@ -308,10 +393,16 @@ struct X86RegCount {
union {
struct {
//! Count of Gp registers.
uint8_t _gp;
uint8_t _fp;
//! Count of Mm registers.
uint8_t _mm;
uint8_t _xy;
//! 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];
......@@ -325,12 +416,13 @@ struct X86RegCount {
//! \internal
//!
//! X86/X64 registers mask (Gp, Fp, Mm, Xmm/Ymm/Zmm).
//! 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();
}
......@@ -339,135 +431,189 @@ struct X86RegMask {
// [IsEmpty / Has]
// --------------------------------------------------------------------------
//! Get whether all register masks are zero (empty).
ASMJIT_INLINE bool isEmpty() const {
return _packed.isZero();
}
ASMJIT_INLINE bool has(uint32_t c, uint32_t mask = 0xFFFFFFFF) const {
switch (c) {
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 kX86RegClassFp : return (static_cast<uint32_t>(_fp ) & 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;
}
ASMJIT_ASSERT(!"Reached");
return false;
}
// --------------------------------------------------------------------------
// [Zero]
// --------------------------------------------------------------------------
ASMJIT_INLINE void zero(uint32_t c) {
switch (c) {
case kX86RegClassGp : _gp = 0; break;
case kX86RegClassFp : _fp = 0; break;
case kX86RegClassMm : _mm = 0; break;
case kX86RegClassXyz: _xyz = 0; break;
}
}
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 c) const {
switch (c) {
ASMJIT_INLINE uint32_t get(uint32_t classId) const {
ASMJIT_ASSERT(classId < _kX86RegClassManagedCount);
switch (classId) {
case kX86RegClassGp : return _gp;
case kX86RegClassFp : return _fp;
case kX86RegClassMm : return _mm;
case kX86RegClassK : return _k;
case kX86RegClassXyz: return _xyz;
}
ASMJIT_ASSERT(!"Reached");
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(uint32_t c, uint32_t mask) {
switch (c) {
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 kX86RegClassFp : _fp = static_cast<uint8_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 set(const X86RegMask& other) {
_packed.setUInt64(other._packed);
}
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); }
// --------------------------------------------------------------------------
// [Add]
// [And]
// --------------------------------------------------------------------------
ASMJIT_INLINE void add(uint32_t c, uint32_t mask) {
switch (c) {
case kX86RegClassGp : _gp |= static_cast<uint16_t>(mask); break;
case kX86RegClassFp : _fp |= static_cast<uint8_t >(mask); break;
case kX86RegClassMm : _mm |= static_cast<uint8_t >(mask); break;
case kX86RegClassXyz: _xyz |= static_cast<uint32_t>(mask); break;
}
ASMJIT_INLINE void and_(const X86RegMask& other) {
_packed.and_(other._packed);
}
ASMJIT_INLINE void add(const X86RegMask& other) {
_packed.or_(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); }
// --------------------------------------------------------------------------
// [Del]
// [AndNot]
// --------------------------------------------------------------------------
ASMJIT_INLINE void del(uint32_t c, uint32_t mask) {
switch (c) {
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 kX86RegClassFp : _fp &= ~static_cast<uint8_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 del(const X86RegMask& other) {
_packed.del(other._packed);
}
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); }
// --------------------------------------------------------------------------
// [And]
// [Or]
// --------------------------------------------------------------------------
ASMJIT_INLINE void and_(uint32_t c, uint32_t mask) {
switch (c) {
case kX86RegClassGp : _gp &= static_cast<uint16_t>(mask); break;
case kX86RegClassFp : _fp &= static_cast<uint8_t >(mask); break;
case kX86RegClassMm : _mm &= static_cast<uint8_t >(mask); break;
case kX86RegClassXyz: _xyz &= static_cast<uint32_t>(mask); break;
}
ASMJIT_INLINE void or_(const X86RegMask& other) {
_packed.or_(other._packed);
}
ASMJIT_INLINE void and_(const X86RegMask& other) {
_packed.and_(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_(uint32_t c, uint32_t mask) {
switch (c) {
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 kX86RegClassFp : _fp ^= static_cast<uint8_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 xor_(const X86RegMask& other) {
_packed.xor_(other._packed);
}
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]
......@@ -475,17 +621,17 @@ struct X86RegMask {
union {
struct {
//! Gp mask (16-bit).
//! Gp registers mask (16 bits).
uint16_t _gp;
//! Fp mask (8-bit).
uint8_t _fp;
//! Mm mask (8-bit).
//! Mm registers mask (8 bits).
uint8_t _mm;
//! Xmm/Ymm/Zmm mask (32-bit).
//! K registers mask (8 bits).
uint8_t _k;
//! Xmm/Ymm/Zmm registers mask (32 bits).
uint32_t _xyz;
};
//! All masks as 64-bit integer.
//! Packed masks.
UInt64 _packed;
};
};
......@@ -494,7 +640,7 @@ struct X86RegMask {
// [asmjit::X86Reg]
// ============================================================================
//! Base class for all X86 registers.
//! X86/X86 register base class.
struct X86Reg : public Reg {
// --------------------------------------------------------------------------
// [Construction / Destruction]
......@@ -520,7 +666,7 @@ struct X86Reg : public Reg {
//! 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 <= kX86RegTypeGpbHi; }
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.
......@@ -536,6 +682,10 @@ struct X86Reg : public Reg {
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.
......@@ -543,7 +693,9 @@ struct X86Reg : public Reg {
//! Get whether the register is Zmm (512-bit) register.
ASMJIT_INLINE bool isZmm() const { return _vreg.type == kX86RegTypeZmm; }
//! Get whether the register is a segment.
//! 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; }
// --------------------------------------------------------------------------
......@@ -559,6 +711,58 @@ struct X86Reg : public Reg {
}
};
// ============================================================================
// [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]
// ============================================================================
......@@ -585,6 +789,24 @@ struct X86GpReg : public X86Reg {
// --------------------------------------------------------------------------
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); }
};
// ============================================================================
......@@ -619,7 +841,32 @@ struct X86FpReg : public X86Reg {
// [asmjit::X86MmReg]
// ============================================================================
//! X86/X64 64-bit Mm register.
//! 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]
......@@ -643,11 +890,92 @@ struct X86MmReg : public X86Reg {
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.
//! 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]
......@@ -669,13 +997,46 @@ struct X86XmmReg : public X86Reg {
// --------------------------------------------------------------------------
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.
//! 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]
......@@ -683,7 +1044,7 @@ struct X86YmmReg : public X86Reg {
//! Create a dummy Ymm register.
ASMJIT_INLINE X86YmmReg() : X86Reg() {}
//! Create a reference to `other` Xmm register.
//! 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) {}
......@@ -697,36 +1058,63 @@ struct X86YmmReg : public X86Reg {
// --------------------------------------------------------------------------
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::X86SegReg]
// [asmjit::X86ZmmReg]
// ============================================================================
//! X86/X64 segment register.
struct X86SegReg : public X86Reg {
//! X86/X64 512-bit Zmm register (AVX512+).
struct X86ZmmReg : 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) {}
//! 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) {}
// --------------------------------------------------------------------------
// [X86SegReg Specific]
// [X86ZmmReg Specific]
// --------------------------------------------------------------------------
ASMJIT_REG_OP(X86SegReg)
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]
// ============================================================================
......@@ -807,7 +1195,7 @@ struct X86Mem : public BaseMem {
(kX86MemVSibGpz << kX86MemVSibIndex)
+ (shift << kX86MemShiftIndex),
label.getId());
_vmem.index = _OP_ID(index);
_vmem.index = ASMJIT_OP_ID(index);
_vmem.displacement = disp;
}
......@@ -815,7 +1203,7 @@ struct X86Mem : public BaseMem {
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
_getGpdFlags(reinterpret_cast<const Var&>(base))
+ (kX86MemVSibGpz << kX86MemVSibIndex),
_OP_ID(base));
ASMJIT_OP_ID(base));
_init_packed_d2_d3(kInvalidValue, disp);
}
......@@ -825,8 +1213,8 @@ struct X86Mem : public BaseMem {
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
_getGpdFlags(reinterpret_cast<const Var&>(base))
+ (shift << kX86MemShiftIndex),
_OP_ID(base));
_vmem.index = _OP_ID(index);
ASMJIT_OP_ID(base));
_vmem.index = ASMJIT_OP_ID(index);
_vmem.displacement = disp;
}
......@@ -837,8 +1225,8 @@ struct X86Mem : public BaseMem {
_getGpdFlags(reinterpret_cast<const Var&>(base))
+ (kX86MemVSibXmm << kX86MemVSibIndex)
+ (shift << kX86MemShiftIndex),
_OP_ID(base));
_vmem.index = _OP_ID(index);
ASMJIT_OP_ID(base));
_vmem.index = ASMJIT_OP_ID(index);
_vmem.displacement = disp;
}
......@@ -849,13 +1237,13 @@ struct X86Mem : public BaseMem {
_getGpdFlags(reinterpret_cast<const Var&>(base))
+ (kX86MemVSibYmm << kX86MemVSibIndex)
+ (shift << kX86MemShiftIndex),
_OP_ID(base));
_vmem.index = _OP_ID(index);
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, _OP_ID(base));
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, 0, ASMJIT_OP_ID(base));
_vmem.index = kInvalidValue;
_vmem.displacement = disp;
}
......@@ -863,8 +1251,8 @@ struct X86Mem : public BaseMem {
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, _OP_ID(base));
_vmem.index = _OP_ID(index);
_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
......@@ -903,19 +1291,19 @@ struct X86Mem : public BaseMem {
return (_vmem.flags & kX86MemSegMask) != (kX86SegDefault << kX86MemSegIndex);
}
//! Get memory operand segment, see `kX86Seg`.
//! 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 `kX86Seg`.
//! 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 `kX86Seg`.
//! Set memory operand segment, see `X86Seg`.
ASMJIT_INLINE X86Mem& setSegment(const X86SegReg& seg) {
return setSegment(seg.getRegIndex());
}
......@@ -946,12 +1334,12 @@ struct X86Mem : public BaseMem {
// [VSib]
// --------------------------------------------------------------------------
//! Get SIB type.
//! Get V-SIB type.
ASMJIT_INLINE uint32_t getVSib() const {
return (static_cast<uint32_t>(_vmem.flags) >> kX86MemVSibIndex) & kX86MemVSibBits;
}
//! Set SIB type.
//! 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);
......@@ -1047,38 +1435,38 @@ struct X86Mem : public BaseMem {
#if !defined(ASMJIT_DISABLE_COMPILER)
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86GpVar& index) {
_vmem.index = _OP_ID(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 = _OP_ID(index);
_vmem.index = ASMJIT_OP_ID(index);
return _setVSib(kX86MemVSibGpz).setShift(shift);
}
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86XmmVar& index) {
_vmem.index = _OP_ID(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 = _OP_ID(index);
_vmem.index = ASMJIT_OP_ID(index);
return _setVSib(kX86MemVSibXmm).setShift(shift);
}
//! Set memory index.
ASMJIT_INLINE X86Mem& setIndex(const X86YmmVar& index) {
_vmem.index = _OP_ID(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 = _OP_ID(index);
_vmem.index = ASMJIT_OP_ID(index);
return _setVSib(kX86MemVSibYmm).setShift(shift);
}
#endif // !ASMJIT_DISABLE_COMPILER
......@@ -1183,7 +1571,35 @@ struct X86Mem : public BaseMem {
return (base._vreg.size & 0x4) << (kX86MemGpdIndex - 2);
}
};
#endif // !ASMJIT_EXPORTS_X86OPERAND_REGS
#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]
......@@ -1195,140 +1611,218 @@ namespace x86 {
// [asmjit::x86 - Reg]
// ============================================================================
//! No Gp register, can be used only within `X86Mem` operand.
ASMJIT_VAR const X86GpReg noGpReg;
ASMJIT_VAR const X86GpReg al; //!< 8-bit Gpb-lo register.
ASMJIT_VAR const X86GpReg cl; //!< 8-bit Gpb-lo register.
ASMJIT_VAR const X86GpReg dl; //!< 8-bit Gpb-lo register.
ASMJIT_VAR const X86GpReg bl; //!< 8-bit Gpb-lo register.
ASMJIT_VAR const X86GpReg spl; //!< 8-bit Gpb-lo register (X64).
ASMJIT_VAR const X86GpReg bpl; //!< 8-bit Gpb-lo register (X64).
ASMJIT_VAR const X86GpReg sil; //!< 8-bit Gpb-lo register (X64).
ASMJIT_VAR const X86GpReg dil; //!< 8-bit Gpb-lo register (X64).
ASMJIT_VAR const X86GpReg r8b; //!< 8-bit Gpb-lo register (X64).
ASMJIT_VAR const X86GpReg r9b; //!< 8-bit Gpb-lo register (X64).
ASMJIT_VAR const X86GpReg r10b; //!< 8-bit Gpb-lo register (X64).
ASMJIT_VAR const X86GpReg r11b; //!< 8-bit Gpb-lo register (X64).
ASMJIT_VAR const X86GpReg r12b; //!< 8-bit Gpb-lo register (X64).
ASMJIT_VAR const X86GpReg r13b; //!< 8-bit Gpb-lo register (X64).
ASMJIT_VAR const X86GpReg r14b; //!< 8-bit Gpb-lo register (X64).
ASMJIT_VAR const X86GpReg r15b; //!< 8-bit Gpb-lo register (X64).
ASMJIT_VAR const X86GpReg ah; //!< 8-bit Gpb-hi register.
ASMJIT_VAR const X86GpReg ch; //!< 8-bit Gpb-hi register.
ASMJIT_VAR const X86GpReg dh; //!< 8-bit Gpb-hi register.
ASMJIT_VAR const X86GpReg bh; //!< 8-bit Gpb-hi register.
ASMJIT_VAR const X86GpReg ax; //!< 16-bit Gpw register.
ASMJIT_VAR const X86GpReg cx; //!< 16-bit Gpw register.
ASMJIT_VAR const X86GpReg dx; //!< 16-bit Gpw register.
ASMJIT_VAR const X86GpReg bx; //!< 16-bit Gpw register.
ASMJIT_VAR const X86GpReg sp; //!< 16-bit Gpw register.
ASMJIT_VAR const X86GpReg bp; //!< 16-bit Gpw register.
ASMJIT_VAR const X86GpReg si; //!< 16-bit Gpw register.
ASMJIT_VAR const X86GpReg di; //!< 16-bit Gpw register.
ASMJIT_VAR const X86GpReg r8w; //!< 16-bit Gpw register (X64).
ASMJIT_VAR const X86GpReg r9w; //!< 16-bit Gpw register (X64).
ASMJIT_VAR const X86GpReg r10w; //!< 16-bit Gpw register (X64).
ASMJIT_VAR const X86GpReg r11w; //!< 16-bit Gpw register (X64).
ASMJIT_VAR const X86GpReg r12w; //!< 16-bit Gpw register (X64).
ASMJIT_VAR const X86GpReg r13w; //!< 16-bit Gpw register (X64).
ASMJIT_VAR const X86GpReg r14w; //!< 16-bit Gpw register (X64).
ASMJIT_VAR const X86GpReg r15w; //!< 16-bit Gpw register (X64).
ASMJIT_VAR const X86GpReg eax; //!< 32-bit Gpd register.
ASMJIT_VAR const X86GpReg ecx; //!< 32-bit Gpd register.
ASMJIT_VAR const X86GpReg edx; //!< 32-bit Gpd register.
ASMJIT_VAR const X86GpReg ebx; //!< 32-bit Gpd register.
ASMJIT_VAR const X86GpReg esp; //!< 32-bit Gpd register.
ASMJIT_VAR const X86GpReg ebp; //!< 32-bit Gpd register.
ASMJIT_VAR const X86GpReg esi; //!< 32-bit Gpd register.
ASMJIT_VAR const X86GpReg edi; //!< 32-bit Gpd register.
ASMJIT_VAR const X86GpReg r8d; //!< 32-bit Gpd register (X64).
ASMJIT_VAR const X86GpReg r9d; //!< 32-bit Gpd register (X64).
ASMJIT_VAR const X86GpReg r10d; //!< 32-bit Gpd register (X64).
ASMJIT_VAR const X86GpReg r11d; //!< 32-bit Gpd register (X64).
ASMJIT_VAR const X86GpReg r12d; //!< 32-bit Gpd register (X64).
ASMJIT_VAR const X86GpReg r13d; //!< 32-bit Gpd register (X64).
ASMJIT_VAR const X86GpReg r14d; //!< 32-bit Gpd register (X64).
ASMJIT_VAR const X86GpReg r15d; //!< 32-bit Gpd register (X64).
ASMJIT_VAR const X86GpReg rax; //!< 64-bit Gpq register (X64).
ASMJIT_VAR const X86GpReg rcx; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg rdx; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg rbx; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg rsp; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg rbp; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg rsi; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg rdi; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg r8; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg r9; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg r10; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg r11; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg r12; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg r13; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg r14; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86GpReg r15; //!< 64-bit Gpq register (X64)
ASMJIT_VAR const X86FpReg fp0; //!< 80-bit Fp register.
ASMJIT_VAR const X86FpReg fp1; //!< 80-bit Fp register.
ASMJIT_VAR const X86FpReg fp2; //!< 80-bit Fp register.
ASMJIT_VAR const X86FpReg fp3; //!< 80-bit Fp register.
ASMJIT_VAR const X86FpReg fp4; //!< 80-bit Fp register.
ASMJIT_VAR const X86FpReg fp5; //!< 80-bit Fp register.
ASMJIT_VAR const X86FpReg fp6; //!< 80-bit Fp register.
ASMJIT_VAR const X86FpReg fp7; //!< 80-bit Fp register.
ASMJIT_VAR const X86MmReg mm0; //!< 64-bit Mm register.
ASMJIT_VAR const X86MmReg mm1; //!< 64-bit Mm register.
ASMJIT_VAR const X86MmReg mm2; //!< 64-bit Mm register.
ASMJIT_VAR const X86MmReg mm3; //!< 64-bit Mm register.
ASMJIT_VAR const X86MmReg mm4; //!< 64-bit Mm register.
ASMJIT_VAR const X86MmReg mm5; //!< 64-bit Mm register.
ASMJIT_VAR const X86MmReg mm6; //!< 64-bit Mm register.
ASMJIT_VAR const X86MmReg mm7; //!< 64-bit Mm register.
ASMJIT_VAR const X86XmmReg xmm0; //!< 128-bit Xmm register.
ASMJIT_VAR const X86XmmReg xmm1; //!< 128-bit Xmm register.
ASMJIT_VAR const X86XmmReg xmm2; //!< 128-bit Xmm register.
ASMJIT_VAR const X86XmmReg xmm3; //!< 128-bit Xmm register.
ASMJIT_VAR const X86XmmReg xmm4; //!< 128-bit Xmm register.
ASMJIT_VAR const X86XmmReg xmm5; //!< 128-bit Xmm register.
ASMJIT_VAR const X86XmmReg xmm6; //!< 128-bit Xmm register.
ASMJIT_VAR const X86XmmReg xmm7; //!< 128-bit Xmm register.
ASMJIT_VAR const X86XmmReg xmm8; //!< 128-bit Xmm register (X64).
ASMJIT_VAR const X86XmmReg xmm9; //!< 128-bit Xmm register (X64).
ASMJIT_VAR const X86XmmReg xmm10; //!< 128-bit Xmm register (X64).
ASMJIT_VAR const X86XmmReg xmm11; //!< 128-bit Xmm register (X64).
ASMJIT_VAR const X86XmmReg xmm12; //!< 128-bit Xmm register (X64).
ASMJIT_VAR const X86XmmReg xmm13; //!< 128-bit Xmm register (X64).
ASMJIT_VAR const X86XmmReg xmm14; //!< 128-bit Xmm register (X64).
ASMJIT_VAR const X86XmmReg xmm15; //!< 128-bit Xmm register (X64).
ASMJIT_VAR const X86YmmReg ymm0; //!< 256-bit Ymm register.
ASMJIT_VAR const X86YmmReg ymm1; //!< 256-bit Ymm register.
ASMJIT_VAR const X86YmmReg ymm2; //!< 256-bit Ymm register.
ASMJIT_VAR const X86YmmReg ymm3; //!< 256-bit Ymm register.
ASMJIT_VAR const X86YmmReg ymm4; //!< 256-bit Ymm register.
ASMJIT_VAR const X86YmmReg ymm5; //!< 256-bit Ymm register.
ASMJIT_VAR const X86YmmReg ymm6; //!< 256-bit Ymm register.
ASMJIT_VAR const X86YmmReg ymm7; //!< 256-bit Ymm register.
ASMJIT_VAR const X86YmmReg ymm8; //!< 256-bit Ymm register (X64).
ASMJIT_VAR const X86YmmReg ymm9; //!< 256-bit Ymm register (X64).
ASMJIT_VAR const X86YmmReg ymm10; //!< 256-bit Ymm register (X64).
ASMJIT_VAR const X86YmmReg ymm11; //!< 256-bit Ymm register (X64).
ASMJIT_VAR const X86YmmReg ymm12; //!< 256-bit Ymm register (X64).
ASMJIT_VAR const X86YmmReg ymm13; //!< 256-bit Ymm register (X64).
ASMJIT_VAR const X86YmmReg ymm14; //!< 256-bit Ymm register (X64).
ASMJIT_VAR const X86YmmReg ymm15; //!< 256-bit Ymm register (X64).
ASMJIT_VAR const X86SegReg cs; //!< Cs segment register.
ASMJIT_VAR const X86SegReg ss; //!< Ss segment register.
ASMJIT_VAR const X86SegReg ds; //!< Ds segment register.
ASMJIT_VAR const X86SegReg es; //!< Es segment register.
ASMJIT_VAR const X86SegReg fs; //!< Fs segment register.
ASMJIT_VAR const X86SegReg gs; //!< Gs segment register.
#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)
......@@ -1347,10 +1841,14 @@ static ASMJIT_INLINE X86GpReg gpq(uint32_t index) { return X86GpReg(kX86RegTypeG
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)]
......@@ -1522,7 +2020,8 @@ ASMJIT_EXPAND_PTR_VAR(zword, 64)
} // asmjit namespace
#undef _OP_ID
// [Cleanup]
#undef ASMJIT_OP_ID
// [Api-End]
#include "../apiend.h"
......
......@@ -20,165 +20,262 @@
namespace asmjit {
// Prevent static initialization.
//
// Remap all classes to POD structs so they can be statically initialized
// without calling a constructor. Compiler will store these in data section.
struct X86GpReg { Operand::VRegOp data; };
struct X86FpReg { Operand::VRegOp data; };
struct X86MmReg { Operand::VRegOp data; };
struct X86XmmReg { Operand::VRegOp data; };
struct X86YmmReg { Operand::VRegOp data; };
struct X86SegReg { Operand::VRegOp data; };
namespace x86 {
// ============================================================================
// [asmjit::x86::Registers]
// ============================================================================
#define REG(_Class_, _Name_, _Type_, _Index_, _Size_) \
const _Class_ _Name_ = {{ \
#define REG(_Type_, _Index_, _Size_) {{ \
kOperandTypeReg, _Size_, { ((_Type_) << 8) + _Index_ }, kInvalidValue, {{ kInvalidVar, 0 }} \
}}
REG(X86GpReg, noGpReg, kInvalidReg, kInvalidReg, 0);
REG(X86GpReg, al, kX86RegTypeGpbLo, kX86RegIndexAx, 1);
REG(X86GpReg, cl, kX86RegTypeGpbLo, kX86RegIndexCx, 1);
REG(X86GpReg, dl, kX86RegTypeGpbLo, kX86RegIndexDx, 1);
REG(X86GpReg, bl, kX86RegTypeGpbLo, kX86RegIndexBx, 1);
REG(X86GpReg, spl, kX86RegTypeGpbLo, kX86RegIndexSp, 1);
REG(X86GpReg, bpl, kX86RegTypeGpbLo, kX86RegIndexBp, 1);
REG(X86GpReg, sil, kX86RegTypeGpbLo, kX86RegIndexSi, 1);
REG(X86GpReg, dil, kX86RegTypeGpbLo, kX86RegIndexDi, 1);
REG(X86GpReg, r8b, kX86RegTypeGpbLo, 8, 1);
REG(X86GpReg, r9b, kX86RegTypeGpbLo, 9, 1);
REG(X86GpReg, r10b, kX86RegTypeGpbLo, 10, 1);
REG(X86GpReg, r11b, kX86RegTypeGpbLo, 11, 1);
REG(X86GpReg, r12b, kX86RegTypeGpbLo, 12, 1);
REG(X86GpReg, r13b, kX86RegTypeGpbLo, 13, 1);
REG(X86GpReg, r14b, kX86RegTypeGpbLo, 14, 1);
REG(X86GpReg, r15b, kX86RegTypeGpbLo, 15, 1);
REG(X86GpReg, ah, kX86RegTypeGpbHi, kX86RegIndexAx, 1);
REG(X86GpReg, ch, kX86RegTypeGpbHi, kX86RegIndexCx, 1);
REG(X86GpReg, dh, kX86RegTypeGpbHi, kX86RegIndexDx, 1);
REG(X86GpReg, bh, kX86RegTypeGpbHi, kX86RegIndexBx, 1);
REG(X86GpReg, ax, kX86RegTypeGpw, kX86RegIndexAx, 2);
REG(X86GpReg, cx, kX86RegTypeGpw, kX86RegIndexCx, 2);
REG(X86GpReg, dx, kX86RegTypeGpw, kX86RegIndexDx, 2);
REG(X86GpReg, bx, kX86RegTypeGpw, kX86RegIndexBx, 2);
REG(X86GpReg, sp, kX86RegTypeGpw, kX86RegIndexSp, 2);
REG(X86GpReg, bp, kX86RegTypeGpw, kX86RegIndexBp, 2);
REG(X86GpReg, si, kX86RegTypeGpw, kX86RegIndexSi, 2);
REG(X86GpReg, di, kX86RegTypeGpw, kX86RegIndexDi, 2);
REG(X86GpReg, r8w, kX86RegTypeGpw, 8, 2);
REG(X86GpReg, r9w, kX86RegTypeGpw, 9, 2);
REG(X86GpReg, r10w, kX86RegTypeGpw, 10, 2);
REG(X86GpReg, r11w, kX86RegTypeGpw, 11, 2);
REG(X86GpReg, r12w, kX86RegTypeGpw, 12, 2);
REG(X86GpReg, r13w, kX86RegTypeGpw, 13, 2);
REG(X86GpReg, r14w, kX86RegTypeGpw, 14, 2);
REG(X86GpReg, r15w, kX86RegTypeGpw, 15, 2);
REG(X86GpReg, eax, kX86RegTypeGpd, kX86RegIndexAx, 4);
REG(X86GpReg, ecx, kX86RegTypeGpd, kX86RegIndexCx, 4);
REG(X86GpReg, edx, kX86RegTypeGpd, kX86RegIndexDx, 4);
REG(X86GpReg, ebx, kX86RegTypeGpd, kX86RegIndexBx, 4);
REG(X86GpReg, esp, kX86RegTypeGpd, kX86RegIndexSp, 4);
REG(X86GpReg, ebp, kX86RegTypeGpd, kX86RegIndexBp, 4);
REG(X86GpReg, esi, kX86RegTypeGpd, kX86RegIndexSi, 4);
REG(X86GpReg, edi, kX86RegTypeGpd, kX86RegIndexDi, 4);
REG(X86GpReg, r8d, kX86RegTypeGpd, 8, 4);
REG(X86GpReg, r9d, kX86RegTypeGpd, 9, 4);
REG(X86GpReg, r10d, kX86RegTypeGpd, 10, 4);
REG(X86GpReg, r11d, kX86RegTypeGpd, 11, 4);
REG(X86GpReg, r12d, kX86RegTypeGpd, 12, 4);
REG(X86GpReg, r13d, kX86RegTypeGpd, 13, 4);
REG(X86GpReg, r14d, kX86RegTypeGpd, 14, 4);
REG(X86GpReg, r15d, kX86RegTypeGpd, 15, 4);
REG(X86GpReg, rax, kX86RegTypeGpq, kX86RegIndexAx, 8);
REG(X86GpReg, rcx, kX86RegTypeGpq, kX86RegIndexCx, 8);
REG(X86GpReg, rdx, kX86RegTypeGpq, kX86RegIndexDx, 8);
REG(X86GpReg, rbx, kX86RegTypeGpq, kX86RegIndexBx, 8);
REG(X86GpReg, rsp, kX86RegTypeGpq, kX86RegIndexSp, 8);
REG(X86GpReg, rbp, kX86RegTypeGpq, kX86RegIndexBp, 8);
REG(X86GpReg, rsi, kX86RegTypeGpq, kX86RegIndexSi, 8);
REG(X86GpReg, rdi, kX86RegTypeGpq, kX86RegIndexDi, 8);
REG(X86GpReg, r8, kX86RegTypeGpq, 8, 8);
REG(X86GpReg, r9, kX86RegTypeGpq, 9, 8);
REG(X86GpReg, r10, kX86RegTypeGpq, 10, 8);
REG(X86GpReg, r11, kX86RegTypeGpq, 11, 8);
REG(X86GpReg, r12, kX86RegTypeGpq, 12, 8);
REG(X86GpReg, r13, kX86RegTypeGpq, 13, 8);
REG(X86GpReg, r14, kX86RegTypeGpq, 14, 8);
REG(X86GpReg, r15, kX86RegTypeGpq, 15, 8);
REG(X86FpReg, fp0, kX86RegTypeFp, 0, 10);
REG(X86FpReg, fp1, kX86RegTypeFp, 1, 10);
REG(X86FpReg, fp2, kX86RegTypeFp, 2, 10);
REG(X86FpReg, fp3, kX86RegTypeFp, 3, 10);
REG(X86FpReg, fp4, kX86RegTypeFp, 4, 10);
REG(X86FpReg, fp5, kX86RegTypeFp, 5, 10);
REG(X86FpReg, fp6, kX86RegTypeFp, 6, 10);
REG(X86FpReg, fp7, kX86RegTypeFp, 7, 10);
REG(X86MmReg, mm0, kX86RegTypeMm, 0, 8);
REG(X86MmReg, mm1, kX86RegTypeMm, 1, 8);
REG(X86MmReg, mm2, kX86RegTypeMm, 2, 8);
REG(X86MmReg, mm3, kX86RegTypeMm, 3, 8);
REG(X86MmReg, mm4, kX86RegTypeMm, 4, 8);
REG(X86MmReg, mm5, kX86RegTypeMm, 5, 8);
REG(X86MmReg, mm6, kX86RegTypeMm, 6, 8);
REG(X86MmReg, mm7, kX86RegTypeMm, 7, 8);
REG(X86XmmReg, xmm0, kX86RegTypeXmm, 0, 16);
REG(X86XmmReg, xmm1, kX86RegTypeXmm, 1, 16);
REG(X86XmmReg, xmm2, kX86RegTypeXmm, 2, 16);
REG(X86XmmReg, xmm3, kX86RegTypeXmm, 3, 16);
REG(X86XmmReg, xmm4, kX86RegTypeXmm, 4, 16);
REG(X86XmmReg, xmm5, kX86RegTypeXmm, 5, 16);
REG(X86XmmReg, xmm6, kX86RegTypeXmm, 6, 16);
REG(X86XmmReg, xmm7, kX86RegTypeXmm, 7, 16);
REG(X86XmmReg, xmm8, kX86RegTypeXmm, 8, 16);
REG(X86XmmReg, xmm9, kX86RegTypeXmm, 9, 16);
REG(X86XmmReg, xmm10, kX86RegTypeXmm, 10, 16);
REG(X86XmmReg, xmm11, kX86RegTypeXmm, 11, 16);
REG(X86XmmReg, xmm12, kX86RegTypeXmm, 12, 16);
REG(X86XmmReg, xmm13, kX86RegTypeXmm, 13, 16);
REG(X86XmmReg, xmm14, kX86RegTypeXmm, 14, 16);
REG(X86XmmReg, xmm15, kX86RegTypeXmm, 15, 16);
REG(X86YmmReg, ymm0, kX86RegTypeYmm, 0, 32);
REG(X86YmmReg, ymm1, kX86RegTypeYmm, 1, 32);
REG(X86YmmReg, ymm2, kX86RegTypeYmm, 2, 32);
REG(X86YmmReg, ymm3, kX86RegTypeYmm, 3, 32);
REG(X86YmmReg, ymm4, kX86RegTypeYmm, 4, 32);
REG(X86YmmReg, ymm5, kX86RegTypeYmm, 5, 32);
REG(X86YmmReg, ymm6, kX86RegTypeYmm, 6, 32);
REG(X86YmmReg, ymm7, kX86RegTypeYmm, 7, 32);
REG(X86YmmReg, ymm8, kX86RegTypeYmm, 8, 32);
REG(X86YmmReg, ymm9, kX86RegTypeYmm, 9, 32);
REG(X86YmmReg, ymm10, kX86RegTypeYmm, 10, 32);
REG(X86YmmReg, ymm11, kX86RegTypeYmm, 11, 32);
REG(X86YmmReg, ymm12, kX86RegTypeYmm, 12, 32);
REG(X86YmmReg, ymm13, kX86RegTypeYmm, 13, 32);
REG(X86YmmReg, ymm14, kX86RegTypeYmm, 14, 32);
REG(X86YmmReg, ymm15, kX86RegTypeYmm, 15, 32);
REG(X86SegReg, cs, kX86RegTypeSeg, kX86SegCs, 2);
REG(X86SegReg, ss, kX86RegTypeSeg, kX86SegSs, 2);
REG(X86SegReg, ds, kX86RegTypeSeg, kX86SegDs, 2);
REG(X86SegReg, es, kX86RegTypeSeg, kX86SegEs, 2);
REG(X86SegReg, fs, kX86RegTypeSeg, kX86SegFs, 2);
REG(X86SegReg, gs, kX86RegTypeSeg, kX86SegGs, 2);
}}
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
} // x86 namespace
} // asmjit namespace
// [Api-End]
......
......@@ -76,7 +76,7 @@ Error X86Scheduler::run(Node* start, Node* stop) {
Node* next = node_->getNext();
ASMJIT_ASSERT(node_->getType() == kNodeTypeInst);
printf(" %s\n", X86Util::getInstInfo(static_cast<InstNode*>(node_)->getCode()).getInstName());
printf(" %s\n", X86Util::getInstInfo(static_cast<InstNode*>(node_)->getInstId()).getInstName());
node_ = next;
}
......
......@@ -90,7 +90,7 @@ static void encodeString(const string& str, string* outString) {
// Below 32 is symbolic.
char buf[ 32 ];
snprintf(buf, sizeof(buf), "&#x%02X;", (unsigned) (c & 0xff));
sprintf(buf, "&#x%02X;", (unsigned) (c & 0xff));
//*ME: warning C4267: convert 'size_t' to 'int'
//*ME: Int-Cast to make compiler happy ...
......
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