// AsmJit - Complete JIT Assembler for C++ Language. // Copyright (c) 2008-2010, Petr Kobalicek // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // [Guard] #ifndef _ASMJIT_DEFSX86X64_H #define _ASMJIT_DEFSX86X64_H #if !defined(_ASMJIT_DEFS_H) #warning "AsmJit/DefsX86X64.h can be only included by AsmJit/Defs.h" #endif // _ASMJIT_DEFS_H // [Dependencies] #include "Build.h" #include "Util.h" #include #include // [Api-Begin] #include "ApiBegin.h" namespace AsmJit { //! @addtogroup AsmJit_Core //! @{ // ============================================================================ // [AsmJit::REG_NUM] // ============================================================================ //! @var REG_NUM //! @brief Count of General purpose registers and XMM registers. //! //! Count of general purpose registers and XMM registers depends to current //! bit-mode. If application is compiled for 32-bit platform then this number //! is 8, 64-bit platforms have 8 extra general purpose and xmm registers (16 //! total). //! @brief Count of registers. enum REG_NUM { //! @var REG_NUM_BASE //! //! Count of general purpose registers and XMM registers depends to current //! bit-mode. If application is compiled for 32-bit platform then this number //! is 8, 64-bit platforms have 8 extra general purpose and xmm registers (16 //! total). #if defined(ASMJIT_X86) REG_NUM_BASE = 8, #else REG_NUM_BASE = 16, #endif // ASMJIT //! @brief Count of general purpose registers. //! //! 8 in 32-bit mode and 16 in 64-bit mode. REG_NUM_GP = REG_NUM_BASE, //! @brief Count of MM registers (always 8). REG_NUM_MM = 8, //! @brief Count of FPU stack registers (always 8). REG_NUM_FPU = 8, //! @brief Count of XMM registers. //! //! 8 in 32-bit mode and 16 in 64-bit mode. REG_NUM_XMM = REG_NUM_BASE }; // ============================================================================ // [AsmJit::REG_INDEX] // ============================================================================ //! @brief Valid X86 register indexes. //! //! These codes are real, don't miss with @c REG enum! and don't use these //! values if you are not writing AsmJit code. enum REG_INDEX { //! @brief Mask for register code (index). REG_INDEX_MASK = 0x00FF, //! @brief ID for AX/EAX/RAX registers. REG_INDEX_EAX = 0, //! @brief ID for CX/ECX/RCX registers. REG_INDEX_ECX = 1, //! @brief ID for DX/EDX/RDX registers. REG_INDEX_EDX = 2, //! @brief ID for BX/EBX/RBX registers. REG_INDEX_EBX = 3, //! @brief ID for SP/ESP/RSP registers. REG_INDEX_ESP = 4, //! @brief ID for BP/EBP/RBP registers. REG_INDEX_EBP = 5, //! @brief ID for SI/ESI/RSI registers. REG_INDEX_ESI = 6, //! @brief ID for DI/EDI/RDI registers. REG_INDEX_EDI = 7, #if defined(ASMJIT_X64) //! @brief ID for AX/EAX/RAX registers. REG_INDEX_RAX = 0, //! @brief ID for CX/ECX/RCX registers. REG_INDEX_RCX = 1, //! @brief ID for DX/EDX/RDX registers. REG_INDEX_RDX = 2, //! @brief ID for BX/EBX/RBX registers. REG_INDEX_RBX = 3, //! @brief ID for SP/ESP/RSP registers. REG_INDEX_RSP = 4, //! @brief ID for BP/EBP/RBP registers. REG_INDEX_RBP = 5, //! @brief ID for SI/ESI/RSI registers. REG_INDEX_RSI = 6, //! @brief ID for DI/EDI/RDI registers. REG_INDEX_RDI = 7, //! @brief ID for r8 register (additional register introduced by 64-bit architecture). REG_INDEX_R8 = 8, //! @brief ID for R9 register (additional register introduced by 64-bit architecture). REG_INDEX_R9 = 9, //! @brief ID for R10 register (additional register introduced by 64-bit architecture). REG_INDEX_R10 = 10, //! @brief ID for R11 register (additional register introduced by 64-bit architecture). REG_INDEX_R11 = 11, //! @brief ID for R12 register (additional register introduced by 64-bit architecture). REG_INDEX_R12 = 12, //! @brief ID for R13 register (additional register introduced by 64-bit architecture). REG_INDEX_R13 = 13, //! @brief ID for R14 register (additional register introduced by 64-bit architecture). REG_INDEX_R14 = 14, //! @brief ID for R15 register (additional register introduced by 64-bit architecture). REG_INDEX_R15 = 15, #endif // ASMJIT_X64 //! @brief ID for mm0 register. REG_INDEX_MM0 = 0, //! @brief ID for mm1 register. REG_INDEX_MM1 = 1, //! @brief ID for mm2 register. REG_INDEX_MM2 = 2, //! @brief ID for mm3 register. REG_INDEX_MM3 = 3, //! @brief ID for mm4 register. REG_INDEX_MM4 = 4, //! @brief ID for mm5 register. REG_INDEX_MM5 = 5, //! @brief ID for mm6 register. REG_INDEX_MM6 = 6, //! @brief ID for mm7 register. REG_INDEX_MM7 = 7, //! @brief ID for xmm0 register. REG_INDEX_XMM0 = 0, //! @brief ID for xmm1 register. REG_INDEX_XMM1 = 1, //! @brief ID for xmm2 register. REG_INDEX_XMM2 = 2, //! @brief ID for xmm3 register. REG_INDEX_XMM3 = 3, //! @brief ID for xmm4 register. REG_INDEX_XMM4 = 4, //! @brief ID for xmm5 register. REG_INDEX_XMM5 = 5, //! @brief ID for xmm6 register. REG_INDEX_XMM6 = 6, //! @brief ID for xmm7 register. REG_INDEX_XMM7 = 7 #if defined(ASMJIT_X64) , //! @brief ID for xmm8 register (additional register introduced by 64-bit architecture). REG_INDEX_XMM8 = 8, //! @brief ID for xmm9 register (additional register introduced by 64-bit architecture). REG_INDEX_XMM9 = 9, //! @brief ID for xmm10 register (additional register introduced by 64-bit architecture). REG_INDEX_XMM10 = 10, //! @brief ID for xmm11 register (additional register introduced by 64-bit architecture). REG_INDEX_XMM11 = 11, //! @brief ID for xmm12 register (additional register introduced by 64-bit architecture). REG_INDEX_XMM12 = 12, //! @brief ID for xmm13 register (additional register introduced by 64-bit architecture). REG_INDEX_XMM13 = 13, //! @brief ID for xmm14 register (additional register introduced by 64-bit architecture). REG_INDEX_XMM14 = 14, //! @brief ID for xmm15 register (additional register introduced by 64-bit architecture). REG_INDEX_XMM15 = 15 #endif // ASMJIT_X64 }; // ============================================================================ // [AsmJit::REG_TYPE] // ============================================================================ //! @brief Pseudo (not real X86) register types. enum REG_TYPE { //! @brief Mask for register type. REG_TYPE_MASK = 0xFF00, // First byte contains register type (mask 0xFF00), Second byte contains // register index code. // -------------------------------------------------------------------------- // [GP Register Types] // -------------------------------------------------------------------------- //! @brief 8-bit general purpose register type (LO). REG_TYPE_GPB_LO = 0x0100, //! @brief 8-bit general purpose register type (HI, only AH, BH, CH, DH). REG_TYPE_GPB_HI = 0x0200, //! @brief 16-bit general purpose register type. REG_TYPE_GPW = 0x1000, //! @brief 32-bit general purpose register type. REG_TYPE_GPD = 0x2000, //! @brief 64-bit general purpose register type. REG_TYPE_GPQ = 0x3000, //! @var REG_GPN //! @brief 32-bit or 64-bit general purpose register type. // native 32-bit or 64-bit register type (depends to x86 or x64 mode). #if defined(ASMJIT_X86) REG_TYPE_GPN = REG_TYPE_GPD, #else REG_TYPE_GPN = REG_TYPE_GPQ, #endif // -------------------------------------------------------------------------- // [X87 (FPU) Register Type] // -------------------------------------------------------------------------- //! @brief X87 (FPU) register type. REG_TYPE_X87 = 0x5000, // -------------------------------------------------------------------------- // [MM Register Type] // -------------------------------------------------------------------------- //! @brief 64-bit MM register type. REG_TYPE_MM = 0x6000, // -------------------------------------------------------------------------- // [XMM Register Type] // -------------------------------------------------------------------------- //! @brief 128-bit XMM register type. REG_TYPE_XMM = 0x7000 }; // ============================================================================ // [AsmJit::REG_CODE] // ============================================================================ //! @brief Pseudo (not real X86) register codes used for generating opcodes. //! //! From this register code can be generated real x86 register ID, type of //! register and size of register. enum REG_CODE { // -------------------------------------------------------------------------- // [8-bit Registers] // -------------------------------------------------------------------------- REG_AL = REG_TYPE_GPB_LO, REG_CL, REG_DL, REG_BL, #if defined(ASMJIT_X64) REG_SPL, REG_BPL, REG_SIL, REG_DIL, #endif // ASMJIT_X64 #if defined(ASMJIT_X64) REG_R8B, REG_R9B, REG_R10B, REG_R11B, REG_R12B, REG_R13B, REG_R14B, REG_R15B, #endif // ASMJIT_X64 REG_AH = REG_TYPE_GPB_HI, REG_CH, REG_DH, REG_BH, // -------------------------------------------------------------------------- // [16-bit Registers] // -------------------------------------------------------------------------- REG_AX = REG_TYPE_GPW, REG_CX, REG_DX, REG_BX, REG_SP, REG_BP, REG_SI, REG_DI, #if defined(ASMJIT_X64) REG_R8W, REG_R9W, REG_R10W, REG_R11W, REG_R12W, REG_R13W, REG_R14W, REG_R15W, #endif // ASMJIT_X64 // -------------------------------------------------------------------------- // [32-bit Registers] // -------------------------------------------------------------------------- REG_EAX = REG_TYPE_GPD, REG_ECX, REG_EDX, REG_EBX, REG_ESP, REG_EBP, REG_ESI, REG_EDI, #if defined(ASMJIT_X64) REG_R8D, REG_R9D, REG_R10D, REG_R11D, REG_R12D, REG_R13D, REG_R14D, REG_R15D, #endif // ASMJIT_X64 // -------------------------------------------------------------------------- // [64-bit Registers] // -------------------------------------------------------------------------- #if defined(ASMJIT_X64) REG_RAX = REG_TYPE_GPQ, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI, REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, #endif // ASMJIT_X64 // -------------------------------------------------------------------------- // [MM Registers] // -------------------------------------------------------------------------- REG_MM0 = REG_TYPE_MM, REG_MM1, REG_MM2, REG_MM3, REG_MM4, REG_MM5, REG_MM6, REG_MM7, // -------------------------------------------------------------------------- // [XMM Registers] // -------------------------------------------------------------------------- REG_XMM0 = REG_TYPE_XMM, REG_XMM1, REG_XMM2, REG_XMM3, REG_XMM4, REG_XMM5, REG_XMM6, REG_XMM7, #if defined(ASMJIT_X64) REG_XMM8, REG_XMM9, REG_XMM10, REG_XMM11, REG_XMM12, REG_XMM13, REG_XMM14, REG_XMM15, #endif // ASMJIT_X64 // -------------------------------------------------------------------------- // [Native registers (depends if processor runs in 32-bit or 64-bit mode)] // -------------------------------------------------------------------------- REG_NAX = REG_TYPE_GPN, REG_NCX, REG_NDX, REG_NBX, REG_NSP, REG_NBP, REG_NSI, REG_NDI }; // ============================================================================ // [AsmJit::SEGMENT_PREFIX] // ============================================================================ //! @brief Segment override prefixes. enum SEGMENT_PREFIX { // DO NOT MODIFY INDEX CODES - They are used by logger in this order. //! @brief No segment override prefix. SEGMENT_NONE = 0, //! @brief Use 'cs' segment override prefix. SEGMENT_CS = 1, //! @brief Use 'ss' segment override prefix. SEGMENT_SS = 2, //! @brief Use 'ds' segment override prefix. SEGMENT_DS = 3, //! @brief Use 'es' segment override prefix. SEGMENT_ES = 4, //! @brief Use 'fs' segment override prefix. SEGMENT_FS = 5, //! @brief Use 'gs' segment override prefix. SEGMENT_GS = 6, //! @brief End of prefix codes _SEGMENT_END }; // ============================================================================ // [AsmJit::PREFETCH_HINT] // ============================================================================ //! @brief Prefetch hints. enum PREFETCH_HINT { //! @brief Prefetch to L0 cache. PREFETCH_T0 = 1, //! @brief Prefetch to L1 cache. PREFETCH_T1 = 2, //! @brief Prefetch to L2 cache. PREFETCH_T2 = 3, //! @brief Prefetch using NT hint. PREFETCH_NTA = 0 }; // ============================================================================ // [AsmJit::CONDITION] // ============================================================================ //! @brief Condition codes. enum CONDITION { //! @brief No condition code. C_NO_CONDITION = -1, // Condition codes from processor manuals. C_A = 0x7, C_AE = 0x3, C_B = 0x2, C_BE = 0x6, C_C = 0x2, C_E = 0x4, C_G = 0xF, C_GE = 0xD, C_L = 0xC, C_LE = 0xE, C_NA = 0x6, C_NAE = 0x2, C_NB = 0x3, C_NBE = 0x7, C_NC = 0x3, C_NE = 0x5, C_NG = 0xE, C_NGE = 0xC, C_NL = 0xD, C_NLE = 0xF, C_NO = 0x1, C_NP = 0xB, C_NS = 0x9, C_NZ = 0x5, C_O = 0x0, C_P = 0xA, C_PE = 0xA, C_PO = 0xB, C_S = 0x8, C_Z = 0x4, // Simplified condition codes C_OVERFLOW = 0x0, C_NO_OVERFLOW = 0x1, C_BELOW = 0x2, C_ABOVE_EQUAL = 0x3, C_EQUAL = 0x4, C_NOT_EQUAL = 0x5, C_BELOW_EQUAL = 0x6, C_ABOVE = 0x7, C_SIGN = 0x8, C_NOT_SIGN = 0x9, C_PARITY_EVEN = 0xA, C_PARITY_ODD = 0xB, C_LESS = 0xC, C_GREATER_EQUAL = 0xD, C_LESS_EQUAL = 0xE, C_GREATER = 0xF, // aliases C_ZERO = 0x4, C_NOT_ZERO = 0x5, C_NEGATIVE = 0x8, C_POSITIVE = 0x9, // x87 floating point only C_FP_UNORDERED = 16, C_FP_NOT_UNORDERED = 17 }; //! @brief Returns the equivalent of !cc. //! //! Negation of the default no_condition (-1) results in a non-default //! no_condition value (-2). As long as tests for no_condition check //! for condition < 0, this will work as expected. static inline CONDITION negateCondition(CONDITION cc) { return static_cast(cc ^ 1); } //! @brief Corresponds to transposing the operands of a comparison. static inline CONDITION reverseCondition(CONDITION cc) { switch (cc) { case C_BELOW: return C_ABOVE; case C_ABOVE: return C_BELOW; case C_ABOVE_EQUAL: return C_BELOW_EQUAL; case C_BELOW_EQUAL: return C_ABOVE_EQUAL; case C_LESS: return C_GREATER; case C_GREATER: return C_LESS; case C_GREATER_EQUAL: return C_LESS_EQUAL; case C_LESS_EQUAL: return C_GREATER_EQUAL; default: return cc; }; } struct ASMJIT_API ConditionToInstruction { //! @brief Used to map condition code to jcc instructions. static const uint32_t _jcctable[16]; //! @brief Used to map condition code to cmovcc instructions. static const uint32_t _cmovcctable[16]; //! @brief Used to map condition code to setcc instructions. static const uint32_t _setcctable[16]; //! @brief Translate condition code @a cc to jcc instruction code. //! @sa @c INST_CODE, @c INST_J. static inline uint32_t toJCC(CONDITION cc) ASMJIT_NOTHROW { ASMJIT_ASSERT(static_cast(cc) <= 0xF); return _jcctable[cc]; } //! @brief Translate condition code @a cc to cmovcc instruction code. //! @sa @c INST_CODE, @c INST_CMOV. static inline uint32_t toCMovCC(CONDITION cc) ASMJIT_NOTHROW { ASMJIT_ASSERT(static_cast(cc) <= 0xF); return _cmovcctable[cc]; } //! @brief Translate condition code @a cc to setcc instruction code. //! @sa @c INST_CODE, @c INST_SET. static inline uint32_t toSetCC(CONDITION cc) ASMJIT_NOTHROW { ASMJIT_ASSERT(static_cast(cc) <= 0xF); return _setcctable[cc]; } }; // ============================================================================ // [AsmJit::SCALE] // ============================================================================ //! @brief Scale, can be used for addressing. //! //! See @c Op and addressing methods like @c byte_ptr(), @c word_ptr(), //! @c dword_ptr(), etc... enum SCALE { //! @brief Scale 1 times (no scale). TIMES_1 = 0, //! @brief Scale 2 times (same as shifting to left by 1). TIMES_2 = 1, //! @brief Scale 4 times (same as shifting to left by 2). TIMES_4 = 2, //! @brief Scale 8 times (same as shifting to left by 3). TIMES_8 = 3 }; // ============================================================================ // [AsmJit::HINT] // ============================================================================ //! @brief Condition hint, see @c AsmJit::Assembler::jz(), @c AsmJit::Compiler::jz() //! and friends. enum HINT { //! @brief No hint. HINT_NONE = 0x00, //! @brief Condition will be taken (likely). HINT_TAKEN = 0x01, //! @brief Condition will be not taken (unlikely). HINT_NOT_TAKEN = 0x02 }; //! @brief Hint byte value is the byte that will be emitted if hint flag //! is specified by @c HINT. enum HINT_BYTE_VALUE { //! @brief Condition will be taken (likely). HINT_BYTE_VALUE_TAKEN = 0x3E, //! @brief Condition will be not taken (unlikely). HINT_BYTE_VALUE_NOT_TAKEN = 0x2E }; // ============================================================================ // [AsmJit::FP_STATUS] // ============================================================================ //! @brief Floating point status. enum FP_STATUS { FP_C0 = 0x100, FP_C1 = 0x200, FP_C2 = 0x400, FP_C3 = 0x4000, FP_CC_MASK = 0x4500 }; // ============================================================================ // [AsmJit::FP_CW] // ============================================================================ //! @brief Floating point control word. enum FP_CW { FP_CW_INVOPEX_MASK = 0x001, FP_CW_DENOPEX_MASK = 0x002, FP_CW_ZERODIV_MASK = 0x004, FP_CW_OVFEX_MASK = 0x008, FP_CW_UNDFEX_MASK = 0x010, FP_CW_PRECEX_MASK = 0x020, FP_CW_PRECC_MASK = 0x300, FP_CW_ROUNDC_MASK = 0xC00, // Values for precision control. FP_CW_PREC_SINGLE = 0x000, FP_CW_PREC_DOUBLE = 0x200, FP_CW_PREC_EXTENDED = 0x300, // Values for rounding control. FP_CW_ROUND_NEAREST = 0x000, FP_CW_ROUND_DOWN = 0x400, FP_CW_ROUND_UP = 0x800, FP_CW_ROUND_TOZERO = 0xC00 }; // ============================================================================ // [AsmJit::INST_CODE] // ============================================================================ //! @brief Instruction codes. //! //! Note that these instruction codes are AsmJit specific. Each instruction is //! unique ID into AsmJit instruction table. Instruction codes are used together //! with AsmJit::Assembler and you can also use instruction codes to serialize //! instructions by @ref AssemblerCore::_emitInstruction() or //! @ref CompilerCore::_emitInstruction() enum INST_CODE { INST_ADC, // X86/X64 INST_ADD, // X86/X64 INST_ADDPD, INST_ADDPS, INST_ADDSD, INST_ADDSS, INST_ADDSUBPD, INST_ADDSUBPS, INST_AMD_PREFETCH, INST_AMD_PREFETCHW, INST_AND, // X86/X64 INST_ANDNPD, INST_ANDNPS, INST_ANDPD, INST_ANDPS, INST_BLENDPD, INST_BLENDPS, INST_BLENDVPD, INST_BLENDVPS, INST_BSF, // X86/X64 INST_BSR, // X86/X64 INST_BSWAP, // X86/X64 (i486) INST_BT, // X86/X64 INST_BTC, // X86/X64 INST_BTR, // X86/X64 INST_BTS, // X86/X64 INST_CALL, // X86/X64 INST_CBW, // X86/X64 INST_CDQE, // X64 only INST_CLC, // X86/X64 INST_CLD, // X86/X64 INST_CLFLUSH, INST_CMC, // X86/X64 INST_CMOV, // Begin (cmovcc) (i586) INST_CMOVA = INST_CMOV, //X86/X64 (cmovcc) (i586) INST_CMOVAE, // X86/X64 (cmovcc) (i586) INST_CMOVB, // X86/X64 (cmovcc) (i586) INST_CMOVBE, // X86/X64 (cmovcc) (i586) INST_CMOVC, // X86/X64 (cmovcc) (i586) INST_CMOVE, // X86/X64 (cmovcc) (i586) INST_CMOVG, // X86/X64 (cmovcc) (i586) INST_CMOVGE, // X86/X64 (cmovcc) (i586) INST_CMOVL, // X86/X64 (cmovcc) (i586) INST_CMOVLE, // X86/X64 (cmovcc) (i586) INST_CMOVNA, // X86/X64 (cmovcc) (i586) INST_CMOVNAE, // X86/X64 (cmovcc) (i586) INST_CMOVNB, // X86/X64 (cmovcc) (i586) INST_CMOVNBE, // X86/X64 (cmovcc) (i586) INST_CMOVNC, // X86/X64 (cmovcc) (i586) INST_CMOVNE, // X86/X64 (cmovcc) (i586) INST_CMOVNG, // X86/X64 (cmovcc) (i586) INST_CMOVNGE, // X86/X64 (cmovcc) (i586) INST_CMOVNL, // X86/X64 (cmovcc) (i586) INST_CMOVNLE, // X86/X64 (cmovcc) (i586) INST_CMOVNO, // X86/X64 (cmovcc) (i586) INST_CMOVNP, // X86/X64 (cmovcc) (i586) INST_CMOVNS, // X86/X64 (cmovcc) (i586) INST_CMOVNZ, // X86/X64 (cmovcc) (i586) INST_CMOVO, // X86/X64 (cmovcc) (i586) INST_CMOVP, // X86/X64 (cmovcc) (i586) INST_CMOVPE, // X86/X64 (cmovcc) (i586) INST_CMOVPO, // X86/X64 (cmovcc) (i586) INST_CMOVS, // X86/X64 (cmovcc) (i586) INST_CMOVZ, // X86/X64 (cmovcc) (i586) INST_CMP, // X86/X64 INST_CMPPD, INST_CMPPS, INST_CMPSD, INST_CMPSS, INST_CMPXCHG, // X86/X64 (i486) INST_CMPXCHG16B, // X64 only INST_CMPXCHG8B, // X86/X64 (i586) INST_COMISD, INST_COMISS, INST_CPUID, // X86/X64 (i486) INST_CRC32, INST_CVTDQ2PD, INST_CVTDQ2PS, INST_CVTPD2DQ, INST_CVTPD2PI, INST_CVTPD2PS, INST_CVTPI2PD, INST_CVTPI2PS, INST_CVTPS2DQ, INST_CVTPS2PD, INST_CVTPS2PI, INST_CVTSD2SI, INST_CVTSD2SS, INST_CVTSI2SD, INST_CVTSI2SS, INST_CVTSS2SD, INST_CVTSS2SI, INST_CVTTPD2DQ, INST_CVTTPD2PI, INST_CVTTPS2DQ, INST_CVTTPS2PI, INST_CVTTSD2SI, INST_CVTTSS2SI, INST_CWDE, // X86/X64 INST_DAA, // X86 only INST_DAS, // X86 only INST_DEC, // X86/X64 INST_DIV, // X86/X64 INST_DIVPD, INST_DIVPS, INST_DIVSD, INST_DIVSS, INST_DPPD, INST_DPPS, INST_EMMS, // MMX INST_ENTER, // X86/X64 INST_EXTRACTPS, INST_F2XM1, // X87 INST_FABS, // X87 INST_FADD, // X87 INST_FADDP, // X87 INST_FBLD, // X87 INST_FBSTP, // X87 INST_FCHS, // X87 INST_FCLEX, // X87 INST_FCMOVB, // X87 INST_FCMOVBE, // X87 INST_FCMOVE, // X87 INST_FCMOVNB, // X87 INST_FCMOVNBE, // X87 INST_FCMOVNE, // X87 INST_FCMOVNU, // X87 INST_FCMOVU, // X87 INST_FCOM, // X87 INST_FCOMI, // X87 INST_FCOMIP, // X87 INST_FCOMP, // X87 INST_FCOMPP, // X87 INST_FCOS, // X87 INST_FDECSTP, // X87 INST_FDIV, // X87 INST_FDIVP, // X87 INST_FDIVR, // X87 INST_FDIVRP, // X87 INST_FEMMS, // 3dNow! INST_FFREE, // X87 INST_FIADD, // X87 INST_FICOM, // X87 INST_FICOMP, // X87 INST_FIDIV, // X87 INST_FIDIVR, // X87 INST_FILD, // X87 INST_FIMUL, // X87 INST_FINCSTP, // X87 INST_FINIT, // X87 INST_FIST, // X87 INST_FISTP, // X87 INST_FISTTP, INST_FISUB, // X87 INST_FISUBR, // X87 INST_FLD, // X87 INST_FLD1, // X87 INST_FLDCW, // X87 INST_FLDENV, // X87 INST_FLDL2E, // X87 INST_FLDL2T, // X87 INST_FLDLG2, // X87 INST_FLDLN2, // X87 INST_FLDPI, // X87 INST_FLDZ, // X87 INST_FMUL, // X87 INST_FMULP, // X87 INST_FNCLEX, // X87 INST_FNINIT, // X87 INST_FNOP, // X87 INST_FNSAVE, // X87 INST_FNSTCW, // X87 INST_FNSTENV, // X87 INST_FNSTSW, // X87 INST_FPATAN, // X87 INST_FPREM, // X87 INST_FPREM1, // X87 INST_FPTAN, // X87 INST_FRNDINT, // X87 INST_FRSTOR, // X87 INST_FSAVE, // X87 INST_FSCALE, // X87 INST_FSIN, // X87 INST_FSINCOS, // X87 INST_FSQRT, // X87 INST_FST, // X87 INST_FSTCW, // X87 INST_FSTENV, // X87 INST_FSTP, // X87 INST_FSTSW, // X87 INST_FSUB, // X87 INST_FSUBP, // X87 INST_FSUBR, // X87 INST_FSUBRP, // X87 INST_FTST, // X87 INST_FUCOM, // X87 INST_FUCOMI, // X87 INST_FUCOMIP, // X87 INST_FUCOMP, // X87 INST_FUCOMPP, // X87 INST_FWAIT, // X87 INST_FXAM, // X87 INST_FXCH, // X87 INST_FXRSTOR, // X87 INST_FXSAVE, // X87 INST_FXTRACT, // X87 INST_FYL2X, // X87 INST_FYL2XP1, // X87 INST_HADDPD, INST_HADDPS, INST_HSUBPD, INST_HSUBPS, INST_IDIV, // X86/X64 INST_IMUL, // X86/X64 INST_INC, // X86/X64 INST_INT3, // X86/X64 INST_J, // Begin (jcc) INST_JA = INST_J, // X86/X64 (jcc) INST_JAE, // X86/X64 (jcc) INST_JB, // X86/X64 (jcc) INST_JBE, // X86/X64 (jcc) INST_JC, // X86/X64 (jcc) INST_JE, // X86/X64 (jcc) INST_JG, // X86/X64 (jcc) INST_JGE, // X86/X64 (jcc) INST_JL, // X86/X64 (jcc) INST_JLE, // X86/X64 (jcc) INST_JNA, // X86/X64 (jcc) INST_JNAE, // X86/X64 (jcc) INST_JNB, // X86/X64 (jcc) INST_JNBE, // X86/X64 (jcc) INST_JNC, // X86/X64 (jcc) INST_JNE, // X86/X64 (jcc) INST_JNG, // X86/X64 (jcc) INST_JNGE, // X86/X64 (jcc) INST_JNL, // X86/X64 (jcc) INST_JNLE, // X86/X64 (jcc) INST_JNO, // X86/X64 (jcc) INST_JNP, // X86/X64 (jcc) INST_JNS, // X86/X64 (jcc) INST_JNZ, // X86/X64 (jcc) INST_JO, // X86/X64 (jcc) INST_JP, // X86/X64 (jcc) INST_JPE, // X86/X64 (jcc) INST_JPO, // X86/X64 (jcc) INST_JS, // X86/X64 (jcc) INST_JZ, // X86/X64 (jcc) INST_JMP, // X86/X64 (jmp) INST_LDDQU, INST_LDMXCSR, INST_LAHF, // X86/X64 (CPUID NEEDED) INST_LEA, // X86/X64 INST_LEAVE, // X86/X64 INST_LFENCE, INST_MASKMOVDQU, INST_MASKMOVQ, // MMX Extensions INST_MAXPD, INST_MAXPS, INST_MAXSD, INST_MAXSS, INST_MFENCE, INST_MINPD, INST_MINPS, INST_MINSD, INST_MINSS, INST_MONITOR, INST_MOV, // X86/X64 INST_MOVAPD, INST_MOVAPS, INST_MOVBE, INST_MOVD, INST_MOVDDUP, INST_MOVDQ2Q, INST_MOVDQA, INST_MOVDQU, INST_MOVHLPS, INST_MOVHPD, INST_MOVHPS, INST_MOVLHPS, INST_MOVLPD, INST_MOVLPS, INST_MOVMSKPD, INST_MOVMSKPS, INST_MOVNTDQ, INST_MOVNTDQA, INST_MOVNTI, INST_MOVNTPD, INST_MOVNTPS, INST_MOVNTQ, // MMX Extensions INST_MOVQ, INST_MOVQ2DQ, INST_MOVSD, INST_MOVSHDUP, INST_MOVSLDUP, INST_MOVSS, INST_MOVSX, // X86/X64 INST_MOVSXD, // X86/X64 INST_MOVUPD, INST_MOVUPS, INST_MOVZX, // X86/X64 INST_MOV_PTR, // X86/X64 INST_MPSADBW, INST_MUL, // X86/X64 INST_MULPD, INST_MULPS, INST_MULSD, INST_MULSS, INST_MWAIT, INST_NEG, // X86/X64 INST_NOP, // X86/X64 INST_NOT, // X86/X64 INST_OR, // X86/X64 INST_ORPD, INST_ORPS, INST_PABSB, INST_PABSD, INST_PABSW, INST_PACKSSDW, INST_PACKSSWB, INST_PACKUSDW, INST_PACKUSWB, INST_PADDB, INST_PADDD, INST_PADDQ, INST_PADDSB, INST_PADDSW, INST_PADDUSB, INST_PADDUSW, INST_PADDW, INST_PALIGNR, INST_PAND, INST_PANDN, INST_PAUSE, INST_PAVGB, // MMX Extensions INST_PAVGW, // MMX Extensions INST_PBLENDVB, INST_PBLENDW, INST_PCMPEQB, INST_PCMPEQD, INST_PCMPEQQ, INST_PCMPEQW, INST_PCMPESTRI, INST_PCMPESTRM, INST_PCMPGTB, INST_PCMPGTD, INST_PCMPGTQ, INST_PCMPGTW, INST_PCMPISTRI, INST_PCMPISTRM, INST_PEXTRB, INST_PEXTRD, INST_PEXTRQ, INST_PEXTRW, // MMX Extensions INST_PF2ID, // 3dNow! INST_PF2IW, // 3dNow! Extensions INST_PFACC, // 3dNow! INST_PFADD, // 3dNow! INST_PFCMPEQ, // 3dNow! INST_PFCMPGE, // 3dNow! INST_PFCMPGT, // 3dNow! INST_PFMAX, // 3dNow! INST_PFMIN, // 3dNow! INST_PFMUL, // 3dNow! INST_PFNACC, // 3dNow! Extensions INST_PFPNACC, // 3dNow! Extensions INST_PFRCP, // 3dNow! INST_PFRCPIT1, // 3dNow! INST_PFRCPIT2, // 3dNow! INST_PFRSQIT1, // 3dNow! INST_PFRSQRT, // 3dNow! INST_PFSUB, // 3dNow! INST_PFSUBR, // 3dNow! INST_PHADDD, INST_PHADDSW, INST_PHADDW, INST_PHMINPOSUW, INST_PHSUBD, INST_PHSUBSW, INST_PHSUBW, INST_PI2FD, // 3dNow! INST_PI2FW, // 3dNow! Extensions INST_PINSRB, INST_PINSRD, INST_PINSRQ, INST_PINSRW, // MMX Extensions INST_PMADDUBSW, INST_PMADDWD, INST_PMAXSB, INST_PMAXSD, INST_PMAXSW, // MMX Extensions INST_PMAXUB, // MMX Extensions INST_PMAXUD, INST_PMAXUW, INST_PMINSB, INST_PMINSD, INST_PMINSW, // MMX Extensions INST_PMINUB, // MMX Extensions INST_PMINUD, INST_PMINUW, INST_PMOVMSKB, // MMX Extensions INST_PMOVSXBD, INST_PMOVSXBQ, INST_PMOVSXBW, INST_PMOVSXDQ, INST_PMOVSXWD, INST_PMOVSXWQ, INST_PMOVZXBD, INST_PMOVZXBQ, INST_PMOVZXBW, INST_PMOVZXDQ, INST_PMOVZXWD, INST_PMOVZXWQ, INST_PMULDQ, INST_PMULHRSW, INST_PMULHUW, // MMX Extensions INST_PMULHW, INST_PMULLD, INST_PMULLW, INST_PMULUDQ, INST_POP, // X86/X64 INST_POPAD, // X86 only INST_POPCNT, INST_POPFD, // X86 only INST_POPFQ, // X64 only INST_POR, INST_PREFETCH, // MMX Extensions INST_PSADBW, // MMX Extensions INST_PSHUFB, INST_PSHUFD, INST_PSHUFW, // MMX Extensions INST_PSHUFHW, INST_PSHUFLW, INST_PSIGNB, INST_PSIGND, INST_PSIGNW, INST_PSLLD, INST_PSLLDQ, INST_PSLLQ, INST_PSLLW, INST_PSRAD, INST_PSRAW, INST_PSRLD, INST_PSRLDQ, INST_PSRLQ, INST_PSRLW, INST_PSUBB, INST_PSUBD, INST_PSUBQ, INST_PSUBSB, INST_PSUBSW, INST_PSUBUSB, INST_PSUBUSW, INST_PSUBW, INST_PSWAPD, // 3dNow! Extensions INST_PTEST, INST_PUNPCKHBW, INST_PUNPCKHDQ, INST_PUNPCKHQDQ, INST_PUNPCKHWD, INST_PUNPCKLBW, INST_PUNPCKLDQ, INST_PUNPCKLQDQ, INST_PUNPCKLWD, INST_PUSH, // X86/X64 INST_PUSHAD, // X86 only INST_PUSHFD, // X86 only INST_PUSHFQ, // X64 only INST_PXOR, INST_RCL, // X86/X64 INST_RCPPS, INST_RCPSS, INST_RCR, // X86/X64 INST_RDTSC, // X86/X64 INST_RDTSCP, // X86/X64 INST_REP_LODSB, // X86/X64 (REP) INST_REP_LODSD, // X86/X64 (REP) INST_REP_LODSQ, // X64 only (REP) INST_REP_LODSW, // X86/X64 (REP) INST_REP_MOVSB, // X86/X64 (REP) INST_REP_MOVSD, // X86/X64 (REP) INST_REP_MOVSQ, // X64 only (REP) INST_REP_MOVSW, // X86/X64 (REP) INST_REP_STOSB, // X86/X64 (REP) INST_REP_STOSD, // X86/X64 (REP) INST_REP_STOSQ, // X64 only (REP) INST_REP_STOSW, // X86/X64 (REP) INST_REPE_CMPSB, // X86/X64 (REP) INST_REPE_CMPSD, // X86/X64 (REP) INST_REPE_CMPSQ, // X64 only (REP) INST_REPE_CMPSW, // X86/X64 (REP) INST_REPE_SCASB, // X86/X64 (REP) INST_REPE_SCASD, // X86/X64 (REP) INST_REPE_SCASQ, // X64 only (REP) INST_REPE_SCASW, // X86/X64 (REP) INST_REPNE_CMPSB, // X86/X64 (REP) INST_REPNE_CMPSD, // X86/X64 (REP) INST_REPNE_CMPSQ, // X64 only (REP) INST_REPNE_CMPSW, // X86/X64 (REP) INST_REPNE_SCASB, // X86/X64 (REP) INST_REPNE_SCASD, // X86/X64 (REP) INST_REPNE_SCASQ, // X64 only (REP) INST_REPNE_SCASW, // X86/X64 (REP) INST_RET, // X86/X64 INST_ROL, // X86/X64 INST_ROR, // X86/X64 INST_ROUNDPD, INST_ROUNDPS, INST_ROUNDSD, INST_ROUNDSS, INST_RSQRTPS, INST_RSQRTSS, INST_SAHF, // X86/X64 (CPUID NEEDED) INST_SAL, // X86/X64 INST_SAR, // X86/X64 INST_SBB, // X86/X64 INST_SET, // Begin (setcc) INST_SETA=INST_SET, // X86/X64 (setcc) INST_SETAE, // X86/X64 (setcc) INST_SETB, // X86/X64 (setcc) INST_SETBE, // X86/X64 (setcc) INST_SETC, // X86/X64 (setcc) INST_SETE, // X86/X64 (setcc) INST_SETG, // X86/X64 (setcc) INST_SETGE, // X86/X64 (setcc) INST_SETL, // X86/X64 (setcc) INST_SETLE, // X86/X64 (setcc) INST_SETNA, // X86/X64 (setcc) INST_SETNAE, // X86/X64 (setcc) INST_SETNB, // X86/X64 (setcc) INST_SETNBE, // X86/X64 (setcc) INST_SETNC, // X86/X64 (setcc) INST_SETNE, // X86/X64 (setcc) INST_SETNG, // X86/X64 (setcc) INST_SETNGE, // X86/X64 (setcc) INST_SETNL, // X86/X64 (setcc) INST_SETNLE, // X86/X64 (setcc) INST_SETNO, // X86/X64 (setcc) INST_SETNP, // X86/X64 (setcc) INST_SETNS, // X86/X64 (setcc) INST_SETNZ, // X86/X64 (setcc) INST_SETO, // X86/X64 (setcc) INST_SETP, // X86/X64 (setcc) INST_SETPE, // X86/X64 (setcc) INST_SETPO, // X86/X64 (setcc) INST_SETS, // X86/X64 (setcc) INST_SETZ, // X86/X64 (setcc) INST_SFENCE, // MMX Extensions INST_SHL, // X86/X64 INST_SHLD, // X86/X64 INST_SHR, // X86/X64 INST_SHRD, // X86/X64 INST_SHUFPD, INST_SHUFPS, INST_SQRTPD, INST_SQRTPS, INST_SQRTSD, INST_SQRTSS, INST_STC, // X86/X64 INST_STD, // X86/X64 INST_STMXCSR, INST_SUB, // X86/X64 INST_SUBPD, INST_SUBPS, INST_SUBSD, INST_SUBSS, INST_TEST, // X86/X64 INST_UCOMISD, INST_UCOMISS, INST_UD2, // X86/X64 INST_UNPCKHPD, INST_UNPCKHPS, INST_UNPCKLPD, INST_UNPCKLPS, INST_XADD, // X86/X64 (i486) INST_XCHG, // X86/X64 (i386) INST_XOR, // X86/X64 INST_XORPD, INST_XORPS, _INST_COUNT, _INST_J_BEGIN = INST_J, _INST_J_END = INST_JMP }; // ============================================================================ // [AsmJit::Instruction Name] // ============================================================================ //! @internal //! //! @brief Instruction names. ASMJIT_API extern const char instructionName[]; // ============================================================================ // [AsmJit::Instruction Description] // ============================================================================ struct InstructionDescription { // -------------------------------------------------------------------------- // [Instruction Groups] // -------------------------------------------------------------------------- //! @brief Instruction groups. //! //! This should be only used by assembler, because it's @c AsmJit::Assembler //! specific grouping. Each group represents one 'case' in the Assembler's //! main emit method. enum G { // Gloup categories. G_EMIT, G_ALU, G_BSWAP, G_BT, G_CALL, G_CRC32, G_ENTER, G_IMUL, G_INC_DEC, G_J, G_JMP, G_LEA, G_M, G_MOV, G_MOV_PTR, G_MOVSX_MOVZX, G_MOVSXD, G_PUSH, // I_PUSH is implemented before I_POP G_POP, G_R_RM, G_RM_B, G_RM, G_RM_R, G_REP, G_RET, G_ROT, G_SHLD_SHRD, G_TEST, G_XCHG, // Group for x87 FP instructions in format mem or st(i), st(i) (fadd, fsub, fdiv, ...) G_X87_FPU, // Group for x87 FP instructions in format st(i), st(i) G_X87_STI, // Group for fld/fst/fstp instruction, internally uses I_X87_MEM group. G_X87_MEM_STI, // Group for x87 FP instructions that uses Word, DWord, QWord or TWord memory pointer. G_X87_MEM, // Group for x87 FSTSW/FNSTSW instructions G_X87_FSTSW, // Group for movbe instruction G_MOVBE, // Group for MMX/SSE instructions in format (X)MM|Reg|Mem <- (X)MM|Reg|Mem, // 0x66 prefix must be set manually in opcodes. // - Primary opcode is used for instructions in (X)MM <- (X)MM/Mem format, // - Secondary opcode is used for instructions in (X)MM/Mem <- (X)MM format. G_MMU_MOV, // Group for movd and movq instructions. G_MMU_MOVD, G_MMU_MOVQ, // Group for pextrd, pextrq and pextrw instructions (it's special instruction // not similar to others) G_MMU_PEXTR, // Group for prefetch instruction G_MMU_PREFETCH, // Group for MMX/SSE instructions in format (X)MM|Reg <- (X)MM|Reg|Mem|Imm, // 0x66 prefix is added for MMX instructions that used by SSE2 registers. // - Primary opcode is used for instructions in (X)MM|Reg <- (X)MM|Reg|Mem format, // - Secondary opcode is iused for instructions in (X)MM|Reg <- Imm format. G_MMU_RMI, G_MMU_RM_IMM8, // Group for 3dNow instructions G_MMU_RM_3DNOW }; // -------------------------------------------------------------------------- // [Instruction Core Flags] // -------------------------------------------------------------------------- //! @brief Instruction core flags. enum F { //! @brief No flags. F_NONE = 0x00, //! @brief Instruction is jump, conditional jump, call or ret. F_JUMP = 0x01, //! @brief Instruction will overwrite first operand - o[0]. F_MOV = 0x02, //! @brief Instruction is X87 FPU. F_FPU = 0x04, //! @brief Instruction can be prepended using LOCK prefix //! (usable for multithreaded applications). F_LOCKABLE = 0x08, //! @brief Instruction is special, this is for @c Compiler. F_SPECIAL = 0x10, //! @brief Instruction always performs memory access. //! //! This flag is always combined with @c F_SPECIAL and signalizes that //! there is implicit address which is accessed (usually EDI/RDI or ESI/EDI). F_SPECIAL_MEM = 0x20 }; // -------------------------------------------------------------------------- // [Instruction Operand Flags] // -------------------------------------------------------------------------- //! @brief Instruction operand flags. enum O { // X86, MM, XMM O_GB = 0x0001, O_GW = 0x0002, O_GD = 0x0004, O_GQ = 0x0008, O_MM = 0x0010, O_XMM = 0x0020, O_MEM = 0x0040, O_IMM = 0x0080, O_GB_MEM = O_GB | O_MEM, O_GW_MEM = O_GW | O_MEM, O_GD_MEM = O_GD | O_MEM, O_GQ_MEM = O_GQ | O_MEM, O_GQDWB = O_GQ | O_GD | O_GW | O_GB, O_GQDW = O_GQ | O_GD | O_GW, O_GQD = O_GQ | O_GD, O_GWB = O_GW | O_GB, O_GQDWB_MEM = O_GQDWB | O_MEM, O_GQDW_MEM = O_GQDW | O_MEM, O_GQD_MEM = O_GQD | O_MEM, O_GWB_MEM = O_GWB | O_MEM, O_MM_MEM = O_MM | O_MEM, O_XMM_MEM = O_XMM | O_MEM, O_MM_XMM = O_MM | O_XMM, O_MM_XMM_MEM = O_MM | O_XMM | O_MEM, // X87 O_FM_2 = O_MEM | 0x0100, O_FM_4 = O_MEM | 0x0200, O_FM_8 = O_MEM | 0x0400, O_FM_10 = O_MEM | 0x0800, O_FM_2_4 = O_FM_2 | O_FM_4, O_FM_2_4_8 = O_FM_2 | O_FM_4 | O_FM_8, O_FM_4_8 = O_FM_4 | O_FM_8, O_FM_4_8_10 = O_FM_4 | O_FM_8 | O_FM_10, // Don't emit REX prefix. O_NOREX = 0x2000 }; // -------------------------------------------------------------------------- // [Members] // -------------------------------------------------------------------------- //! @brief Instruction code. uint16_t code; //! @brief Instruction name index in instructionName[] array. uint16_t nameIndex; //! @brief Instruction group, used also by @c Compiler. uint8_t group; //! @brief Instruction type flags. uint8_t flags; //! @brief First and second operand flags (some groups depends to these settings, used also by @c Compiler). uint16_t oflags[2]; //! @brief If instruction has only memory operand, this is register opcode. uint16_t opCodeR; //! @brief Primary and secondary opcodes. uint32_t opCode[2]; //! @brief Get the instruction name (null terminated string). inline const char* getName() const { return instructionName + nameIndex; } //! @brief Get whether the instruction is conditional or standard jump. inline bool isJump() const { return (flags & F_JUMP) != 0; } //! @brief Get whether the instruction is MOV type. inline bool isMov() const { return (flags & F_MOV) != 0; } //! @brief Get whether the instruction is X87 FPU type. inline bool isFPU() const { return (flags & F_FPU) != 0; } //! @brief Get whether the instruction can be prefixed by LOCK prefix. inline bool isLockable() const { return (flags & F_LOCKABLE) != 0; } //! @brief Get whether the instruction is special type (this is used by //! @c Compiler to manage additional variables or functionality). inline bool isSpecial() const { return (flags & F_SPECIAL) != 0; } //! @brief Get whether the instruction is special type and it performs //! memory access. inline bool isSpecialMem() const { return (flags & F_SPECIAL_MEM) != 0; } }; ASMJIT_API extern const InstructionDescription instructionDescription[]; // ============================================================================ // [AsmJit::EMIT_OPTIONS] // ============================================================================ //! @brief Emit options, mainly for internal purposes. enum EMIT_OPTIONS { //! @brief Force REX prefix to be emitted. //! //! This option should be used carefully, because there are unencodable //! combinations. If you want to access ah, bh, ch or dh registers then you //! can't emit REX prefix and it will cause an illegal instruction error. EMIT_OPTION_REX_PREFIX = (1 << 0), //! @brief Tell @c Assembler or @c Compiler to emit and validate lock prefix. //! //! If this option is used and instruction doesn't support LOCK prefix then //! invalid instruction error is generated. EMIT_OPTION_LOCK_PREFIX = (1 << 1), //! @brief Emit short/near jump or conditional jump instead of far one, //! saving some bytes. EMIT_OPTION_SHORT_JUMP = (1 << 2) }; // ============================================================================ // [AsmJit::CALL_CONV] // ============================================================================ //! @brief Calling convention type. //! //! Calling convention is scheme how function arguments are passed into //! function and how functions returns values. In assembler programming //! it's needed to always comply with function calling conventions, because //! even small inconsistency can cause undefined behavior or crash. //! //! List of calling conventions for 32-bit x86 mode: //! - @c CALL_CONV_CDECL - Calling convention for C runtime. //! - @c CALL_CONV_STDCALL - Calling convention for WinAPI functions. //! - @c CALL_CONV_MSTHISCALL - Calling convention for C++ members under //! Windows (produced by MSVC and all MSVC compatible compilers). //! - @c CALL_CONV_MSFASTCALL - Fastest calling convention that can be used //! by MSVC compiler. //! - @c CALL_CONV_BORNANDFASTCALL - Borland fastcall convention. //! - @c CALL_CONV_GCCFASTCALL - GCC fastcall convention (2 register arguments). //! - @c CALL_CONV_GCCREGPARM_1 - GCC regparm(1) convention. //! - @c CALL_CONV_GCCREGPARM_2 - GCC regparm(2) convention. //! - @c CALL_CONV_GCCREGPARM_3 - GCC regparm(3) convention. //! //! List of calling conventions for 64-bit x86 mode (x64): //! - @c CALL_CONV_X64W - Windows 64-bit calling convention (WIN64 ABI). //! - @c CALL_CONV_X64U - Unix 64-bit calling convention (AMD64 ABI). //! //! There is also @c CALL_CONV_DEFAULT that is defined to fit best to your //! compiler. //! //! These types are used together with @c AsmJit::Compiler::newFunction() //! method. enum CALL_CONV { //! @brief Calling convention is invalid (can't be used). CALL_CONV_NONE = 0, // [X64 Calling Conventions] //! @brief X64 calling convention for Windows platform (WIN64 ABI). //! //! For first four arguments are used these registers: //! - 1. 32/64-bit integer or floating point argument - rcx/xmm0 //! - 2. 32/64-bit integer or floating point argument - rdx/xmm1 //! - 3. 32/64-bit integer or floating point argument - r8/xmm2 //! - 4. 32/64-bit integer or floating point argument - r9/xmm3 //! //! Note first four arguments here means arguments at positions from 1 to 4 //! (included). For example if second argument is not passed by register then //! rdx/xmm1 register is unused. //! //! All other arguments are pushed on the stack in right-to-left direction. //! Stack is aligned by 16 bytes. There is 32-byte shadow space on the stack //! that can be used to save up to four 64-bit registers (probably designed to //! be used to save first four arguments passed in registers). //! //! Arguments direction: //! - Right to Left (except for first 4 parameters that's in registers) //! //! Stack is cleaned by: //! - Caller. //! //! Return value: //! - Integer types - RAX register. //! - Floating points - XMM0 register. //! //! Stack is always aligned by 16 bytes. //! //! More information about this calling convention can be found on MSDN: //! http://msdn.microsoft.com/en-us/library/9b372w95.aspx . CALL_CONV_X64W = 1, //! @brief X64 calling convention for Unix platforms (AMD64 ABI). //! //! First six 32 or 64-bit integer arguments are passed in rdi, rsi, rdx, //! rcx, r8, r9 registers. First eight floating point or XMM arguments //! are passed in xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 registers. //! This means that in registers can be transferred up to 14 arguments total. //! //! There is also RED ZONE below the stack pointer that can be used for //! temporary storage. The red zone is the space from [rsp-128] to [rsp-8]. //! //! Arguments direction: //! - Right to Left (Except for arguments passed in registers). //! //! Stack is cleaned by: //! - Caller. //! //! Return value: //! - Integer types - RAX register. //! - Floating points - XMM0 register. //! //! Stack is always aligned by 16 bytes. CALL_CONV_X64U = 2, // [X86 Calling Conventions] //! @brief Cdecl calling convention (used by C runtime). //! //! Compatible across MSVC and GCC. //! //! Arguments direction: //! - Right to Left //! //! Stack is cleaned by: //! - Caller. CALL_CONV_CDECL = 3, //! @brief Stdcall calling convention (used by WinAPI). //! //! Compatible across MSVC and GCC. //! //! Arguments direction: //! - Right to Left //! //! Stack is cleaned by: //! - Callee. //! //! Return value: //! - Integer types - EAX:EDX registers. //! - Floating points - st(0) register. CALL_CONV_STDCALL = 4, //! @brief MSVC specific calling convention used by MSVC/Intel compilers //! for struct/class methods. //! //! This is MSVC (and Intel) only calling convention used in Windows //! world for C++ class methods. Implicit 'this' pointer is stored in //! ECX register instead of storing it on the stack. //! //! Arguments direction: //! - Right to Left (except this pointer in ECX) //! //! Stack is cleaned by: //! - Callee. //! //! Return value: //! - Integer types - EAX:EDX registers. //! - Floating points - st(0) register. //! //! C++ class methods that have variable count of arguments uses different //! calling convention called cdecl. //! //! @note This calling convention is always used by MSVC for class methods, //! it's implicit and there is no way how to override it. CALL_CONV_MSTHISCALL = 5, //! @brief MSVC specific fastcall. //! //! Two first parameters (evaluated from left-to-right) are in ECX:EDX //! registers, all others on the stack in right-to-left order. //! //! Arguments direction: //! - Right to Left (except to first two integer arguments in ECX:EDX) //! //! Stack is cleaned by: //! - Callee. //! //! Return value: //! - Integer types - EAX:EDX registers. //! - Floating points - st(0) register. //! //! @note This calling convention differs to GCC one in stack cleaning //! mechanism. CALL_CONV_MSFASTCALL = 6, //! @brief Borland specific fastcall with 2 parameters in registers. //! //! Two first parameters (evaluated from left-to-right) are in ECX:EDX //! registers, all others on the stack in left-to-right order. //! //! Arguments direction: //! - Left to Right (except to first two integer arguments in ECX:EDX) //! //! Stack is cleaned by: //! - Callee. //! //! Return value: //! - Integer types - EAX:EDX registers. //! - Floating points - st(0) register. //! //! @note Arguments on the stack are in left-to-right order that differs //! to other fastcall conventions used in different compilers. CALL_CONV_BORLANDFASTCALL = 7, //! @brief GCC specific fastcall convention. //! //! Two first parameters (evaluated from left-to-right) are in ECX:EDX //! registers, all others on the stack in right-to-left order. //! //! Arguments direction: //! - Right to Left (except to first two integer arguments in ECX:EDX) //! //! Stack is cleaned by: //! - Callee. //! //! Return value: //! - Integer types - EAX:EDX registers. //! - Floating points - st(0) register. //! //! @note This calling convention should be compatible to //! @c CALL_CONV_MSFASTCALL. CALL_CONV_GCCFASTCALL = 8, //! @brief GCC specific regparm(1) convention. //! //! The first parameter (evaluated from left-to-right) is in EAX register, //! all others on the stack in right-to-left order. //! //! Arguments direction: //! - Right to Left (except to first one integer argument in EAX) //! //! Stack is cleaned by: //! - Caller. //! //! Return value: //! - Integer types - EAX:EDX registers. //! - Floating points - st(0) register. CALL_CONV_GCCREGPARM_1 = 9, //! @brief GCC specific regparm(2) convention. //! //! Two first parameters (evaluated from left-to-right) are in EAX:EDX //! registers, all others on the stack in right-to-left order. //! //! Arguments direction: //! - Right to Left (except to first two integer arguments in EAX:EDX) //! //! Stack is cleaned by: //! - Caller. //! //! Return value: //! - Integer types - EAX:EDX registers. //! - Floating points - st(0) register. CALL_CONV_GCCREGPARM_2 = 10, //! @brief GCC specific fastcall with 3 parameters in registers. //! //! Three first parameters (evaluated from left-to-right) are in //! EAX:EDX:ECX registers, all others on the stack in right-to-left order. //! //! Arguments direction: //! - Right to Left (except to first three integer arguments in EAX:EDX:ECX) //! //! Stack is cleaned by: //! - Caller. //! //! Return value: //! - Integer types - EAX:EDX registers. //! - Floating points - st(0) register. CALL_CONV_GCCREGPARM_3 = 11, // [Preferred Calling Convention] //! @def CALL_CONV_DEFAULT //! @brief Default calling convention for current platform / operating system. #if defined(ASMJIT_X86) CALL_CONV_DEFAULT = CALL_CONV_CDECL, # if defined(_MSC_VER) CALL_CONV_COMPAT_FASTCALL = CALL_CONV_MSFASTCALL, # elif defined(__GNUC__) CALL_CONV_COMPAT_FASTCALL = CALL_CONV_GCCFASTCALL, # elif defined(__BORLANDC__) CALL_CONV_COMPAT_FASTCALL = CALL_CONV_BORLANDFASTCALL, # else # error "AsmJit::CALL_CONV_COMPATIBLE_FASTCALL_2 - Unsupported." # endif CALL_CONV_COMPAT_STDCALL = CALL_CONV_STDCALL, CALL_CONV_COMPAT_CDECL = CALL_CONV_CDECL #else # if defined(ASMJIT_WINDOWS) CALL_CONV_DEFAULT = CALL_CONV_X64W, # else CALL_CONV_DEFAULT = CALL_CONV_X64U, # endif CALL_CONV_COMPAT_FASTCALL = CALL_CONV_DEFAULT, CALL_CONV_COMPAT_STDCALL = CALL_CONV_DEFAULT, CALL_CONV_COMPAT_CDECL = CALL_CONV_DEFAULT #endif // ASMJIT_X86 }; // ============================================================================ // [AsmJit::VARIABLE_TYPE] // ============================================================================ //! @brief Variable type. enum VARIABLE_TYPE { // -------------------------------------------------------------------------- // [Platform Dependent] // -------------------------------------------------------------------------- //! @brief Variable is 32-bit general purpose register. VARIABLE_TYPE_GPD = 0, //! @brief Variable is 64-bit general purpose register. VARIABLE_TYPE_GPQ = 1, //! @var VARIABLE_TYPE_GPN //! @brief Variable is system wide general purpose register (32-bit or 64-bit). #if defined(ASMJIT_X86) VARIABLE_TYPE_GPN = VARIABLE_TYPE_GPD, #else VARIABLE_TYPE_GPN = VARIABLE_TYPE_GPQ, #endif //! @brief Variable is X87 (FPU). VARIABLE_TYPE_X87 = 2, //! @brief Variable is X87 (FPU) SP-FP number (float). VARIABLE_TYPE_X87_1F = 3, //! @brief Variable is X87 (FPU) DP-FP number (double). VARIABLE_TYPE_X87_1D = 4, //! @brief Variable is MM register / memory location. VARIABLE_TYPE_MM = 5, //! @brief Variable is XMM register / memory location. VARIABLE_TYPE_XMM = 6, //! @brief Variable is SSE scalar SP-FP number. VARIABLE_TYPE_XMM_1F = 7, //! @brief Variable is SSE packed SP-FP number (4 floats). VARIABLE_TYPE_XMM_4F = 8, //! @brief Variable is SSE2 scalar DP-FP number. VARIABLE_TYPE_XMM_1D = 9, //! @brief Variable is SSE2 packed DP-FP number (2 doubles). VARIABLE_TYPE_XMM_2D = 10, //! @brief Count of variable types. _VARIABLE_TYPE_COUNT = 11, // -------------------------------------------------------------------------- // [Platform Independent] // -------------------------------------------------------------------------- //! @brief Variable is 32-bit integer. VARIABLE_TYPE_INT32 = VARIABLE_TYPE_GPD, //! @brief Variable is 64-bit integer. VARIABLE_TYPE_INT64 = VARIABLE_TYPE_GPQ, //! @brief Variable is system dependent integer / pointer. VARIABLE_TYPE_INTPTR = VARIABLE_TYPE_GPN, #if !defined(ASMJIT_NODOC) #if defined(ASMJIT_X86) VARIABLE_TYPE_FLOAT = VARIABLE_TYPE_X87_1F, VARIABLE_TYPE_DOUBLE = VARIABLE_TYPE_X87_1D #else VARIABLE_TYPE_FLOAT = VARIABLE_TYPE_XMM_1F, VARIABLE_TYPE_DOUBLE = VARIABLE_TYPE_XMM_1D #endif #else //! @brief Variable is SP-FP (x87 or xmm). VARIABLE_TYPE_FLOAT = XXX, //! @brief Variable is DP-FP (x87 or xmm). VARIABLE_TYPE_DOUBLE = XXX #endif }; // ============================================================================ // [AsmJit::VARIABLE_HINT] // ============================================================================ //! @brief Variable hint (used by @ref Compiler). //! //! @sa @ref Compiler. enum VARIABLE_HINT { //! @brief Alloc variable. VARIABLE_HINT_ALLOC = 0, //! @brief Spill variable. VARIABLE_HINT_SPILL = 1, //! @brief Save variable if modified. VARIABLE_HINT_SAVE = 2, //! @brief Save variable if modified and mark it as unused. VARIABLE_HINT_SAVE_AND_UNUSE = 3, //! @brief Mark variable as unused. VARIABLE_HINT_UNUSE = 4 }; //! @} } // AsmJit namespace // [Api-End] #include "ApiEnd.h" // [Guard] #endif // _ASMJIT_DEFSX86X64_H