"vscode:/vscode.git/clone" did not exist on "69abec48cd54a4896787bb664fc9390368b08634"
Commit 01da1b51 authored by peastman's avatar peastman
Browse files

Updated to latest asmjit, which supports 32 bit mode

parent 26790496
...@@ -26,11 +26,11 @@ namespace asmjit { ...@@ -26,11 +26,11 @@ namespace asmjit {
//! \{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::kLoggerOption] // [asmjit::LoggerOption]
// ============================================================================ // ============================================================================
//! Logger options. //! Logger options.
ASMJIT_ENUM(kLoggerOption) { ASMJIT_ENUM(LoggerOption) {
//! Whether to output instructions also in binary form. //! Whether to output instructions also in binary form.
kLoggerOptionBinaryForm = 0, kLoggerOptionBinaryForm = 0,
...@@ -44,11 +44,11 @@ ASMJIT_ENUM(kLoggerOption) { ...@@ -44,11 +44,11 @@ ASMJIT_ENUM(kLoggerOption) {
}; };
// ============================================================================ // ============================================================================
// [asmjit::kLoggerStyle] // [asmjit::LoggerStyle]
// ============================================================================ // ============================================================================
//! Logger style. //! Logger style.
ASMJIT_ENUM(kLoggerStyle) { ASMJIT_ENUM(LoggerStyle) {
kLoggerStyleDefault = 0, kLoggerStyleDefault = 0,
kLoggerStyleDirective = 1, kLoggerStyleDirective = 1,
kLoggerStyleLabel = 2, kLoggerStyleLabel = 2,
...@@ -133,7 +133,7 @@ struct ASMJIT_VCLASS Logger { ...@@ -133,7 +133,7 @@ struct ASMJIT_VCLASS Logger {
// [Members] // [Members]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Options, see `kLoggerOption`. //! Options, see \ref LoggerOption.
uint32_t _options; uint32_t _options;
//! Indentation. //! Indentation.
...@@ -165,11 +165,15 @@ struct ASMJIT_VCLASS FileLogger : public Logger { ...@@ -165,11 +165,15 @@ struct ASMJIT_VCLASS FileLogger : public Logger {
//! Get `FILE*` stream. //! Get `FILE*` stream.
//! //!
//! \note Return value can be `NULL`. //! \note Return value can be `NULL`.
ASMJIT_INLINE FILE* getStream() const { return _stream; } ASMJIT_INLINE FILE* getStream() const {
return _stream;
}
//! Set `FILE*` stream, can be set to `NULL` to disable logging, although //! Set `FILE*` stream, can be set to `NULL` to disable logging, although
//! the `CodeGen` will still call `logString` even if there is no stream. //! the `CodeGen` will still call `logString` even if there is no stream.
ASMJIT_API void setStream(FILE* stream); ASMJIT_INLINE void setStream(FILE* stream) {
_stream = stream;
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Logging] // [Logging]
...@@ -207,8 +211,7 @@ struct ASMJIT_VCLASS StringLogger : public Logger { ...@@ -207,8 +211,7 @@ struct ASMJIT_VCLASS StringLogger : public Logger {
// [Accessors] // [Accessors]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Get <code>char*</code> pointer which represents the resulting //! Get `char*` pointer which represents the resulting string.
//! string.
//! //!
//! The pointer is owned by `StringLogger`, it can't be modified or freed. //! The pointer is owned by `StringLogger`, it can't be modified or freed.
ASMJIT_INLINE const char* getString() const { ASMJIT_INLINE const char* getString() const {
......
...@@ -27,11 +27,11 @@ struct Compiler; ...@@ -27,11 +27,11 @@ struct Compiler;
//! \{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::kOperandType] // [asmjit::OperandType]
// ============================================================================ // ============================================================================
//! Operand types that can be encoded in `Operand`. //! Operand types that can be encoded in `Operand`.
ASMJIT_ENUM(kOperandType) { ASMJIT_ENUM(OperandType) {
//! Invalid operand, used only internally (not initialized Operand). //! Invalid operand, used only internally (not initialized Operand).
kOperandTypeNone = 0, kOperandTypeNone = 0,
//! Operand is a register. //! Operand is a register.
...@@ -47,11 +47,11 @@ ASMJIT_ENUM(kOperandType) { ...@@ -47,11 +47,11 @@ ASMJIT_ENUM(kOperandType) {
}; };
// ============================================================================ // ============================================================================
// [asmjit::kOperandId] // [asmjit::OperandId]
// ============================================================================ // ============================================================================
//! Operand id masks used to determine the operand type. //! Operand id masks used to determine the operand type.
ASMJIT_ENUM(kOperandId) { ASMJIT_ENUM(OperandId) {
//! Operand id refers to `Var`. //! Operand id refers to `Var`.
kOperandIdVar = 0x80000000U, kOperandIdVar = 0x80000000U,
//! Operand id to real index mask. //! Operand id to real index mask.
...@@ -59,21 +59,21 @@ ASMJIT_ENUM(kOperandId) { ...@@ -59,21 +59,21 @@ ASMJIT_ENUM(kOperandId) {
}; };
// ============================================================================ // ============================================================================
// [asmjit::kRegClass] // [asmjit::RegClass]
// ============================================================================ // ============================================================================
//! Register class. //! Register class.
ASMJIT_ENUM(kRegClass) { ASMJIT_ENUM(RegClass) {
//! Gp register class, compatible with all architectures. //! Gp register class, compatible with all architectures.
kRegClassGp = 0 kRegClassGp = 0
}; };
// ============================================================================ // ============================================================================
// [asmjit::kSize] // [asmjit::SizeDefs]
// ============================================================================ // ============================================================================
//! Common size of registers and pointers. //! Common size of registers and pointers.
ASMJIT_ENUM(kSize) { ASMJIT_ENUM(SizeDefs) {
//! 1 byte size (BYTE). //! 1 byte size (BYTE).
kSizeByte = 1, kSizeByte = 1,
//! 2 bytes size (WORD). //! 2 bytes size (WORD).
...@@ -91,11 +91,11 @@ ASMJIT_ENUM(kSize) { ...@@ -91,11 +91,11 @@ ASMJIT_ENUM(kSize) {
}; };
// ============================================================================ // ============================================================================
// [asmjit::kMemType] // [asmjit::MemType]
// ============================================================================ // ============================================================================
//! Type of memory operand. //! Type of memory operand.
ASMJIT_ENUM(kMemType) { ASMJIT_ENUM(MemType) {
//! Memory operand is a combination of base register and optional index register //! Memory operand is a combination of base register and optional index register
//! and displacement. //! and displacement.
//! //!
...@@ -135,7 +135,7 @@ struct Operand { ...@@ -135,7 +135,7 @@ struct Operand {
//! //!
//! Base operand data. //! Base operand data.
struct BaseOp { struct BaseOp {
//! Type of operand, see `kOperandType`. //! Type of operand, see \ref OperandType.
uint8_t op; uint8_t op;
//! Size of operand (register, address, immediate, or variable). //! Size of operand (register, address, immediate, or variable).
uint8_t size; uint8_t size;
...@@ -170,7 +170,7 @@ struct Operand { ...@@ -170,7 +170,7 @@ struct Operand {
//! Register type and index access. //! Register type and index access.
struct { struct {
#if defined(ASMJIT_HOST_LE) #if defined(ASMJIT_ARCH_LE)
//! Register index. //! Register index.
uint8_t index; uint8_t index;
//! Register type. //! Register type.
...@@ -180,7 +180,7 @@ struct Operand { ...@@ -180,7 +180,7 @@ struct Operand {
uint8_t type; uint8_t type;
//! Register index. //! Register index.
uint8_t index; uint8_t index;
#endif // ASMJIT_HOST #endif
}; };
}; };
...@@ -212,10 +212,10 @@ struct Operand { ...@@ -212,10 +212,10 @@ struct Operand {
uint8_t op; uint8_t op;
//! Size of the pointer in bytes. //! Size of the pointer in bytes.
uint8_t size; uint8_t size;
//! Type of the memory operand, see `kMemType`. //! Type of the memory operand, see `MemType`.
uint8_t type; uint8_t type;
//! X86/X64 layout: //! X86/X64 layout:
//! - segment [3 bits], see `kX86Seg`. //! - segment [3 bits], see `X86Seg`.
//! - shift [2 bits], index register shift (0 to 3). //! - shift [2 bits], index register shift (0 to 3).
uint8_t flags; uint8_t flags;
...@@ -378,7 +378,7 @@ struct Operand { ...@@ -378,7 +378,7 @@ struct Operand {
// [Type] // [Type]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Get type of the operand, see `kOperandType`. //! Get type of the operand, see \ref OperandType.
ASMJIT_INLINE uint32_t getOp() const { return _base.op; } ASMJIT_INLINE uint32_t getOp() const { return _base.op; }
//! Get whether the operand is none - `kOperandTypeNone`. //! Get whether the operand is none - `kOperandTypeNone`.
...@@ -659,7 +659,7 @@ struct BaseMem : public Operand { ...@@ -659,7 +659,7 @@ struct BaseMem : public Operand {
_init_packed_d2_d3(kInvalidValue, 0); _init_packed_d2_d3(kInvalidValue, 0);
} }
//! Get the type of the memory operand, see `kMemType`. //! Get the type of the memory operand, see `MemType`.
ASMJIT_INLINE uint32_t getMemType() const { ASMJIT_INLINE uint32_t getMemType() const {
return _vmem.type; return _vmem.type;
} }
...@@ -774,17 +774,17 @@ struct Imm : public Operand { ...@@ -774,17 +774,17 @@ struct Imm : public Operand {
ASMJIT_INLINE bool isUInt32() const { return IntUtil::isUInt32(_imm.value._i64[0]); } ASMJIT_INLINE bool isUInt32() const { return IntUtil::isUInt32(_imm.value._i64[0]); }
//! Get immediate value as 8-bit signed integer. //! Get immediate value as 8-bit signed integer.
ASMJIT_INLINE int8_t getInt8() const { return _imm.value._i8[_ASMJIT_HOST_INDEX(8, 0)]; } ASMJIT_INLINE int8_t getInt8() const { return _imm.value._i8[_ASMJIT_ARCH_INDEX(8, 0)]; }
//! Get immediate value as 8-bit unsigned integer. //! Get immediate value as 8-bit unsigned integer.
ASMJIT_INLINE uint8_t getUInt8() const { return _imm.value._u8[_ASMJIT_HOST_INDEX(8, 0)]; } ASMJIT_INLINE uint8_t getUInt8() const { return _imm.value._u8[_ASMJIT_ARCH_INDEX(8, 0)]; }
//! Get immediate value as 16-bit signed integer. //! Get immediate value as 16-bit signed integer.
ASMJIT_INLINE int16_t getInt16() const { return _imm.value._i16[_ASMJIT_HOST_INDEX(4, 0)]; } ASMJIT_INLINE int16_t getInt16() const { return _imm.value._i16[_ASMJIT_ARCH_INDEX(4, 0)]; }
//! Get immediate value as 16-bit unsigned integer. //! Get immediate value as 16-bit unsigned integer.
ASMJIT_INLINE uint16_t getUInt16() const { return _imm.value._u16[_ASMJIT_HOST_INDEX(4, 0)]; } ASMJIT_INLINE uint16_t getUInt16() const { return _imm.value._u16[_ASMJIT_ARCH_INDEX(4, 0)]; }
//! Get immediate value as 32-bit signed integer. //! Get immediate value as 32-bit signed integer.
ASMJIT_INLINE int32_t getInt32() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)]; } ASMJIT_INLINE int32_t getInt32() const { return _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 0)]; }
//! Get immediate value as 32-bit unsigned integer. //! Get immediate value as 32-bit unsigned integer.
ASMJIT_INLINE uint32_t getUInt32() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)]; } ASMJIT_INLINE uint32_t getUInt32() const { return _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)]; }
//! Get immediate value as 64-bit signed integer. //! Get immediate value as 64-bit signed integer.
ASMJIT_INLINE int64_t getInt64() const { return _imm.value._i64[0]; } ASMJIT_INLINE int64_t getInt64() const { return _imm.value._i64[0]; }
//! Get immediate value as 64-bit unsigned integer. //! Get immediate value as 64-bit unsigned integer.
...@@ -807,13 +807,13 @@ struct Imm : public Operand { ...@@ -807,13 +807,13 @@ struct Imm : public Operand {
} }
//! Get low 32-bit signed integer. //! Get low 32-bit signed integer.
ASMJIT_INLINE int32_t getInt32Lo() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)]; } ASMJIT_INLINE int32_t getInt32Lo() const { return _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 0)]; }
//! Get low 32-bit signed integer. //! Get low 32-bit signed integer.
ASMJIT_INLINE uint32_t getUInt32Lo() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)]; } ASMJIT_INLINE uint32_t getUInt32Lo() const { return _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)]; }
//! Get high 32-bit signed integer. //! Get high 32-bit signed integer.
ASMJIT_INLINE int32_t getInt32Hi() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)]; } ASMJIT_INLINE int32_t getInt32Hi() const { return _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 1)]; }
//! Get high 32-bit signed integer. //! Get high 32-bit signed integer.
ASMJIT_INLINE uint32_t getUInt32Hi() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)]; } ASMJIT_INLINE uint32_t getUInt32Hi() const { return _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)]; }
//! Set immediate value to 8-bit signed integer `val`. //! Set immediate value to 8-bit signed integer `val`.
ASMJIT_INLINE Imm& setInt8(int8_t val) { ASMJIT_INLINE Imm& setInt8(int8_t val) {
...@@ -822,8 +822,8 @@ struct Imm : public Operand { ...@@ -822,8 +822,8 @@ struct Imm : public Operand {
} }
else { else {
int32_t val32 = static_cast<int32_t>(val); int32_t val32 = static_cast<int32_t>(val);
_imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val32; _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 0)] = val32;
_imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val32 >> 31; _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 1)] = val32 >> 31;
} }
return *this; return *this;
} }
...@@ -834,8 +834,8 @@ struct Imm : public Operand { ...@@ -834,8 +834,8 @@ struct Imm : public Operand {
_imm.value._u64[0] = static_cast<uint64_t>(val); _imm.value._u64[0] = static_cast<uint64_t>(val);
} }
else { else {
_imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = static_cast<uint32_t>(val); _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)] = static_cast<uint32_t>(val);
_imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0;
} }
return *this; return *this;
} }
...@@ -847,8 +847,8 @@ struct Imm : public Operand { ...@@ -847,8 +847,8 @@ struct Imm : public Operand {
} }
else { else {
int32_t val32 = static_cast<int32_t>(val); int32_t val32 = static_cast<int32_t>(val);
_imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val32; _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 0)] = val32;
_imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val32 >> 31; _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 1)] = val32 >> 31;
} }
return *this; return *this;
} }
...@@ -859,8 +859,8 @@ struct Imm : public Operand { ...@@ -859,8 +859,8 @@ struct Imm : public Operand {
_imm.value._u64[0] = static_cast<uint64_t>(val); _imm.value._u64[0] = static_cast<uint64_t>(val);
} }
else { else {
_imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = static_cast<uint32_t>(val); _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)] = static_cast<uint32_t>(val);
_imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0;
} }
return *this; return *this;
} }
...@@ -871,8 +871,8 @@ struct Imm : public Operand { ...@@ -871,8 +871,8 @@ struct Imm : public Operand {
_imm.value._i64[0] = static_cast<int64_t>(val); _imm.value._i64[0] = static_cast<int64_t>(val);
} }
else { else {
_imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val; _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 0)] = val;
_imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val >> 31; _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 1)] = val >> 31;
} }
return *this; return *this;
} }
...@@ -883,8 +883,8 @@ struct Imm : public Operand { ...@@ -883,8 +883,8 @@ struct Imm : public Operand {
_imm.value._u64[0] = static_cast<uint64_t>(val); _imm.value._u64[0] = static_cast<uint64_t>(val);
} }
else { else {
_imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = val; _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)] = val;
_imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0;
} }
return *this; return *this;
} }
...@@ -921,8 +921,8 @@ struct Imm : public Operand { ...@@ -921,8 +921,8 @@ struct Imm : public Operand {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
ASMJIT_INLINE Imm& setFloat(float f) { ASMJIT_INLINE Imm& setFloat(float f) {
_imm.value._f32[_ASMJIT_HOST_INDEX(2, 0)] = f; _imm.value._f32[_ASMJIT_ARCH_INDEX(2, 0)] = f;
_imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0;
return *this; return *this;
} }
...@@ -940,8 +940,8 @@ struct Imm : public Operand { ...@@ -940,8 +940,8 @@ struct Imm : public Operand {
_imm.value._u64[0] &= static_cast<uint64_t>(0x000000FFU); _imm.value._u64[0] &= static_cast<uint64_t>(0x000000FFU);
} }
else { else {
_imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] &= 0x000000FFU; _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)] &= 0x000000FFU;
_imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0;
} }
return *this; return *this;
} }
...@@ -951,14 +951,14 @@ struct Imm : public Operand { ...@@ -951,14 +951,14 @@ struct Imm : public Operand {
_imm.value._u64[0] &= static_cast<uint64_t>(0x0000FFFFU); _imm.value._u64[0] &= static_cast<uint64_t>(0x0000FFFFU);
} }
else { else {
_imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] &= 0x0000FFFFU; _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)] &= 0x0000FFFFU;
_imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0;
} }
return *this; return *this;
} }
ASMJIT_INLINE Imm& truncateTo32Bits() { ASMJIT_INLINE Imm& truncateTo32Bits() {
_imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0;
return *this; return *this;
} }
......
...@@ -55,7 +55,7 @@ const CpuInfo* HostRuntime::getCpuInfo() { ...@@ -55,7 +55,7 @@ const CpuInfo* HostRuntime::getCpuInfo() {
uint32_t HostRuntime::getStackAlignment() { uint32_t HostRuntime::getStackAlignment() {
uint32_t alignment = sizeof(intptr_t); uint32_t alignment = sizeof(intptr_t);
#if defined(ASMJIT_HOST_X86) #if defined(ASMJIT_ARCH_X86)
// Modern Linux, APPLE and UNIX guarantees 16-byte stack alignment, but I'm // Modern Linux, APPLE and UNIX guarantees 16-byte stack alignment, but I'm
// not sure about all other UNIX operating systems, because 16-byte alignment // not sure about all other UNIX operating systems, because 16-byte alignment
// is addition to an older specification. // is addition to an older specification.
...@@ -69,7 +69,7 @@ uint32_t HostRuntime::getStackAlignment() { ...@@ -69,7 +69,7 @@ uint32_t HostRuntime::getStackAlignment() {
defined(__APPLE__) ) defined(__APPLE__) )
alignment = 16; alignment = 16;
# endif # endif
#elif defined(ASMJIT_HOST_X64) #elif defined(ASMJIT_ARCH_X64)
alignment = 16; alignment = 16;
#endif #endif
...@@ -78,14 +78,14 @@ uint32_t HostRuntime::getStackAlignment() { ...@@ -78,14 +78,14 @@ uint32_t HostRuntime::getStackAlignment() {
void HostRuntime::flush(void* p, size_t size) { void HostRuntime::flush(void* p, size_t size) {
// Only useful on non-x86 architectures. // Only useful on non-x86 architectures.
#if !defined(ASMJIT_HOST_X86) && !defined(ASMJIT_HOST_X64) #if !defined(ASMJIT_ARCH_X86) && !defined(ASMJIT_ARCH_X64)
// Windows has built-in support in kernel32.dll. // Windows has built-in support in kernel32.dll.
#if defined(ASMJIT_OS_WINDOWS) #if defined(ASMJIT_OS_WINDOWS)
::FlushInstructionCache(_memMgr.getProcessHandle(), p, size); ::FlushInstructionCache(_memMgr.getProcessHandle(), p, size);
#endif // ASMJIT_OS_WINDOWS #endif // ASMJIT_OS_WINDOWS
#endif // !ASMJIT_HOST_X86 && !ASMJIT_HOST_X64 #endif // !ASMJIT_ARCH_X86 && !ASMJIT_ARCH_X64
} }
// ============================================================================ // ============================================================================
......
...@@ -28,12 +28,11 @@ struct CpuInfo; ...@@ -28,12 +28,11 @@ struct CpuInfo;
//! \{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::kRuntimeType] // [asmjit::RuntimeType]
// ============================================================================ // ============================================================================
ASMJIT_ENUM(kRuntimeType) { ASMJIT_ENUM(RuntimeType) {
kRuntimeTypeNone = 0, kRuntimeTypeNone = 0,
kRuntimeTypeJit = 1, kRuntimeTypeJit = 1,
kRuntimeTypeRemote = 2 kRuntimeTypeRemote = 2
}; };
...@@ -90,7 +89,7 @@ struct ASMJIT_VCLASS Runtime { ...@@ -90,7 +89,7 @@ struct ASMJIT_VCLASS Runtime {
//! relocate it to the target location. //! relocate it to the target location.
//! //!
//! The beginning of the memory allocated for the function is returned in //! The beginning of the memory allocated for the function is returned in
//! `dst`. Returns Status code as \ref kError, on failure `dst` is set to //! `dst`. Returns Status code as \ref ErrorCode, on failure `dst` is set to
//! `NULL`. //! `NULL`.
virtual Error add(void** dst, Assembler* assembler) = 0; virtual Error add(void** dst, Assembler* assembler) = 0;
......
...@@ -23,13 +23,13 @@ namespace asmjit { ...@@ -23,13 +23,13 @@ namespace asmjit {
//! \{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::kStringOp] // [asmjit::StringOp]
// ============================================================================ // ============================================================================
//! \internal //! \internal
//! //!
//! String operation. //! String operation.
ASMJIT_ENUM(kStringOp) { ASMJIT_ENUM(StringOp) {
//! Replace the current string by a given content. //! Replace the current string by a given content.
kStringOpSet = 0, kStringOpSet = 0,
//! Append a given content to the current string. //! Append a given content to the current string.
...@@ -37,13 +37,13 @@ ASMJIT_ENUM(kStringOp) { ...@@ -37,13 +37,13 @@ ASMJIT_ENUM(kStringOp) {
}; };
// ============================================================================ // ============================================================================
// [asmjit::kStringFormat] // [asmjit::StringFormatFlags]
// ============================================================================ // ============================================================================
//! \internal //! \internal
//! //!
//! String format flags. //! String format flags.
ASMJIT_ENUM(kStringFormat) { ASMJIT_ENUM(StringFormatFlags) {
kStringFormatShowSign = 0x00000001, kStringFormatShowSign = 0x00000001,
kStringFormatShowSpace = 0x00000002, kStringFormatShowSpace = 0x00000002,
kStringFormatAlternate = 0x00000004, kStringFormatAlternate = 0x00000004,
......
...@@ -512,7 +512,7 @@ static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) { ...@@ -512,7 +512,7 @@ static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) {
} }
else { else {
// False tree root. // False tree root.
RbNode head = { 0 }; RbNode head = { { NULL, NULL }, 0, 0 };
// Grandparent & parent. // Grandparent & parent.
RbNode* g = NULL; RbNode* g = NULL;
...@@ -522,7 +522,8 @@ static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) { ...@@ -522,7 +522,8 @@ static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) {
RbNode* p = NULL; RbNode* p = NULL;
RbNode* q = t->node[1] = self->_root; RbNode* q = t->node[1] = self->_root;
int dir = 0, last; int dir = 0;
int last = 0; // Not needed to initialize, but makes some tools happy.
// Search down the tree. // Search down the tree.
for (;;) { for (;;) {
...@@ -590,7 +591,7 @@ static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) { ...@@ -590,7 +591,7 @@ static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) {
//! the `node` passed. //! the `node` passed.
static MemNode* vMemMgrRemoveNode(VMemMgr* self, MemNode* node) { static MemNode* vMemMgrRemoveNode(VMemMgr* self, MemNode* node) {
// False tree root. // False tree root.
RbNode head = { 0 }; RbNode head = { { NULL, NULL }, 0, 0 };
// Helpers. // Helpers.
RbNode* q = &head; RbNode* q = &head;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#ifndef _ASMJIT_BASE_VMEM_H #ifndef _ASMJIT_BASE_VMEM_H
#define _ASMJIT_BASE_VMEM_H #define _ASMJIT_BASE_VMEM_H
// [Dependencies] // [Dependencies - AsmJit]
#include "../base/error.h" #include "../base/error.h"
#include "../base/lock.h" #include "../base/lock.h"
...@@ -21,11 +21,11 @@ namespace asmjit { ...@@ -21,11 +21,11 @@ namespace asmjit {
//! \{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::kVMemAlloc] // [asmjit::VMemAllocType]
// ============================================================================ // ============================================================================
//! Type of virtual memory allocation, see `VMemMgr::alloc()`. //! Type of virtual memory allocation, see `VMemMgr::alloc()`.
ASMJIT_ENUM(kVMemAlloc) { ASMJIT_ENUM(VMemAllocType) {
//! Normal memory allocation, has to be freed by `VMemMgr::release()`. //! Normal memory allocation, has to be freed by `VMemMgr::release()`.
kVMemAllocFreeable = 0, kVMemAllocFreeable = 0,
//! Allocate permanent memory, can't be freed. //! Allocate permanent memory, can't be freed.
...@@ -33,11 +33,11 @@ ASMJIT_ENUM(kVMemAlloc) { ...@@ -33,11 +33,11 @@ ASMJIT_ENUM(kVMemAlloc) {
}; };
// ============================================================================ // ============================================================================
// [asmjit::kVMemFlags] // [asmjit::VMemFlags]
// ============================================================================ // ============================================================================
//! Type of virtual memory allocation, see `VMemMgr::alloc()`. //! Type of virtual memory allocation, see `VMemMgr::alloc()`.
ASMJIT_ENUM(kVMemFlags) { ASMJIT_ENUM(VMemFlags) {
//! Memory is writable. //! Memory is writable.
kVMemFlagWritable = 0x00000001, kVMemFlagWritable = 0x00000001,
//! Memory is executable. //! Memory is executable.
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#ifndef _ASMJIT_BASE_ZONE_H #ifndef _ASMJIT_BASE_ZONE_H
#define _ASMJIT_BASE_ZONE_H #define _ASMJIT_BASE_ZONE_H
// [Dependencies] // [Dependencies - AsmJit]
#include "../base/globals.h" #include "../base/globals.h"
// [Api-Begin] // [Api-Begin]
......
...@@ -8,14 +8,14 @@ ...@@ -8,14 +8,14 @@
#ifndef _ASMJIT_BUILD_H #ifndef _ASMJIT_BUILD_H
#define _ASMJIT_BUILD_H #define _ASMJIT_BUILD_H
// [Include] // [Config]
#if defined(ASMJIT_CONFIG_FILE) #if defined(ASMJIT_CONFIG_FILE)
# include ASMJIT_CONFIG_FILE # include ASMJIT_CONFIG_FILE
#else #else
# include "./config.h" # include "./config.h"
#endif // ASMJIT_CONFIG_FILE #endif // ASMJIT_CONFIG_FILE
// Turn off deprecation warnings when compiling AsmJit. // [MSC - Turn off deprecation warnings when compiling AsmJit]
#if defined(ASMJIT_EXPORTS) && defined(_MSC_VER) #if defined(ASMJIT_EXPORTS) && defined(_MSC_VER)
# if !defined(_CRT_SECURE_NO_DEPRECATE) # if !defined(_CRT_SECURE_NO_DEPRECATE)
# define _CRT_SECURE_NO_DEPRECATE # define _CRT_SECURE_NO_DEPRECATE
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#endif // ASMJIT_EXPORTS #endif // ASMJIT_EXPORTS
// [Dependencies - C] // [Dependencies - C]
#include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
...@@ -34,7 +35,7 @@ ...@@ -34,7 +35,7 @@
#include <new> #include <new>
// ============================================================================ // ============================================================================
// [asmjit::build - Sanity] // [asmjit::Build - Sanity]
// ============================================================================ // ============================================================================
#if defined(ASMJIT_DISABLE_NAMES) && !defined(ASMJIT_DISABLE_LOGGER) #if defined(ASMJIT_DISABLE_NAMES) && !defined(ASMJIT_DISABLE_LOGGER)
...@@ -42,7 +43,7 @@ ...@@ -42,7 +43,7 @@
#endif // ASMJIT_DISABLE_NAMES && !ASMJIT_DISABLE_LOGGER #endif // ASMJIT_DISABLE_NAMES && !ASMJIT_DISABLE_LOGGER
// ============================================================================ // ============================================================================
// [asmjit::build - OS] // [asmjit::Build - OS]
// ============================================================================ // ============================================================================
#if defined(_WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(_WIN64) #if defined(_WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(_WIN64)
...@@ -57,34 +58,41 @@ ...@@ -57,34 +58,41 @@
# define ASMJIT_OS_POSIX # define ASMJIT_OS_POSIX
# define ASMJIT_OS_MAC # define ASMJIT_OS_MAC
#else #else
# warning "AsmJit - Unable to detect host operating system, using ASMJIT_OS_POSIX" # pragma message("AsmJit - Unable to detect host operating system, using ASMJIT_OS_POSIX.")
# define ASMJIT_OS_POSIX # define ASMJIT_OS_POSIX
#endif #endif
// ============================================================================ // ============================================================================
// [asmjit::build - Arch] // [asmjit::Build - Arch]
// ============================================================================ // ============================================================================
#if defined(_M_X64 ) || \ // [X64]
defined(_M_AMD64 ) || \ #if defined(__x86_64__) || \
defined(_WIN64 ) || \
defined(__amd64__ ) || \ defined(__amd64__ ) || \
defined(__LP64 ) || \ defined(__LP64 ) || \
defined(__x86_64__) defined(_M_X64 ) || \
# define ASMJIT_HOST_X64 defined(_M_AMD64 ) || \
# define ASMJIT_HOST_LE defined(_WIN64 )
# define ASMJIT_HOST_UNALIGNED_16
# define ASMJIT_HOST_UNALIGNED_32 # define ASMJIT_ARCH_X64
# define ASMJIT_HOST_UNALIGNED_64 # define ASMJIT_ARCH_LE
# define ASMJIT_ARCH_UNALIGNED_16
# define ASMJIT_ARCH_UNALIGNED_32
# define ASMJIT_ARCH_UNALIGNED_64
// [X86]
#elif \ #elif \
defined(_M_IX86 ) || \ defined(_M_IX86 ) || \
defined(__INTEL__) || \ defined(__INTEL__) || \
defined(__i386__ ) defined(__i386__ )
# define ASMJIT_HOST_X86
# define ASMJIT_HOST_LE # define ASMJIT_ARCH_X86
# define ASMJIT_HOST_UNALIGNED_16 # define ASMJIT_ARCH_LE
# define ASMJIT_HOST_UNALIGNED_32 # define ASMJIT_ARCH_UNALIGNED_16
# define ASMJIT_HOST_UNALIGNED_64 # define ASMJIT_ARCH_UNALIGNED_32
# define ASMJIT_ARCH_UNALIGNED_64
// [Arm]
#elif \ #elif \
defined(_ARM ) || \ defined(_ARM ) || \
defined(_M_ARM_FP ) || \ defined(_M_ARM_FP ) || \
...@@ -94,14 +102,17 @@ ...@@ -94,14 +102,17 @@
defined(__TARGET_ARCH_ARM ) || \ defined(__TARGET_ARCH_ARM ) || \
defined(__TARGET_ARCH_THUMB) || \ defined(__TARGET_ARCH_THUMB) || \
defined(__thumb__ ) defined(__thumb__ )
# define ASMJIT_HOST_ARM
# define ASMJIT_HOST_LE # define ASMJIT_ARCH_ARM
# define ASMJIT_ARCH_LE
// [Unknown]
#else #else
# warning "AsmJit - Unable to detect host architecture" # error "AsmJit - Unable to detect host architecture."
#endif #endif
// ============================================================================ // ============================================================================
// [asmjit::build - Build] // [asmjit::Build - Build]
// ============================================================================ // ============================================================================
// Build host architecture if no architecture is selected. // Build host architecture if no architecture is selected.
...@@ -113,16 +124,16 @@ ...@@ -113,16 +124,16 @@
// Autodetect host architecture if enabled. // Autodetect host architecture if enabled.
#if defined(ASMJIT_BUILD_HOST) #if defined(ASMJIT_BUILD_HOST)
# if defined(ASMJIT_HOST_X86) && !defined(ASMJIT_BUILD_X86) # if defined(ASMJIT_ARCH_X86) && !defined(ASMJIT_BUILD_X86)
# define ASMJIT_BUILD_X86 # define ASMJIT_BUILD_X86
# endif // ASMJIT_HOST_X86 && !ASMJIT_BUILD_X86 # endif // ASMJIT_ARCH_X86 && !ASMJIT_BUILD_X86
# if defined(ASMJIT_HOST_X64) && !defined(ASMJIT_BUILD_X64) # if defined(ASMJIT_ARCH_X64) && !defined(ASMJIT_BUILD_X64)
# define ASMJIT_BUILD_X64 # define ASMJIT_BUILD_X64
# endif // ASMJIT_HOST_X64 && !ASMJIT_BUILD_X64 # endif // ASMJIT_ARCH_X64 && !ASMJIT_BUILD_X64
#endif // ASMJIT_BUILD_HOST #endif // ASMJIT_BUILD_HOST
// ============================================================================ // ============================================================================
// [asmjit::build - Decorators] // [asmjit::Build - Decorators]
// ============================================================================ // ============================================================================
#if defined(ASMJIT_EMBED) && !defined(ASMJIT_STATIC) #if defined(ASMJIT_EMBED) && !defined(ASMJIT_STATIC)
...@@ -179,7 +190,7 @@ ...@@ -179,7 +190,7 @@
# define ASMJIT_INLINE inline # define ASMJIT_INLINE inline
#endif #endif
#if defined(ASMJIT_HOST_X86) #if defined(ASMJIT_ARCH_X86)
# if defined(__GNUC__) || defined(__clang__) # if defined(__GNUC__) || defined(__clang__)
# define ASMJIT_REGPARM_1 __attribute__((regparm(1))) # define ASMJIT_REGPARM_1 __attribute__((regparm(1)))
# define ASMJIT_REGPARM_2 __attribute__((regparm(2))) # define ASMJIT_REGPARM_2 __attribute__((regparm(2)))
...@@ -196,20 +207,20 @@ ...@@ -196,20 +207,20 @@
# define ASMJIT_FASTCALL # define ASMJIT_FASTCALL
# define ASMJIT_STDCALL # define ASMJIT_STDCALL
# define ASMJIT_CDECL # define ASMJIT_CDECL
#endif // ASMJIT_HOST_X86 #endif // ASMJIT_ARCH_X86
// ============================================================================ // ============================================================================
// [asmjit::build - Enum] // [asmjit::Build - Enum]
// ============================================================================ // ============================================================================
#if defined(_MSC_VER) #if defined(_MSC_VER) && _MSC_VER >= 1400
# define ASMJIT_ENUM(_Name_) enum _Name_ : uint32_t # define ASMJIT_ENUM(_Name_) enum _Name_ : uint32_t
#else #else
# define ASMJIT_ENUM(_Name_) enum _Name_ # define ASMJIT_ENUM(_Name_) enum _Name_
#endif #endif
// ============================================================================ // ============================================================================
// [asmjit::build - Memory Management] // [asmjit::Build - Memory Management]
// ============================================================================ // ============================================================================
#if !defined(ASMJIT_ALLOC) && !defined(ASMJIT_REALLOC) && !defined(ASMJIT_FREE) #if !defined(ASMJIT_ALLOC) && !defined(ASMJIT_REALLOC) && !defined(ASMJIT_FREE)
...@@ -223,32 +234,32 @@ ...@@ -223,32 +234,32 @@
#endif // !ASMJIT_ALLOC && !ASMJIT_REALLOC && !ASMJIT_FREE #endif // !ASMJIT_ALLOC && !ASMJIT_REALLOC && !ASMJIT_FREE
// ============================================================================ // ============================================================================
// [asmjit::build - _ASMJIT_HOST_INDEX] // [asmjit::Build - _ASMJIT_ARCH_INDEX]
// ============================================================================ // ============================================================================
#if defined(ASMJIT_HOST_LE) #if defined(ASMJIT_ARCH_LE)
# define _ASMJIT_HOST_INDEX(_Total_, _Index_) (_Index_) # define _ASMJIT_ARCH_INDEX(_Total_, _Index_) (_Index_)
#else #else
# define _ASMJIT_HOST_INDEX(_Total_, _Index_) ((_Total_) - 1 - (_Index_)) # define _ASMJIT_ARCH_INDEX(_Total_, _Index_) ((_Total_) - 1 - (_Index_))
#endif #endif
// ============================================================================ // ============================================================================
// [asmjit::build - BLEND_OFFSET_OF] // [asmjit::Build - BLEND_OFFSET_OF]
// ============================================================================ // ============================================================================
//! Cross-platform solution to get offset of `_Field_` in `_Struct_`. //! Cross-platform solution to get offset of `_Field_` in `_Struct_`.
#define ASMJIT_OFFSET_OF(_Struct_, _Field_) \ #define ASMJIT_OFFSET_OF(_Struct_, _Field_) \
((size_t) ((const uint8_t*) &((const _Struct_*)0x1)->_Field_) - 1) static_cast<int>((intptr_t) ((const uint8_t*) &((const _Struct_*)0x1)->_Field_) - 1)
// ============================================================================ // ============================================================================
// [asmjit::build - ASMJIT_ARRAY_SIZE] // [asmjit::Build - ASMJIT_ARRAY_SIZE]
// ============================================================================ // ============================================================================
#define ASMJIT_ARRAY_SIZE(_Array_) \ #define ASMJIT_ARRAY_SIZE(_Array_) \
(sizeof(_Array_) / sizeof(*_Array_)) (sizeof(_Array_) / sizeof(*_Array_))
// ============================================================================ // ============================================================================
// [asmjit::build - ASMJIT_DEBUG / ASMJIT_TRACE] // [asmjit::Build - ASMJIT_DEBUG / ASMJIT_TRACE]
// ============================================================================ // ============================================================================
// If ASMJIT_DEBUG and ASMJIT_RELEASE is not defined ASMJIT_DEBUG will be // If ASMJIT_DEBUG and ASMJIT_RELEASE is not defined ASMJIT_DEBUG will be
...@@ -263,7 +274,7 @@ ...@@ -263,7 +274,7 @@
// ASMJIT_TRACE is only used by sources and private headers. It's safe to make // ASMJIT_TRACE is only used by sources and private headers. It's safe to make
// it unavailable outside of AsmJit. // it unavailable outside of AsmJit.
#if defined(ASMJIT_EXPORTS) #if defined(ASMJIT_EXPORTS)
namespace asmjit { static inline int disabledTrace(...) {} } namespace asmjit { static inline int disabledTrace(...) { return 0; } }
# if defined(ASMJIT_TRACE) # if defined(ASMJIT_TRACE)
# define ASMJIT_TSEC(_Section_) _Section_ # define ASMJIT_TSEC(_Section_) _Section_
# define ASMJIT_TLOG ::printf(__VA_ARGS__) # define ASMJIT_TLOG ::printf(__VA_ARGS__)
...@@ -274,7 +285,7 @@ namespace asmjit { static inline int disabledTrace(...) {} } ...@@ -274,7 +285,7 @@ namespace asmjit { static inline int disabledTrace(...) {} }
#endif // ASMJIT_EXPORTS #endif // ASMJIT_EXPORTS
// ============================================================================ // ============================================================================
// [asmjit::build - ASMJIT_UNUSED] // [asmjit::Build - ASMJIT_UNUSED]
// ============================================================================ // ============================================================================
#if !defined(ASMJIT_UNUSED) #if !defined(ASMJIT_UNUSED)
...@@ -282,7 +293,7 @@ namespace asmjit { static inline int disabledTrace(...) {} } ...@@ -282,7 +293,7 @@ namespace asmjit { static inline int disabledTrace(...) {} }
#endif // ASMJIT_UNUSED #endif // ASMJIT_UNUSED
// ============================================================================ // ============================================================================
// [asmjit::build - ASMJIT_NOP] // [asmjit::Build - ASMJIT_NOP]
// ============================================================================ // ============================================================================
#if !defined(ASMJIT_NOP) #if !defined(ASMJIT_NOP)
...@@ -290,7 +301,7 @@ namespace asmjit { static inline int disabledTrace(...) {} } ...@@ -290,7 +301,7 @@ namespace asmjit { static inline int disabledTrace(...) {} }
#endif // ASMJIT_NOP #endif // ASMJIT_NOP
// ============================================================================ // ============================================================================
// [asmjit::build - ASMJIT_NO_COPY] // [asmjit::Build - ASMJIT_NO_COPY]
// ============================================================================ // ============================================================================
#define ASMJIT_NO_COPY(_Type_) \ #define ASMJIT_NO_COPY(_Type_) \
...@@ -300,7 +311,7 @@ private: \ ...@@ -300,7 +311,7 @@ private: \
public: public:
// ============================================================================ // ============================================================================
// [asmjit::build - StdInt] // [asmjit::Build - StdInt]
// ============================================================================ // ============================================================================
#if defined(__MINGW32__) #if defined(__MINGW32__)
...@@ -308,7 +319,7 @@ public: ...@@ -308,7 +319,7 @@ public:
#endif // __MINGW32__ #endif // __MINGW32__
#if defined(_MSC_VER) && (_MSC_VER < 1600) #if defined(_MSC_VER) && (_MSC_VER < 1600)
# if !defined(ASMJIT_SUPRESS_STD_TYPES) # if !defined(ASMJIT_SUPPRESS_STD_TYPES)
# if (_MSC_VER < 1300) # if (_MSC_VER < 1300)
typedef signed char int8_t; typedef signed char int8_t;
typedef signed short int16_t; typedef signed short int16_t;
...@@ -328,7 +339,7 @@ typedef unsigned __int16 uint16_t; ...@@ -328,7 +339,7 @@ typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t; typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t; typedef unsigned __int64 uint64_t;
# endif // _MSC_VER # endif // _MSC_VER
# endif // ASMJIT_SUPRESS_STD_TYPES # endif // ASMJIT_SUPPRESS_STD_TYPES
#else #else
# include <stdint.h> # include <stdint.h>
# include <limits.h> # include <limits.h>
...@@ -343,10 +354,10 @@ typedef unsigned __int64 uint64_t; ...@@ -343,10 +354,10 @@ typedef unsigned __int64 uint64_t;
#endif #endif
// ============================================================================ // ============================================================================
// [asmjit::build - Windows] // [asmjit::Build - Windows]
// ============================================================================ // ============================================================================
#if defined(ASMJIT_OS_WINDOWS) && !defined(ASMJIT_SUPRESS_WINDOWS_H) #if defined(ASMJIT_OS_WINDOWS) && !defined(ASMJIT_SUPPRESS_WINDOWS_H)
# if !defined(WIN32_LEAN_AND_MEAN) # if !defined(WIN32_LEAN_AND_MEAN)
# define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
...@@ -370,10 +381,10 @@ typedef unsigned __int64 uint64_t; ...@@ -370,10 +381,10 @@ typedef unsigned __int64 uint64_t;
# undef ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN # undef ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN
# endif # endif
#endif // ASMJIT_OS_WINDOWS && !ASMJIT_SUPRESS_WINDOWS_H #endif // ASMJIT_OS_WINDOWS && !ASMJIT_SUPPRESS_WINDOWS_H
// ============================================================================ // ============================================================================
// [asmjit::build - Test] // [asmjit::Build - Test]
// ============================================================================ // ============================================================================
// Include a unit testing package if this is a `asmjit_test` build. // Include a unit testing package if this is a `asmjit_test` build.
......
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in this package.
// [Guard]
#ifndef _ASMJIT_CONTRIB_H
#define _ASMJIT_CONTRIB_H
// [Dependencies - Core]
#include "base.h"
// [Dependencies - Contrib]
#include "contrib/winremoteruntime.h"
// [Guard]
#endif // _ASMJIT_CONTRIB_H
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
// Zlib - See LICENSE.md file in the package. // Zlib - See LICENSE.md file in the package.
// [Guard] // [Guard]
#ifndef _ASMJIT_HOST_H #ifndef _ASMJIT_ARCH_H
#define _ASMJIT_HOST_H #define _ASMJIT_ARCH_H
// [Dependencies - Core] // [Dependencies - Core]
#include "base.h" #include "base.h"
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
// [asmjit::host - X86 / X64] // [asmjit::host - X86 / X64]
// ============================================================================ // ============================================================================
#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) #if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64)
#include "x86.h" #include "x86.h"
namespace asmjit { namespace asmjit {
...@@ -53,7 +53,7 @@ typedef X86YmmVar YmmVar; ...@@ -53,7 +53,7 @@ typedef X86YmmVar YmmVar;
} // asmjit namespace } // asmjit namespace
#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 #endif // ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64
// [Guard] // [Guard]
#endif // _ASMJIT_HOST_H #endif // _ASMJIT_ARCH_H
This diff is collapsed.
This diff is collapsed.
...@@ -60,14 +60,18 @@ const X86VarInfo _x86VarInfo[] = { ...@@ -60,14 +60,18 @@ const X86VarInfo _x86VarInfo[] = {
/* 10: kVarTypeFp32 */ { kX86RegTypeFp , 4 , C(Fp) , D(Sp) , "fp" }, /* 10: kVarTypeFp32 */ { kX86RegTypeFp , 4 , C(Fp) , D(Sp) , "fp" },
/* 11: kVarTypeFp64 */ { kX86RegTypeFp , 8 , C(Fp) , D(Dp) , "fp" }, /* 11: kVarTypeFp64 */ { kX86RegTypeFp , 8 , C(Fp) , D(Dp) , "fp" },
/* 12: kX86VarTypeMm */ { kX86RegTypeMm , 8 , C(Mm) , 0 , "mm" }, /* 12: kX86VarTypeMm */ { kX86RegTypeMm , 8 , C(Mm) , 0 , "mm" },
/* 13: kX86VarTypeXmm */ { kX86RegTypeXmm , 16, C(Xyz), 0 , "xmm" }, /* 13: kX86VarTypeK */ { kX86RegTypeK , 8 , C(K) , 0 , "k" },
/* 14: kX86VarTypeXmmSs */ { kX86RegTypeXmm , 4 , C(Xyz), D(Sp) , "xmm" }, /* 14: kX86VarTypeXmm */ { kX86RegTypeXmm , 16, C(Xyz), 0 , "xmm" },
/* 15: kX86VarTypeXmmPs */ { kX86RegTypeXmm , 16, C(Xyz), D(Sp) | D(Packed), "xmm" }, /* 15: kX86VarTypeXmmSs */ { kX86RegTypeXmm , 4 , C(Xyz), D(Sp) , "xmm" },
/* 16: kX86VarTypeXmmSd */ { kX86RegTypeXmm , 8 , C(Xyz), D(Dp) , "xmm" }, /* 16: kX86VarTypeXmmPs */ { kX86RegTypeXmm , 16, C(Xyz), D(Sp) | D(Packed), "xmm" },
/* 17: kX86VarTypeXmmPd */ { kX86RegTypeXmm , 16, C(Xyz), D(Dp) | D(Packed), "xmm" }, /* 17: kX86VarTypeXmmSd */ { kX86RegTypeXmm , 8 , C(Xyz), D(Dp) , "xmm" },
/* 18: kX86VarTypeYmm */ { kX86RegTypeYmm , 32, C(Xyz), 0 , "ymm" }, /* 18: kX86VarTypeXmmPd */ { kX86RegTypeXmm , 16, C(Xyz), D(Dp) | D(Packed), "xmm" },
/* 19: kX86VarTypeYmmPs */ { kX86RegTypeYmm , 32, C(Xyz), D(Sp) | D(Packed), "ymm" }, /* 19: kX86VarTypeYmm */ { kX86RegTypeYmm , 32, C(Xyz), 0 , "ymm" },
/* 20: kX86VarTypeYmmPd */ { kX86RegTypeYmm , 32, C(Xyz), D(Dp) | D(Packed), "ymm" } /* 20: kX86VarTypeYmmPs */ { kX86RegTypeYmm , 32, C(Xyz), D(Sp) | D(Packed), "ymm" },
/* 21: kX86VarTypeYmmPd */ { kX86RegTypeYmm , 32, C(Xyz), D(Dp) | D(Packed), "ymm" },
/* 22: kX86VarTypeZmm */ { kX86RegTypeZmm , 64, C(Xyz), 0 , "zmm" },
/* 23: kX86VarTypeZmmPs */ { kX86RegTypeZmm , 64, C(Xyz), D(Sp) | D(Packed), "zmm" },
/* 24: kX86VarTypeZmmPd */ { kX86RegTypeZmm , 64, C(Xyz), D(Dp) | D(Packed), "zmm" }
}; };
#undef D #undef D
...@@ -88,14 +92,18 @@ const uint8_t _x86VarMapping[kX86VarTypeCount] = { ...@@ -88,14 +92,18 @@ const uint8_t _x86VarMapping[kX86VarTypeCount] = {
/* 10: kVarTypeFp32 */ kVarTypeFp32, /* 10: kVarTypeFp32 */ kVarTypeFp32,
/* 11: kVarTypeFp64 */ kVarTypeFp64, /* 11: kVarTypeFp64 */ kVarTypeFp64,
/* 12: kX86VarTypeMm */ kX86VarTypeMm, /* 12: kX86VarTypeMm */ kX86VarTypeMm,
/* 13: kX86VarTypeXmm */ kX86VarTypeXmm, /* 13: kX86VarTypeK */ kX86VarTypeK,
/* 14: kX86VarTypeXmmSs */ kX86VarTypeXmmSs, /* 14: kX86VarTypeXmm */ kX86VarTypeXmm,
/* 15: kX86VarTypeXmmPs */ kX86VarTypeXmmPs, /* 15: kX86VarTypeXmmSs */ kX86VarTypeXmmSs,
/* 16: kX86VarTypeXmmSd */ kX86VarTypeXmmSd, /* 16: kX86VarTypeXmmPs */ kX86VarTypeXmmPs,
/* 17: kX86VarTypeXmmPd */ kX86VarTypeXmmPd, /* 17: kX86VarTypeXmmSd */ kX86VarTypeXmmSd,
/* 18: kX86VarTypeYmm */ kX86VarTypeYmm, /* 18: kX86VarTypeXmmPd */ kX86VarTypeXmmPd,
/* 19: kX86VarTypeYmmPs */ kX86VarTypeYmmPs, /* 19: kX86VarTypeYmm */ kX86VarTypeYmm,
/* 20: kX86VarTypeYmmPd */ kX86VarTypeYmmPd /* 20: kX86VarTypeYmmPs */ kX86VarTypeYmmPs,
/* 21: kX86VarTypeYmmPd */ kX86VarTypeYmmPd,
/* 22: kX86VarTypeZmm */ kX86VarTypeZmm,
/* 23: kX86VarTypeZmmPs */ kX86VarTypeZmmPs,
/* 24: kX86VarTypeZmmPd */ kX86VarTypeZmmPd
}; };
#endif // ASMJIT_BUILD_X86 #endif // ASMJIT_BUILD_X86
...@@ -114,14 +122,18 @@ const uint8_t _x64VarMapping[kX86VarTypeCount] = { ...@@ -114,14 +122,18 @@ const uint8_t _x64VarMapping[kX86VarTypeCount] = {
/* 10: kVarTypeFp32 */ kVarTypeFp32, /* 10: kVarTypeFp32 */ kVarTypeFp32,
/* 11: kVarTypeFp64 */ kVarTypeFp64, /* 11: kVarTypeFp64 */ kVarTypeFp64,
/* 12: kX86VarTypeMm */ kX86VarTypeMm, /* 12: kX86VarTypeMm */ kX86VarTypeMm,
/* 13: kX86VarTypeXmm */ kX86VarTypeXmm, /* 13: kX86VarTypeK */ kX86VarTypeK,
/* 14: kX86VarTypeXmmSs */ kX86VarTypeXmmSs, /* 14: kX86VarTypeXmm */ kX86VarTypeXmm,
/* 15: kX86VarTypeXmmPs */ kX86VarTypeXmmPs, /* 15: kX86VarTypeXmmSs */ kX86VarTypeXmmSs,
/* 16: kX86VarTypeXmmSd */ kX86VarTypeXmmSd, /* 16: kX86VarTypeXmmPs */ kX86VarTypeXmmPs,
/* 17: kX86VarTypeXmmPd */ kX86VarTypeXmmPd, /* 17: kX86VarTypeXmmSd */ kX86VarTypeXmmSd,
/* 18: kX86VarTypeYmm */ kX86VarTypeYmm, /* 18: kX86VarTypeXmmPd */ kX86VarTypeXmmPd,
/* 19: kX86VarTypeYmmPs */ kX86VarTypeYmmPs, /* 19: kX86VarTypeYmm */ kX86VarTypeYmm,
/* 20: kX86VarTypeYmmPd */ kX86VarTypeYmmPd /* 20: kX86VarTypeYmmPs */ kX86VarTypeYmmPs,
/* 21: kX86VarTypeYmmPd */ kX86VarTypeYmmPd,
/* 22: kX86VarTypeZmm */ kX86VarTypeZmm,
/* 23: kX86VarTypeZmmPs */ kX86VarTypeZmmPs,
/* 24: kX86VarTypeZmmPd */ kX86VarTypeZmmPd
}; };
#endif // ASMJIT_BUILD_X64 #endif // ASMJIT_BUILD_X64
...@@ -436,7 +448,7 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch, ...@@ -436,7 +448,7 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch,
continue; continue;
arg._regIndex = self->_passedOrderGp[gpPos++]; arg._regIndex = self->_passedOrderGp[gpPos++];
self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); self->_used.or_(kX86RegClassGp, IntUtil::mask(arg.getRegIndex()));
} }
// Stack arguments. // Stack arguments.
...@@ -482,14 +494,14 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch, ...@@ -482,14 +494,14 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch,
if (x86ArgIsInt(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderGp)) { if (x86ArgIsInt(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderGp)) {
arg._regIndex = self->_passedOrderGp[i]; arg._regIndex = self->_passedOrderGp[i];
self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); self->_used.or_(kX86RegClassGp, IntUtil::mask(arg.getRegIndex()));
continue; continue;
} }
if (x86ArgIsFp(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderXmm)) { if (x86ArgIsFp(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderXmm)) {
arg._varType = static_cast<uint8_t>(x86ArgTypeToXmmType(varType)); arg._varType = static_cast<uint8_t>(x86ArgTypeToXmmType(varType));
arg._regIndex = self->_passedOrderXmm[i]; arg._regIndex = self->_passedOrderXmm[i];
self->_used.add(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex())); self->_used.or_(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex()));
} }
} }
...@@ -527,7 +539,7 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch, ...@@ -527,7 +539,7 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch,
continue; continue;
arg._regIndex = self->_passedOrderGp[gpPos++]; arg._regIndex = self->_passedOrderGp[gpPos++];
self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); self->_used.or_(kX86RegClassGp, IntUtil::mask(arg.getRegIndex()));
} }
// Register arguments (Xmm), always left-to-right. // Register arguments (Xmm), always left-to-right.
...@@ -538,7 +550,7 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch, ...@@ -538,7 +550,7 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch,
if (x86ArgIsFp(varType)) { if (x86ArgIsFp(varType)) {
arg._varType = static_cast<uint8_t>(x86ArgTypeToXmmType(varType)); arg._varType = static_cast<uint8_t>(x86ArgTypeToXmmType(varType));
arg._regIndex = self->_passedOrderXmm[xmmPos++]; arg._regIndex = self->_passedOrderXmm[xmmPos++];
self->_used.add(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex())); self->_used.or_(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex()));
} }
} }
...@@ -721,10 +733,10 @@ Error X86Compiler::setArch(uint32_t arch) { ...@@ -721,10 +733,10 @@ Error X86Compiler::setArch(uint32_t arch) {
_regSize = 4; _regSize = 4;
_regCount.reset(); _regCount.reset();
_regCount._gp = 8; _regCount._gp = 8;
_regCount._fp = 8; _regCount._mm = 8;
_regCount._mm = 8; _regCount._k = 8;
_regCount._xy = 8; _regCount._xyz = 8;
zax = x86::eax; zax = x86::eax;
zcx = x86::ecx; zcx = x86::ecx;
...@@ -746,10 +758,10 @@ Error X86Compiler::setArch(uint32_t arch) { ...@@ -746,10 +758,10 @@ Error X86Compiler::setArch(uint32_t arch) {
_regSize = 8; _regSize = 8;
_regCount.reset(); _regCount.reset();
_regCount._gp = 16; _regCount._gp = 16;
_regCount._fp = 8; _regCount._mm = 8;
_regCount._mm = 8; _regCount._k = 8;
_regCount._xy = 16; _regCount._xyz = 16;
zax = x86::rax; zax = x86::rax;
zcx = x86::rcx; zcx = x86::rcx;
...@@ -783,7 +795,7 @@ static InstNode* X86Compiler_newInst(X86Compiler* self, void* p, uint32_t code, ...@@ -783,7 +795,7 @@ static InstNode* X86Compiler_newInst(X86Compiler* self, void* p, uint32_t code,
JumpNode* node = new(p) JumpNode(self, code, options, opList, opCount); JumpNode* node = new(p) JumpNode(self, code, options, opList, opCount);
TargetNode* jTarget = self->getTargetById(opList[0].getId()); TargetNode* jTarget = self->getTargetById(opList[0].getId());
node->addFlags(code == kX86InstIdJmp ? kNodeFlagIsJmp | kNodeFlagIsTaken : kNodeFlagIsJcc); node->orFlags(code == kX86InstIdJmp ? kNodeFlagIsJmp | kNodeFlagIsTaken : kNodeFlagIsJcc);
node->_target = jTarget; node->_target = jTarget;
node->_jumpNext = static_cast<JumpNode*>(jTarget->_from); node->_jumpNext = static_cast<JumpNode*>(jTarget->_from);
...@@ -792,9 +804,9 @@ static InstNode* X86Compiler_newInst(X86Compiler* self, void* p, uint32_t code, ...@@ -792,9 +804,9 @@ static InstNode* X86Compiler_newInst(X86Compiler* self, void* p, uint32_t code,
// The 'jmp' is always taken, conditional jump can contain hint, we detect it. // The 'jmp' is always taken, conditional jump can contain hint, we detect it.
if (code == kX86InstIdJmp) if (code == kX86InstIdJmp)
node->addFlags(kNodeFlagIsTaken); node->orFlags(kNodeFlagIsTaken);
else if (options & kInstOptionTaken) else if (options & kInstOptionTaken)
node->addFlags(kNodeFlagIsTaken); node->orFlags(kNodeFlagIsTaken);
node->addOptions(options); node->addOptions(options);
return node; return node;
...@@ -1025,6 +1037,22 @@ InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, ...@@ -1025,6 +1037,22 @@ InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1,
return static_cast<InstNode*>(addNode(node)); return static_cast<InstNode*>(addNode(node));
} }
InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3_) {
Imm o3(o3_);
InstNode* node = newInst(code, o0, o1, o2, o3);
if (node == NULL)
return NULL;
return static_cast<InstNode*>(addNode(node));
}
InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3_) {
Imm o3(o3_);
InstNode* node = newInst(code, o0, o1, o2, o3);
if (node == NULL)
return NULL;
return static_cast<InstNode*>(addNode(node));
}
// ============================================================================ // ============================================================================
// [asmjit::X86Compiler - Func] // [asmjit::X86Compiler - Func]
// ============================================================================ // ============================================================================
......
This diff is collapsed.
This diff is collapsed.
...@@ -59,7 +59,7 @@ struct X86Context : public Context { ...@@ -59,7 +59,7 @@ struct X86Context : public Context {
// [Reset] // [Reset]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
virtual void reset(); virtual void reset(bool releaseMemory = false);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Arch] // [Arch]
...@@ -150,8 +150,8 @@ struct X86Context : public Context { ...@@ -150,8 +150,8 @@ struct X86Context : public Context {
vd->setModified(modified); vd->setModified(modified);
_x86State.getListByClass(C)[regIndex] = vd; _x86State.getListByClass(C)[regIndex] = vd;
_x86State._occupied.add(C, regMask); _x86State._occupied.or_(C, regMask);
_x86State._modified.add(C, static_cast<uint32_t>(modified) << regIndex); _x86State._modified.or_(C, static_cast<uint32_t>(modified) << regIndex);
ASMJIT_X86_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
...@@ -174,8 +174,8 @@ struct X86Context : public Context { ...@@ -174,8 +174,8 @@ struct X86Context : public Context {
vd->setModified(false); vd->setModified(false);
_x86State.getListByClass(C)[regIndex] = NULL; _x86State.getListByClass(C)[regIndex] = NULL;
_x86State._occupied.del(C, regMask); _x86State._occupied.andNot(C, regMask);
_x86State._modified.del(C, regMask); _x86State._modified.andNot(C, regMask);
ASMJIT_X86_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
...@@ -244,7 +244,7 @@ struct X86Context : public Context { ...@@ -244,7 +244,7 @@ struct X86Context : public Context {
emitSave(vd, regIndex, "Save"); emitSave(vd, regIndex, "Save");
vd->setModified(false); vd->setModified(false);
_x86State._modified.del(C, regMask); _x86State._modified.andNot(C, regMask);
ASMJIT_X86_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
...@@ -381,7 +381,7 @@ struct X86Context : public Context { ...@@ -381,7 +381,7 @@ struct X86Context : public Context {
uint32_t regMask = IntUtil::mask(regIndex); uint32_t regMask = IntUtil::mask(regIndex);
vd->setModified(true); vd->setModified(true);
_x86State._modified.add(C, regMask); _x86State._modified.or_(C, regMask);
ASMJIT_X86_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
...@@ -393,9 +393,9 @@ struct X86Context : public Context { ...@@ -393,9 +393,9 @@ struct X86Context : public Context {
//! Unuse. //! Unuse.
//! //!
//! Unuse variable, it will be detached it if it's allocated then its state //! Unuse variable, it will be detached it if it's allocated then its state
//! will be changed to kVarStateUnused. //! will be changed to kVarStateNone.
template<int C> template<int C>
ASMJIT_INLINE void unuse(VarData* vd, uint32_t vState = kVarStateUnused) { ASMJIT_INLINE void unuse(VarData* vd, uint32_t vState = kVarStateNone) {
ASMJIT_ASSERT(vd->getClass() == C); ASMJIT_ASSERT(vd->getClass() == C);
ASMJIT_ASSERT(vState != kVarStateReg); ASMJIT_ASSERT(vState != kVarStateReg);
......
...@@ -88,20 +88,33 @@ _Skip: ...@@ -88,20 +88,33 @@ _Skip:
// in 64-bit mode not allows to use inline assembler, so we need intrinsic and // in 64-bit mode not allows to use inline assembler, so we need intrinsic and
// we need also asm version. // we need also asm version.
union X86XCR {
uint64_t value;
struct {
uint32_t eax;
uint32_t edx;
};
};
// callCpuId() and detectCpuInfo() for x86 and x64 platforms begins here. // callCpuId() and detectCpuInfo() for x86 and x64 platforms begins here.
#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) #if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64)
void X86CpuUtil::callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* outResult) { void X86CpuUtil::_docpuid(uint32_t inEcx, uint32_t inEax, X86CpuId* result) {
#if defined(_MSC_VER) #if defined(_MSC_VER)
// 2009-02-05: Thanks to Mike Tajmajer for supporting VC7.1 compiler. // __cpuidex was introduced by VS2008-SP1.
// ASMJIT_HOST_X64 is here only for readibility, only VS2005 can compile 64-bit code. # if _MSC_FULL_VER >= 150030729
# if _MSC_VER >= 1400 || defined(ASMJIT_HOST_X64) __cpuidex(reinterpret_cast<int*>(result->i), inEax, inEcx);
// Done by intrinsics. # elif defined(ASMJIT_ARCH_X64)
__cpuidex(reinterpret_cast<int*>(outResult->i), inEax, inEcx); // VS2008 or less, 64-bit mode - `__cpuidex` doesn't exist! However, 64-bit
# else // _MSC_VER < 1400 // calling convention specifies parameter to be passed in ECX/RCX, so we may
// be lucky if compiler doesn't move the register, otherwise the result is
// undefined.
__cpuid(reinterpret_cast<int*>(result->i), inEax);
# else
uint32_t cpuid_eax = inEax; uint32_t cpuid_eax = inEax;
uint32_t cpuid_ecx = inCax; uint32_t cpuid_ecx = inEcx;
uint32_t* cpuid_out = outResult->i; uint32_t* cpuid_out = result->i;
__asm { __asm {
mov eax, cpuid_eax mov eax, cpuid_eax
...@@ -113,24 +126,59 @@ void X86CpuUtil::callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* outResult) ...@@ -113,24 +126,59 @@ void X86CpuUtil::callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* outResult)
mov dword ptr[edi + 8], ecx mov dword ptr[edi + 8], ecx
mov dword ptr[edi + 12], edx mov dword ptr[edi + 12], edx
} }
# endif // _MSC_VER < 1400 # endif
#elif defined(__GNUC__) #elif defined(__GNUC__)
// Note, patched to preserve ebx/rbx register which is used by GCC. // Note, patched to preserve ebx/rbx register which is used by GCC.
# if defined(ASMJIT_HOST_X86) # if defined(ASMJIT_ARCH_X86)
# define __myCpuId(inEax, inEcx, outEax, outEbx, outEcx, outEdx) \ # define __myCpuId(inEax, inEcx, outEax, outEbx, outEcx, outEdx) \
asm ("mov %%ebx, %%edi\n" \ __asm__ __volatile__( \
"cpuid\n" \ "mov %%ebx, %%edi\n" \
"xchg %%edi, %%ebx\n" \ "cpuid\n" \
: "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) : "a" (inEax), "c" (inEcx)) "xchg %%edi, %%ebx\n" \
: "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) \
: "a" (inEax), "c" (inEcx))
# else # else
# define __myCpuId(inEax, inEcx, outEax, outEbx, outEcx, outEdx) \ # define __myCpuId(inEax, inEcx, outEax, outEbx, outEcx, outEdx) \
asm ("mov %%rbx, %%rdi\n" \ __asm__ __volatile__( \
"cpuid\n" \ "mov %%rbx, %%rdi\n" \
"xchg %%rdi, %%rbx\n" \ "cpuid\n" \
: "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) : "a" (inEax), "c" (inEcx)) "xchg %%rdi, %%rbx\n" \
: "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) \
: "a" (inEax), "c" (inEcx))
# endif # endif
__myCpuId(inEax, inEcx, outResult->eax, outResult->ebx, outResult->ecx, outResult->edx); __myCpuId(inEax, inEcx, result->eax, result->ebx, result->ecx, result->edx);
#else
# error "asmjit::X86CpuUtil::_docpuid() unimplemented!"
#endif
}
static void callXGetBV(X86XCR* result, uint32_t inEcx) {
#if defined(_MSC_VER)
# if (_MSC_FULL_VER >= 160040219) // 2010SP1+
result->value = _xgetbv(inEcx);
# else
result->value = 0;
# endif
#elif defined(__GNUC__)
unsigned int eax, edx;
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
__asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(inEcx));
# else
__asm__ __volatile__(".byte 0x0F, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(inEcx));
# endif
result->eax = eax;
result->edx = edx;
#else
result->value = 0;
#endif // COMPILER #endif // COMPILER
} }
...@@ -138,7 +186,11 @@ void X86CpuUtil::detect(X86CpuInfo* cpuInfo) { ...@@ -138,7 +186,11 @@ void X86CpuUtil::detect(X86CpuInfo* cpuInfo) {
X86CpuId regs; X86CpuId regs;
uint32_t i; uint32_t i;
uint32_t maxId; uint32_t maxBaseId;
bool maybeMPX = false;
X86XCR xcr0;
xcr0.value = 0;
// Clear everything except the '_size' member. // Clear everything except the '_size' member.
::memset(reinterpret_cast<uint8_t*>(cpuInfo) + sizeof(uint32_t), ::memset(reinterpret_cast<uint8_t*>(cpuInfo) + sizeof(uint32_t),
...@@ -148,14 +200,13 @@ void X86CpuUtil::detect(X86CpuInfo* cpuInfo) { ...@@ -148,14 +200,13 @@ void X86CpuUtil::detect(X86CpuInfo* cpuInfo) {
cpuInfo->_hwThreadsCount = CpuInfo::detectHwThreadsCount(); cpuInfo->_hwThreadsCount = CpuInfo::detectHwThreadsCount();
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [CPUID EAX=0x00000000] // [CPUID EAX=0x0]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Get vendor string/id. // Get vendor string/id.
callCpuId(0, 0, &regs); callCpuId(&regs, 0x0);
maxId = regs.eax;
maxBaseId = regs.eax;
::memcpy(cpuInfo->_vendorString, &regs.ebx, 4); ::memcpy(cpuInfo->_vendorString, &regs.ebx, 4);
::memcpy(cpuInfo->_vendorString + 4, &regs.edx, 4); ::memcpy(cpuInfo->_vendorString + 4, &regs.edx, 4);
::memcpy(cpuInfo->_vendorString + 8, &regs.ecx, 4); ::memcpy(cpuInfo->_vendorString + 8, &regs.ecx, 4);
...@@ -168,79 +219,134 @@ void X86CpuUtil::detect(X86CpuInfo* cpuInfo) { ...@@ -168,79 +219,134 @@ void X86CpuUtil::detect(X86CpuInfo* cpuInfo) {
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [CPUID EAX=0x00000001] // [CPUID EAX=0x1]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Get feature flags in ecx/edx and family/model in eax. if (maxBaseId >= 0x1) {
callCpuId(1, 0, &regs); // Get feature flags in ECX/EDX and family/model in EAX.
callCpuId(&regs, 0x1);
// Fill family and model fields. // Fill family and model fields.
cpuInfo->_family = (regs.eax >> 8) & 0x0F; cpuInfo->_family = (regs.eax >> 8) & 0x0F;
cpuInfo->_model = (regs.eax >> 4) & 0x0F; cpuInfo->_model = (regs.eax >> 4) & 0x0F;
cpuInfo->_stepping = (regs.eax ) & 0x0F; cpuInfo->_stepping = (regs.eax ) & 0x0F;
// Use extended family and model fields. // Use extended family and model fields.
if (cpuInfo->_family == 0x0F) { if (cpuInfo->_family == 0x0F) {
cpuInfo->_family += ((regs.eax >> 20) & 0xFF); cpuInfo->_family += ((regs.eax >> 20) & 0xFF);
cpuInfo->_model += ((regs.eax >> 16) & 0x0F) << 4; cpuInfo->_model += ((regs.eax >> 16) & 0x0F) << 4;
} }
cpuInfo->_processorType = ((regs.eax >> 12) & 0x03); cpuInfo->_processorType = ((regs.eax >> 12) & 0x03);
cpuInfo->_brandIndex = ((regs.ebx ) & 0xFF); cpuInfo->_brandIndex = ((regs.ebx ) & 0xFF);
cpuInfo->_flushCacheLineSize = ((regs.ebx >> 8) & 0xFF) * 8; cpuInfo->_flushCacheLineSize = ((regs.ebx >> 8) & 0xFF) * 8;
cpuInfo->_maxLogicalProcessors = ((regs.ebx >> 16) & 0xFF); cpuInfo->_maxLogicalProcessors = ((regs.ebx >> 16) & 0xFF);
if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureSse3); if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureSSE3);
if (regs.ecx & 0x00000002U) cpuInfo->addFeature(kX86CpuFeaturePclmulqdq); if (regs.ecx & 0x00000002U) cpuInfo->addFeature(kX86CpuFeaturePCLMULQDQ);
if (regs.ecx & 0x00000008U) cpuInfo->addFeature(kX86CpuFeatureMonitorMWait); if (regs.ecx & 0x00000008U) cpuInfo->addFeature(kX86CpuFeatureMONITOR);
if (regs.ecx & 0x00000200U) cpuInfo->addFeature(kX86CpuFeatureSsse3); if (regs.ecx & 0x00000200U) cpuInfo->addFeature(kX86CpuFeatureSSSE3);
if (regs.ecx & 0x00002000U) cpuInfo->addFeature(kX86CpuFeatureCmpXchg16B); if (regs.ecx & 0x00002000U) cpuInfo->addFeature(kX86CpuFeatureCMPXCHG16B);
if (regs.ecx & 0x00080000U) cpuInfo->addFeature(kX86CpuFeatureSse41); if (regs.ecx & 0x00080000U) cpuInfo->addFeature(kX86CpuFeatureSSE4_1);
if (regs.ecx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureSse42); if (regs.ecx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureSSE4_2);
if (regs.ecx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMovbe); if (regs.ecx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMOVBE);
if (regs.ecx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeaturePopcnt); if (regs.ecx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeaturePOPCNT);
if (regs.ecx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureAesni); if (regs.ecx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureAESNI);
if (regs.ecx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeatureRdrand); if (regs.ecx & 0x04000000U) cpuInfo->addFeature(kX86CpuFeatureXSave);
if (regs.ecx & 0x08000000U) cpuInfo->addFeature(kX86CpuFeatureXSaveOS);
if (regs.edx & 0x00000010U) cpuInfo->addFeature(kX86CpuFeatureRdtsc); if (regs.ecx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeatureRDRAND);
if (regs.edx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeatureCmpXchg8B);
if (regs.edx & 0x00008000U) cpuInfo->addFeature(kX86CpuFeatureCmov); if (regs.edx & 0x00000010U) cpuInfo->addFeature(kX86CpuFeatureRDTSC);
if (regs.edx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeatureMmx); if (regs.edx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeatureCMPXCHG8B);
if (regs.edx & 0x01000000U) cpuInfo->addFeature(kX86CpuFeatureFxsr); if (regs.edx & 0x00008000U) cpuInfo->addFeature(kX86CpuFeatureCMOV);
if (regs.edx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureSse).addFeature(kX86CpuFeatureMmxExt); if (regs.edx & 0x00080000U) cpuInfo->addFeature(kX86CpuFeatureCLFLUSH);
if (regs.edx & 0x04000000U) cpuInfo->addFeature(kX86CpuFeatureSse).addFeature(kX86CpuFeatureSse2); if (regs.edx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeatureMMX);
if (regs.edx & 0x10000000U) cpuInfo->addFeature(kX86CpuFeatureMultithreading); if (regs.edx & 0x01000000U) cpuInfo->addFeature(kX86CpuFeatureFXSR);
if (regs.edx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureSSE).addFeature(kX86CpuFeatureMMX2);
if (cpuInfo->_vendorId == kCpuVendorAmd && (regs.edx & 0x10000000U)) { if (regs.edx & 0x04000000U) cpuInfo->addFeature(kX86CpuFeatureSSE).addFeature(kX86CpuFeatureSSE2);
// AMD sets Multithreading to ON if it has more cores. if (regs.edx & 0x10000000U) cpuInfo->addFeature(kX86CpuFeatureMT);
if (cpuInfo->_hwThreadsCount == 1)
// AMD sets Multithreading to ON if it has two or more cores.
if (cpuInfo->_hwThreadsCount == 1 && cpuInfo->_vendorId == kCpuVendorAmd && (regs.edx & 0x10000000U)) {
cpuInfo->_hwThreadsCount = 2; cpuInfo->_hwThreadsCount = 2;
} }
// Detect AVX. // Get the content of XCR0 if supported by CPU and enabled by OS.
if (regs.ecx & 0x10000000U) { if ((regs.ecx & 0x0C000000U) == 0x0C000000U) {
cpuInfo->addFeature(kX86CpuFeatureAvx); callXGetBV(&xcr0, 0);
}
if (regs.ecx & 0x00000800U) cpuInfo->addFeature(kX86CpuFeatureXop); // Detect AVX+.
if (regs.ecx & 0x00004000U) cpuInfo->addFeature(kX86CpuFeatureFma3); if (regs.ecx & 0x10000000U) {
if (regs.ecx & 0x00010000U) cpuInfo->addFeature(kX86CpuFeatureFma4); // - XCR0[2:1] == 11b
if (regs.ecx & 0x20000000U) cpuInfo->addFeature(kX86CpuFeatureF16C); // XMM & YMM states are enabled by OS.
if ((xcr0.eax & 0x00000006U) == 0x00000006U) {
cpuInfo->addFeature(kX86CpuFeatureAVX);
if (regs.ecx & 0x00000800U) cpuInfo->addFeature(kX86CpuFeatureXOP);
if (regs.ecx & 0x00004000U) cpuInfo->addFeature(kX86CpuFeatureFMA3);
if (regs.ecx & 0x00010000U) cpuInfo->addFeature(kX86CpuFeatureFMA4);
if (regs.ecx & 0x20000000U) cpuInfo->addFeature(kX86CpuFeatureF16C);
}
}
} }
// --------------------------------------------------------------------------
// [CPUID EAX=0x7 ECX=0x0]
// --------------------------------------------------------------------------
// Detect new features if the processor supports CPUID-07. // Detect new features if the processor supports CPUID-07.
if (maxId >= 7) { if (maxBaseId >= 0x7) {
callCpuId(7, 0, &regs); callCpuId(&regs, 0x7);
if (regs.ebx & 0x00000001) cpuInfo->addFeature(kX86CpuFeatureFsGsBase); if (regs.ebx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureFSGSBase);
if (regs.ebx & 0x00000008) cpuInfo->addFeature(kX86CpuFeatureBmi); if (regs.ebx & 0x00000008U) cpuInfo->addFeature(kX86CpuFeatureBMI);
if (regs.ebx & 0x00000010) cpuInfo->addFeature(kX86CpuFeatureHle); if (regs.ebx & 0x00000010U) cpuInfo->addFeature(kX86CpuFeatureHLE);
if (regs.ebx & 0x00000100) cpuInfo->addFeature(kX86CpuFeatureBmi2); if (regs.ebx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeatureBMI2);
if (regs.ebx & 0x00000200) cpuInfo->addFeature(kX86CpuFeatureRepMovsbStosbExt); if (regs.ebx & 0x00000200U) cpuInfo->addFeature(kX86CpuFeatureMOVSBSTOSBOpt);
if (regs.ebx & 0x00000800) cpuInfo->addFeature(kX86CpuFeatureRtm); if (regs.ebx & 0x00000800U) cpuInfo->addFeature(kX86CpuFeatureRTM);
if (regs.ebx & 0x00004000U) maybeMPX = true;
// AVX2 depends on AVX. if (regs.ebx & 0x00040000U) cpuInfo->addFeature(kX86CpuFeatureRDSEED);
if (cpuInfo->hasFeature(kX86CpuFeatureAvx)) { if (regs.ebx & 0x00080000U) cpuInfo->addFeature(kX86CpuFeatureADX);
if (regs.ebx & 0x00000020) cpuInfo->addFeature(kX86CpuFeatureAvx2); if (regs.ebx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeatureCLFLUSHOpt);
if (regs.ebx & 0x20000000U) cpuInfo->addFeature(kX86CpuFeatureSHA);
if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeaturePREFETCHWT1);
// Detect AVX2.
if (cpuInfo->hasFeature(kX86CpuFeatureAVX)) {
if (regs.ebx & 0x00000020U) cpuInfo->addFeature(kX86CpuFeatureAVX2);
}
// Detect AVX-512+.
if (regs.ebx & 0x00010000U) {
// - XCR0[2:1] == 11b
// XMM & YMM states are enabled by OS.
// - XCR0[7:5] == 111b
// Upper 256-bit of ZMM0-XMM15 and ZMM16-ZMM31 state are enabled by OS.
if ((xcr0.eax & 0x00000076U) == 0x00000076U) {
cpuInfo->addFeature(kX86CpuFeatureAVX512F);
if (regs.ebx & 0x00020000U) cpuInfo->addFeature(kX86CpuFeatureAVX512DQ);
if (regs.ebx & 0x04000000U) cpuInfo->addFeature(kX86CpuFeatureAVX512PF);
if (regs.ebx & 0x08000000U) cpuInfo->addFeature(kX86CpuFeatureAVX512ER);
if (regs.ebx & 0x10000000U) cpuInfo->addFeature(kX86CpuFeatureAVX512CD);
if (regs.ebx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeatureAVX512BW);
if (regs.ebx & 0x80000000U) cpuInfo->addFeature(kX86CpuFeatureAVX512VL);
}
}
}
// --------------------------------------------------------------------------
// [CPUID EAX=0xD, ECX=0x0]
// --------------------------------------------------------------------------
if (maxBaseId >= 0xD && maybeMPX) {
callCpuId(&regs, 0xD);
// Both CPUID result and XCR0 has to be enabled to have support for MPX.
if (((regs.eax & xcr0.eax) & 0x00000018U) == 0x00000018U) {
cpuInfo->addFeature(kX86CpuFeatureMPX);
} }
} }
...@@ -250,28 +356,28 @@ void X86CpuUtil::detect(X86CpuInfo* cpuInfo) { ...@@ -250,28 +356,28 @@ void X86CpuUtil::detect(X86CpuInfo* cpuInfo) {
// Calling cpuid with 0x80000000 as the in argument gets the number of valid // Calling cpuid with 0x80000000 as the in argument gets the number of valid
// extended IDs. // extended IDs.
callCpuId(0x80000000, 0, &regs); callCpuId(&regs, 0x80000000);
uint32_t maxExtId = IntUtil::iMin<uint32_t>(regs.eax, 0x80000004); uint32_t maxExtId = IntUtil::iMin<uint32_t>(regs.eax, 0x80000004);
uint32_t* brand = reinterpret_cast<uint32_t*>(cpuInfo->_brandString); uint32_t* brand = reinterpret_cast<uint32_t*>(cpuInfo->_brandString);
for (i = 0x80000001; i <= maxExtId; i++) { for (i = 0x80000001; i <= maxExtId; i++) {
callCpuId(i, 0, &regs); callCpuId(&regs, i);
switch (i) { switch (i) {
case 0x80000001: case 0x80000001:
if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureLahfSahf); if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureLahfSahf);
if (regs.ecx & 0x00000020U) cpuInfo->addFeature(kX86CpuFeatureLzcnt); if (regs.ecx & 0x00000020U) cpuInfo->addFeature(kX86CpuFeatureLZCNT);
if (regs.ecx & 0x00000040U) cpuInfo->addFeature(kX86CpuFeatureSse4A); if (regs.ecx & 0x00000040U) cpuInfo->addFeature(kX86CpuFeatureSSE4A);
if (regs.ecx & 0x00000080U) cpuInfo->addFeature(kX86CpuFeatureMsse); if (regs.ecx & 0x00000080U) cpuInfo->addFeature(kX86CpuFeatureMSSE);
if (regs.ecx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeaturePrefetch); if (regs.ecx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeaturePREFETCH);
if (regs.edx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureExecuteDisableBit); if (regs.edx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureNX);
if (regs.edx & 0x00200000U) cpuInfo->addFeature(kX86CpuFeatureFfxsr); if (regs.edx & 0x00200000U) cpuInfo->addFeature(kX86CpuFeatureFXSROpt);
if (regs.edx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMmxExt); if (regs.edx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMMX2);
if (regs.edx & 0x08000000U) cpuInfo->addFeature(kX86CpuFeatureRdtscp); if (regs.edx & 0x08000000U) cpuInfo->addFeature(kX86CpuFeatureRDTSCP);
if (regs.edx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeature3dNowExt).addFeature(kX86CpuFeatureMmxExt); if (regs.edx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeature3DNOW2).addFeature(kX86CpuFeatureMMX2);
if (regs.edx & 0x80000000U) cpuInfo->addFeature(kX86CpuFeature3dNow); if (regs.edx & 0x80000000U) cpuInfo->addFeature(kX86CpuFeature3DNOW);
break; break;
case 0x80000002: case 0x80000002:
......
This diff is collapsed.
This diff is collapsed.
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