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

Merge pull request #806 from peastman/jit32

Updated to latest asmjit, which supports 32 bit mode
parents fabb38d1 01da1b51
......@@ -274,14 +274,12 @@ ELSE (ANDROID OR PNACL)
SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/libraries/sfmt/src/SFMT.cpp PROPERTIES COMPILE_FLAGS "-DHAVE_SSE2=1")
ENDIF(ANDROID OR PNACL)
IF (NOT (ANDROID OR PNACL))
IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
FILE(GLOB src_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*/*.cpp)
FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*.h)
SET(SOURCE_FILES ${SOURCE_FILES} ${src_files})
SET(SOURCE_INCLUDE_FILES ${SOURCE_INCLUDE_FILES} ${incl_files})
INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit")
SET(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DLEPTON_USE_JIT")
ENDIF (CMAKE_SIZEOF_VOID_P EQUAL 8)
FILE(GLOB src_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*/*.cpp)
FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*.h)
SET(SOURCE_FILES ${SOURCE_FILES} ${src_files})
SET(SOURCE_INCLUDE_FILES ${SOURCE_INCLUDE_FILES} ${incl_files})
INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit")
SET(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DLEPTON_USE_JIT")
ENDIF (NOT (ANDROID OR PNACL))
# If API wrappers are being generated, and add them to the build.
......
......@@ -4,12 +4,38 @@
// [License]
// Zlib - See LICENSE.md file in the package.
// [Dependencies - AsmJit]
#if !defined(_ASMJIT_BUILD_H)
#include "build.h"
#endif // !_ASMJIT_BUILD_H
// [Guard]
#if !defined(ASMJIT_API_SCOPE)
# define ASMJIT_API_SCOPE
#else
# error "AsmJit - Api-Scope is already active, previous scope not closed by apiend.h?"
#endif // ASMJIT_API_SCOPE
// ============================================================================
// [MSVC]
// [Override]
// ============================================================================
#if !defined(ASMJIT_CC_HAS_OVERRIDE) && !defined(override)
# define override
# define ASMJIT_UNDEF_OVERRIDE
#endif // !ASMJIT_CC_HAS_OVERRIDE && !override
// ============================================================================
// [NoExcept]
// ============================================================================
#if !defined(ASMJIT_CC_HAS_NOEXCEPT) && !defined(noexcept)
# define noexcept ASMJIT_NOEXCEPT
# define ASMJIT_UNDEF_NOEXCEPT
#endif // !ASMJIT_CC_HAS_NOEXCEPT && !noexcept
// ============================================================================
// [MSC]
// ============================================================================
#if defined(_MSC_VER)
......@@ -29,21 +55,30 @@
// Rename symbols.
# if !defined(vsnprintf)
# define ASMJIT_DEFINED_VSNPRINTF
# define ASMJIT_UNDEF_VSNPRINTF
# define vsnprintf _vsnprintf
# endif // !vsnprintf
# if !defined(snprintf)
# define ASMJIT_DEFINED_SNPRINTF
# define ASMJIT_UNDEF_SNPRINTF
# define snprintf _snprintf
# endif // !snprintf
#endif // _MSC_VER
// ============================================================================
// [GNUC]
// [CLang]
// ============================================================================
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunnamed-type-template-args"
#endif // __clang__
// ============================================================================
// [GCC]
// ============================================================================
#if defined(__GNUC__) && !defined(__clang__)
# if __GNUC__ >= 4 && !defined(__MINGW32__)
# pragma GCC visibility push(hidden)
# endif // __GNUC__ >= 4
# endif // GCC 4+
#endif // __GNUC__
......@@ -4,30 +4,64 @@
// [License]
// Zlib - See LICENSE.md file in the package.
// [Guard]
#if defined(ASMJIT_API_SCOPE)
# undef ASMJIT_API_SCOPE
#else
# error "AsmJit - Api-Scope not active, forgot to include apibegin.h?"
#endif // ASMJIT_API_SCOPE
// ============================================================================
// [Override]
// ============================================================================
#if defined(ASMJIT_UNDEF_OVERRIDE)
# undef override
# undef ASMJIT_UNDEF_OVERRIDE
#endif // ASMJIT_UNDEF_OVERRIDE
// ============================================================================
// [NoExcept]
// ============================================================================
#if defined(ASMJIT_UNDEF_NOEXCEPT)
# undef noexcept
# undef ASMJIT_UNDEF_NOEXCEPT
#endif // ASMJIT_UNDEF_NOEXCEPT
// ============================================================================
// [MSVC]
// [MSC]
// ============================================================================
#if defined(_MSC_VER)
// Pop disabled warnings by ApiBegin.h
# pragma warning(pop)
// Rename symbols back.
# if defined(ASMJIT_DEFINED_VSNPRINTF)
# undef ASMJIT_DEFINED_VSNPRINTF
# if defined(ASMJIT_UNDEF_VSNPRINTF)
# undef vsnprintf
# endif // ASMJIT_DEFINED_VSNPRINTF
# if defined(ASMJIT_DEFINED_SNPRINTF)
# undef ASMJIT_DEFINED_SNPRINTF
# undef ASMJIT_UNDEF_VSNPRINTF
# endif // ASMJIT_UNDEF_VSNPRINTF
# if defined(ASMJIT_UNDEF_SNPRINTF)
# undef snprintf
# endif // ASMJIT_DEFINED_SNPRINTF
# undef ASMJIT_UNDEF_SNPRINTF
# endif // ASMJIT_UNDEF_SNPRINTF
#endif // _MSC_VER
// ============================================================================
// [GNUC]
// [CLang]
// ============================================================================
#if defined(__clang__)
# pragma clang diagnostic pop
#endif // __clang__
// ============================================================================
// [GCC]
// ============================================================================
#if defined(__GNUC__) && !defined(__clang__)
# if __GNUC__ >= 4 && !defined(__MINGW32__)
# pragma GCC visibility pop
# endif // __GNUC__ >= 4
# endif // GCC 4+
#endif // __GNUC__
......@@ -235,15 +235,15 @@
//! `BaseMem` class. These functions are used to make operands that represents
//! memory addresses:
//!
//! - `asmjit::ptr()`
//! - `asmjit::byte_ptr()`
//! - `asmjit::word_ptr()`
//! - `asmjit::dword_ptr()`
//! - `asmjit::qword_ptr()`
//! - `asmjit::tword_ptr()`
//! - `asmjit::oword_ptr()`
//! - `asmjit::yword_ptr()`
//! - `asmjit::zword_ptr()`
//! - `asmjit::ptr()` - Address size not specified.
//! - `asmjit::byte_ptr()` - 1 byte.
//! - `asmjit::word_ptr()` - 2 bytes (Gpw size).
//! - `asmjit::dword_ptr()` - 4 bytes (Gpd size).
//! - `asmjit::qword_ptr()` - 8 bytes (Gpq/Mm size).
//! - `asmjit::tword_ptr()` - 10 bytes (FPU).
//! - `asmjit::oword_ptr()` - 16 bytes (Xmm size).
//! - `asmjit::yword_ptr()` - 32 bytes (Ymm size).
//! - `asmjit::zword_ptr()` - 64 bytes (Zmm size).
//!
//! Most useful function to make pointer should be `asmjit::ptr()`. It creates
//! pointer to the target with unspecified size. Unspecified size works in all
......@@ -298,10 +298,10 @@
//! // Get `X86CpuInfo` global instance.
//! const X86CpuInfo* cpuInfo = X86CpuInfo::getHost();
//!
//! if (cpuInfo->hasFeature(kX86CpuFeatureSse2)) {
//! if (cpuInfo->hasFeature(kX86CpuFeatureSSE2)) {
//! // Processor has SSE2.
//! }
//! else if (cpuInfo->hasFeature(kX86CpuFeatureMmx)) {
//! else if (cpuInfo->hasFeature(kX86CpuFeatureMMX)) {
//! // Processor doesn't have SSE2, but has MMX.
//! }
//! else {
......
......@@ -340,43 +340,35 @@ Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const
}
Error Assembler::emit(uint32_t code, int o0) {
Imm imm(o0);
return _emit(code, imm, NA, NA, NA);
return _emit(code, Imm(o0), NA, NA, NA);
}
Error Assembler::emit(uint32_t code, uint64_t o0) {
Imm imm(o0);
return _emit(code, imm, NA, NA, NA);
Error Assembler::emit(uint32_t code, const Operand& o0, int o1) {
return _emit(code, o0, Imm(o1), NA, NA);
}
Error Assembler::emit(uint32_t code, const Operand& o0, int o1) {
Imm imm(o1);
return _emit(code, o0, imm, NA, NA);
Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, int o2) {
return _emit(code, o0, o1, Imm(o2), NA);
}
Error Assembler::emit(uint32_t code, const Operand& o0, uint64_t o1) {
Imm imm(o1);
return _emit(code, o0, imm, NA, NA);
Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3) {
return _emit(code, o0, o1, o2, Imm(o3));
}
Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, int o2) {
Imm imm(o2);
return _emit(code, o0, o1, imm, NA);
Error Assembler::emit(uint32_t code, int64_t o0) {
return _emit(code, Imm(o0), NA, NA, NA);
}
Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2) {
Imm imm(o2);
return _emit(code, o0, o1, imm, NA);
Error Assembler::emit(uint32_t code, const Operand& o0, int64_t o1) {
return _emit(code, o0, Imm(o1), NA, NA);
}
Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3) {
Imm imm(o3);
return _emit(code, o0, o1, o2, imm);
Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, int64_t o2) {
return _emit(code, o0, o1, Imm(o2), NA);
}
Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3) {
Imm imm(o3);
return _emit(code, o0, o1, o2, imm);
Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int64_t o3) {
return _emit(code, o0, o1, o2, Imm(o3));
}
#undef NA
......
......@@ -26,23 +26,23 @@ namespace asmjit {
//! \{
// ============================================================================
// [asmjit::kInstId]
// [asmjit::InstId]
// ============================================================================
//! Instruction codes (stub).
ASMJIT_ENUM(kInstId) {
ASMJIT_ENUM(InstId) {
//! No instruction.
kInstIdNone = 0
};
// ============================================================================
// [asmjit::kInstOptions]
// [asmjit::InstOptions]
// ============================================================================
//! Instruction options (stub).
ASMJIT_ENUM(kInstOptions) {
//! Instruction options.
ASMJIT_ENUM(InstOptions) {
//! No instruction options.
kInstOptionNone = 0x00,
kInstOptionNone = 0x00000000,
//! Emit short form of the instruction.
//!
......@@ -53,7 +53,8 @@ ASMJIT_ENUM(kInstOptions) {
//! can be dangerous if the short jmp/jcc is required, but not encodable due
//! to large displacement, in such case an error happens and the whole
//! assembler/compiler stream is unusable.
kInstOptionShortForm = 0x01,
kInstOptionShortForm = 0x00000001,
//! Emit long form of the instruction.
//!
//! X86/X64:
......@@ -61,12 +62,13 @@ ASMJIT_ENUM(kInstOptions) {
//! Long form is mosrlt related to jmp and jcc instructions, but like the
//! `kInstOptionShortForm` option it can be used by other instructions
//! supporting both 8-bit and 32-bit immediates.
kInstOptionLongForm = 0x02,
kInstOptionLongForm = 0x00000002,
//! Condition is likely to be taken.
kInstOptionTaken = 0x04,
kInstOptionTaken = 0x00000004,
//! Condition is unlikely to be taken.
kInstOptionNotTaken = 0x08
kInstOptionNotTaken = 0x00000008
};
// ============================================================================
......@@ -474,19 +476,20 @@ struct ASMJIT_VCLASS Assembler : public CodeGen {
//! Emit an instruction with integer immediate operand.
ASMJIT_API Error emit(uint32_t code, int o0);
//! \overload
ASMJIT_API Error emit(uint32_t code, uint64_t o0);
//! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0, int o1);
//! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0, uint64_t o1);
//! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, int o2);
//! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2);
//! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3);
//! \overload
ASMJIT_API Error emit(uint32_t code, int64_t o0);
//! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0, int64_t o1);
//! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, int64_t o2);
//! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3);
ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int64_t o3);
//! Emit an instruction (virtual).
virtual Error _emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) = 0;
......
......@@ -23,11 +23,11 @@ namespace asmjit {
//! \{
// ============================================================================
// [asmjit::kCodeGen]
// [asmjit::CodeGenFeatures]
// ============================================================================
//! Features of \ref CodeGen.
ASMJIT_ENUM(kCodeGen) {
ASMJIT_ENUM(CodeGenFeatures) {
//! Emit optimized code-alignment sequences (`Assembler` and `Compiler`).
//!
//! Default `true`.
......@@ -80,11 +80,11 @@ ASMJIT_ENUM(kCodeGen) {
};
// ============================================================================
// [asmjit::kAlignMode]
// [asmjit::AlignMode]
// ============================================================================
//! Code aligning mode.
ASMJIT_ENUM(kAlignMode) {
ASMJIT_ENUM(AlignMode) {
//! Align by emitting a sequence that can be executed (code).
kAlignCode = 0,
//! Align by emitting sequence that shouldn't be executed (data).
......@@ -92,11 +92,11 @@ ASMJIT_ENUM(kAlignMode) {
};
// ============================================================================
// [asmjit::kRelocMode]
// [asmjit::RelocMode]
// ============================================================================
//! Relocation mode.
ASMJIT_ENUM(kRelocMode) {
ASMJIT_ENUM(RelocMode) {
//! Relocate an absolute address to an absolute address.
kRelocAbsToAbs = 0,
//! Relocate a relative address to an absolute address.
......
......@@ -40,11 +40,11 @@ enum { kBaseCompilerDefaultLookAhead = 64 };
Compiler::Compiler(Runtime* runtime) :
CodeGen(runtime),
_assembler(NULL),
_nodeFlowId(0),
_nodeFlags(0),
_maxLookAhead(kBaseCompilerDefaultLookAhead),
_targetVarMapping(NULL),
_assembler(NULL),
_firstNode(NULL),
_lastNode(NULL),
_cursor(NULL),
......@@ -482,7 +482,7 @@ VarData* Compiler::_newVd(uint32_t type, uint32_t size, uint32_t c, const char*
vd->_flags = 0;
vd->_priority = 10;
vd->_state = kVarStateUnused;
vd->_state = kVarStateNone;
vd->_regIndex = kInvalidReg;
vd->_isStack = false;
vd->_isMemArg = false;
......
......@@ -43,14 +43,14 @@ struct InstNode;
struct JumpNode;
// ============================================================================
// [asmjit::kConstScope]
// [asmjit::ConstScope]
// ============================================================================
//! \addtogroup asmjit_base_compiler
//! \{
//! Scope of the constant.
ASMJIT_ENUM(kConstScope) {
ASMJIT_ENUM(ConstScope) {
//! Local constant, always embedded right after the current function.
kConstScopeLocal = 0,
//! Global constant, embedded at the end of the currently compiled code.
......@@ -58,10 +58,10 @@ ASMJIT_ENUM(kConstScope) {
};
// ============================================================================
// [asmjit::kVarType]
// [asmjit::VarType]
// ============================================================================
ASMJIT_ENUM(kVarType) {
ASMJIT_ENUM(VarType) {
//! Variable is 8-bit signed integer.
kVarTypeInt8 = 0,
//! Variable is 8-bit unsigned integer.
......@@ -101,13 +101,13 @@ ASMJIT_ENUM(kVarType) {
};
// ============================================================================
// [asmjit::kVarFlags]
// [asmjit::VarFlags]
// ============================================================================
//! \internal
//!
//! X86/X64 variable flags.
ASMJIT_ENUM(kVarFlags) {
ASMJIT_ENUM(VarFlags) {
//! Variable contains single-precision floating-point(s).
kVarFlagSp = 0x10,
//! Variable contains double-precision floating-point(s).
......@@ -117,11 +117,11 @@ ASMJIT_ENUM(kVarFlags) {
};
// ============================================================================
// [asmjit::kVarAttrFlags]
// [asmjit::VarAttrFlags]
// ============================================================================
//! Variable attribute flags.
ASMJIT_ENUM(kVarAttrFlags) {
ASMJIT_ENUM(VarAttrFlags) {
//! Variable is accessed through register on input.
kVarAttrInReg = 0x00000001,
//! Variable is accessed through register on output.
......@@ -188,13 +188,13 @@ ASMJIT_ENUM(kVarAttrFlags) {
};
// ============================================================================
// [asmjit::kVarHint]
// [asmjit::VarHint]
// ============================================================================
//! Variable hint (used by `Compiler)`.
//!
//! \sa Compiler.
ASMJIT_ENUM(kVarHint) {
ASMJIT_ENUM(VarHint) {
//! Alloc variable.
kVarHintAlloc = 0,
//! Spill variable.
......@@ -211,35 +211,29 @@ ASMJIT_ENUM(kVarHint) {
// [asmjit::kVarState]
// ============================================================================
// TODO: Rename `kVarState` or `VarState`.
//! State of variable.
//!
//! \note State of variable is used only during make process and it's not
//! visible to the developer.
//! \note Variable states are used only during register allocation.
ASMJIT_ENUM(kVarState) {
//! Variable is currently not used.
kVarStateUnused = 0,
//! Variable is in register.
//!
kVarStateNone = 0,
//! Variable is currently allocated in register.
kVarStateReg = 1,
//! Variable is in memory location or spilled.
//!
//! Variable was spilled from register to memory or variable is used for
//! memory only storage.
//! Variable is currently allocated in memory (or has been spilled).
kVarStateMem = 2
};
// ============================================================================
// [asmjit::kFuncConv]
// [asmjit::FuncConv]
// ============================================================================
//! Function calling convention.
//!
//! For a platform specific calling conventions, see:
//! - `kX86FuncConv` - X86/X64 calling conventions.
ASMJIT_ENUM(kFuncConv) {
//! - `X86FuncConv` - X86/X64 calling conventions.
ASMJIT_ENUM(FuncConv) {
//! Calling convention is invalid (can't be used).
kFuncConvNone = 0,
......@@ -267,14 +261,14 @@ ASMJIT_ENUM(kFuncConv) {
};
// ============================================================================
// [asmjit::kFuncHint]
// [asmjit::FuncHint]
// ============================================================================
//! Function hints.
//!
//! For a platform specific calling conventions, see:
//! - `kX86FuncHint` - X86/X64 function hints.
ASMJIT_ENUM(kFuncHint) {
//! - `X86FuncHint` - X86/X64 function hints.
ASMJIT_ENUM(FuncHint) {
//! Make a naked function (default true).
//!
//! Naked function is function without using standard prolog/epilog sequence).
......@@ -325,14 +319,14 @@ ASMJIT_ENUM(kFuncHint) {
};
// ============================================================================
// [asmjit::kFuncFlags]
// [asmjit::FuncFlags]
// ============================================================================
//! Function flags.
//!
//! For a platform specific calling conventions, see:
//! - `kX86FuncFlags` - X86/X64 function flags.
ASMJIT_ENUM(kFuncFlags) {
//! - `X86FuncFlags` - X86/X64 function flags.
ASMJIT_ENUM(FuncFlags) {
//! Whether the function is using naked (minimal) prolog / epilog.
kFuncFlagIsNaked = 0x00000001,
......@@ -360,11 +354,11 @@ ASMJIT_ENUM(kFuncFlags) {
};
// ============================================================================
// [asmjit::kFuncDir]
// [asmjit::FuncDir]
// ============================================================================
//! Function arguments direction.
ASMJIT_ENUM(kFuncDir) {
ASMJIT_ENUM(FuncDir) {
//! Arguments are passed left to right.
//!
//! This arguments direction is unusual in C, however it's used in Pascal.
......@@ -377,11 +371,11 @@ ASMJIT_ENUM(kFuncDir) {
};
// ============================================================================
// [asmjit::kFuncArg]
// [asmjit::FuncArgIndex]
// ============================================================================
//! Function argument (lo/hi) specification.
ASMJIT_ENUM(kFuncArg) {
//! Function argument index (lo/hi).
ASMJIT_ENUM(FuncArgIndex) {
//! Maxumum number of function arguments supported by AsmJit.
kFuncArgCount = 16,
//! Extended maximum number of arguments (used internally).
......@@ -401,11 +395,11 @@ ASMJIT_ENUM(kFuncArg) {
};
// ============================================================================
// [asmjit::kFuncRet]
// [asmjit::FuncRet]
// ============================================================================
//! Function return value (lo/hi) specification.
ASMJIT_ENUM(kFuncRet) {
ASMJIT_ENUM(FuncRet) {
//! Index to the LO part of function return value.
kFuncRetLo = 0,
//! Index to the HI part of function return value.
......@@ -416,17 +410,17 @@ ASMJIT_ENUM(kFuncRet) {
// [asmjit::kFuncStackInvalid]
// ============================================================================
enum kFuncMisc {
enum {
//! Invalid stack offset in function or function parameter.
kFuncStackInvalid = -1
};
// ============================================================================
// [asmjit::kNodeType]
// [asmjit::NodeType]
// ============================================================================
//! Type of node, see \ref Node.
ASMJIT_ENUM(kNodeType) {
ASMJIT_ENUM(NodeType) {
//! Invalid node (internal, can't be used).
kNodeTypeNone = 0,
//! Node is an .align directive, see \ref AlignNode.
......@@ -454,10 +448,10 @@ ASMJIT_ENUM(kNodeType) {
};
// ============================================================================
// [asmjit::kNodeFlags]
// [asmjit::NodeFlags]
// ============================================================================
ASMJIT_ENUM(kNodeFlags) {
ASMJIT_ENUM(NodeFlags) {
//! Whether the node has been translated, thus contains only registers.
kNodeFlagIsTranslated = 0x0001,
......@@ -558,6 +552,12 @@ struct Var : public Operand {
return Var(*this);
}
//! Reset Var operand.
ASMJIT_INLINE void reset() {
_init_packed_op_sz_b0_b1_id(kOperandTypeVar, 0, kInvalidReg, kInvalidReg, kInvalidValue);
_init_packed_d2_d3(kInvalidValue, kInvalidValue);
}
//! Get whether the variable has been initialized by `Compiler`.
ASMJIT_INLINE bool isInitialized() const {
return _vreg.id != kInvalidValue;
......@@ -987,11 +987,11 @@ struct VarAttr {
//! Get whether `flag` is on.
ASMJIT_INLINE bool hasFlag(uint32_t flag) { return (_flags & flag) != 0; }
//! Add `flags`.
ASMJIT_INLINE void addFlags(uint32_t flags) { _flags |= flags; }
ASMJIT_INLINE void orFlags(uint32_t flags) { _flags |= flags; }
//! Mask `flags`.
ASMJIT_INLINE void andFlags(uint32_t flags) { _flags &= flags; }
//! Clear `flags`.
ASMJIT_INLINE void delFlags(uint32_t flags) { _flags &= ~flags; }
ASMJIT_INLINE void andNotFlags(uint32_t flags) { _flags &= ~flags; }
//! Get how many times the variable is used by the instruction/node.
ASMJIT_INLINE uint32_t getVarCount() const { return _varCount; }
......@@ -1174,7 +1174,7 @@ struct DoubleType {};
#if !defined(ASMJIT_DOCGEN)
template<typename T>
struct TypeId {
enum { kId = static_cast<int>(::asmjit::kInvalidVar) };
// Left empty to report any type, which is not known to asmjit.
};
template<typename T>
......@@ -1186,38 +1186,30 @@ struct TypeId<T*> {
template<> \
struct TypeId<_T_> { enum { kId = _Id_ }; }
ASMJIT_TYPE_ID(void, kInvalidVar);
ASMJIT_TYPE_ID(Void, kInvalidVar);
ASMJIT_TYPE_ID(int8_t, kVarTypeInt8);
ASMJIT_TYPE_ID(Int8Type, kVarTypeInt8);
ASMJIT_TYPE_ID(uint8_t, kVarTypeUInt8);
ASMJIT_TYPE_ID(UInt8Type, kVarTypeUInt8);
ASMJIT_TYPE_ID(int16_t, kVarTypeInt16);
ASMJIT_TYPE_ID(Int16Type, kVarTypeInt16);
ASMJIT_TYPE_ID(uint16_t, kVarTypeUInt8);
ASMJIT_TYPE_ID(UInt16Type, kVarTypeUInt8);
ASMJIT_TYPE_ID(int32_t, kVarTypeInt32);
ASMJIT_TYPE_ID(Int32Type, kVarTypeUInt8);
ASMJIT_TYPE_ID(uint32_t, kVarTypeUInt32);
ASMJIT_TYPE_ID(UInt32Type, kVarTypeUInt8);
ASMJIT_TYPE_ID(int64_t, kVarTypeInt64);
ASMJIT_TYPE_ID(Int64Type, kVarTypeUInt8);
ASMJIT_TYPE_ID(uint64_t, kVarTypeUInt64);
ASMJIT_TYPE_ID(UInt64Type, kVarTypeUInt8);
ASMJIT_TYPE_ID(float, kVarTypeFp32);
ASMJIT_TYPE_ID(FloatType, kVarTypeFp32);
ASMJIT_TYPE_ID(double, kVarTypeFp64);
ASMJIT_TYPE_ID(DoubleType, kVarTypeFp64);
ASMJIT_TYPE_ID(void , kInvalidVar);
ASMJIT_TYPE_ID(char , IntTraits<char>::kIsSigned ? kVarTypeInt8 : kVarTypeUInt8);
ASMJIT_TYPE_ID(signed char , kVarTypeInt8);
ASMJIT_TYPE_ID(unsigned char, kVarTypeUInt8);
ASMJIT_TYPE_ID(int16_t , kVarTypeInt16);
ASMJIT_TYPE_ID(uint16_t , kVarTypeUInt16);
ASMJIT_TYPE_ID(int32_t , kVarTypeInt32);
ASMJIT_TYPE_ID(uint32_t , kVarTypeUInt32);
ASMJIT_TYPE_ID(int64_t , kVarTypeInt64);
ASMJIT_TYPE_ID(uint64_t , kVarTypeUInt64);
ASMJIT_TYPE_ID(float , kVarTypeFp32);
ASMJIT_TYPE_ID(double , kVarTypeFp64);
ASMJIT_TYPE_ID(Void , kInvalidVar);
ASMJIT_TYPE_ID(Int8Type , kVarTypeInt8);
ASMJIT_TYPE_ID(UInt8Type , kVarTypeUInt8);
ASMJIT_TYPE_ID(Int16Type , kVarTypeInt16);
ASMJIT_TYPE_ID(UInt16Type , kVarTypeUInt16);
ASMJIT_TYPE_ID(Int32Type , kVarTypeUInt32);
ASMJIT_TYPE_ID(UInt32Type , kVarTypeUInt32);
ASMJIT_TYPE_ID(Int64Type , kVarTypeUInt64);
ASMJIT_TYPE_ID(UInt64Type , kVarTypeUInt64);
ASMJIT_TYPE_ID(FloatType , kVarTypeFp32);
ASMJIT_TYPE_ID(DoubleType , kVarTypeFp64);
#endif // !ASMJIT_DOCGEN
// ============================================================================
......@@ -1256,7 +1248,7 @@ struct FuncInOut {
union {
struct {
//! Variable type, see `kVarType`.
//! Variable type, see `VarType`.
uint8_t _varType;
//! Register index if argument / return value is a register.
uint8_t _regIndex;
......@@ -1482,7 +1474,7 @@ struct FuncDecl {
// [Accessors - Calling Convention]
// --------------------------------------------------------------------------
//! Get function calling convention, see `kFuncConv`.
//! Get function calling convention, see `FuncConv`.
ASMJIT_INLINE uint32_t getConvention() const { return _convention; }
//! Get whether the callee pops the stack.
......@@ -1550,7 +1542,7 @@ struct FuncDecl {
uint8_t _convention;
//! Whether a callee pops stack.
uint8_t _calleePopsStack : 1;
//! Direction for arguments passed on the stack, see `kFuncDir`.
//! Direction for arguments passed on the stack, see `FuncDir`.
uint8_t _direction : 1;
//! Reserved #0 (alignment).
uint8_t _reserved0 : 6;
......@@ -1636,7 +1628,7 @@ struct Node {
// [Accessors - Type and Flags]
// --------------------------------------------------------------------------
//! Get type of node, see `kNodeType`.
//! Get node type, see `NodeType`.
ASMJIT_INLINE uint32_t getType() const {
return _type;
}
......@@ -1646,24 +1638,29 @@ struct Node {
return _flags;
}
//! Set node flags to `flags`.
ASMJIT_INLINE void setFlags(uint32_t flags) {
_flags = static_cast<uint16_t>(flags);
}
//! Get whether the instruction has flag `flag`.
ASMJIT_INLINE bool hasFlag(uint32_t flag) const {
return (static_cast<uint32_t>(_flags) & flag) != 0;
}
//! Set node flags to `flags`.
ASMJIT_INLINE void setFlags(uint32_t flags) {
_flags = static_cast<uint16_t>(flags);
}
//! Add instruction `flags`.
ASMJIT_INLINE void addFlags(uint32_t flags) {
ASMJIT_INLINE void orFlags(uint32_t flags) {
_flags |= static_cast<uint16_t>(flags);
}
//! And instruction `flags`.
ASMJIT_INLINE void andFlags(uint32_t flags) {
_flags &= static_cast<uint16_t>(flags);
}
//! Clear instruction `flags`.
ASMJIT_INLINE void delFlags(uint32_t flags) {
_flags &= static_cast<uint16_t>(~flags);
ASMJIT_INLINE void andNotFlags(uint32_t flags) {
_flags &= ~static_cast<uint16_t>(flags);
}
//! Get whether the node has beed fetched.
......@@ -1689,18 +1686,18 @@ struct Node {
return hasFlag(kNodeFlagIsInformative);
}
//! Whether the instruction is an unconditional jump.
//! Whether the node is `InstNode` and unconditional jump.
ASMJIT_INLINE bool isJmp() const { return hasFlag(kNodeFlagIsJmp); }
//! Whether the instruction is a conditional jump.
//! Whether the node is `InstNode` and conditional jump.
ASMJIT_INLINE bool isJcc() const { return hasFlag(kNodeFlagIsJcc); }
//! Whether the instruction is an unconditional or conditional jump.
//! Whether the node is `InstNode` and conditional/unconditional jump.
ASMJIT_INLINE bool isJmpOrJcc() const { return hasFlag(kNodeFlagIsJmp | kNodeFlagIsJcc); }
//! Whether the instruction is a return.
//! Whether the node is `InstNode` and return.
ASMJIT_INLINE bool isRet() const { return hasFlag(kNodeFlagIsRet); }
//! Get whether the instruction is special.
//! Get whether the node is `InstNode` and the instruction is special.
ASMJIT_INLINE bool isSpecial() const { return hasFlag(kNodeFlagIsSpecial); }
//! Get whether the instruction accesses FPU.
//! Get whether the node is `InstNode` and the instruction uses x87-FPU.
ASMJIT_INLINE bool isFp() const { return hasFlag(kNodeFlagIsFp); }
// --------------------------------------------------------------------------
......@@ -1785,7 +1782,7 @@ struct Node {
//! Next node.
Node* _next;
//! Node type, see `kNodeType`.
//! Node type, see `NodeType`.
uint8_t _type;
//! Operands count (if the node has operands, otherwise zero).
uint8_t _opCount;
......@@ -1863,7 +1860,7 @@ struct AlignNode : public Node {
// [Members]
// --------------------------------------------------------------------------
//! Alignment mode, see \ref kAlignMode.
//! Alignment mode, see \ref AlignMode.
uint32_t _mode;
//! Alignment offset in bytes.
uint32_t _offset;
......@@ -1891,7 +1888,9 @@ struct EmbedNode : public Node {
// --------------------------------------------------------------------------
//! Create a new `EmbedNode` instance.
ASMJIT_INLINE EmbedNode(Compiler* compiler, void* data, uint32_t size) : Node(compiler, kNodeTypeEmbed) {
ASMJIT_INLINE EmbedNode(Compiler* compiler, void* data, uint32_t size) :
Node(compiler, kNodeTypeEmbed) {
_size = size;
if (size <= kInlineBufferSize) {
if (data != NULL)
......@@ -1947,7 +1946,7 @@ struct CommentNode : public Node {
//! Create a new `CommentNode` instance.
ASMJIT_INLINE CommentNode(Compiler* compiler, const char* comment) : Node(compiler, kNodeTypeComment) {
addFlags(kNodeFlagIsInformative);
orFlags(kNodeFlagIsInformative);
_comment = comment;
}
......@@ -1968,8 +1967,10 @@ struct HintNode : public Node {
// --------------------------------------------------------------------------
//! Create a new `HintNode` instance.
ASMJIT_INLINE HintNode(Compiler* compiler, VarData* vd, uint32_t hint, uint32_t value) : Node(compiler, kNodeTypeHint) {
addFlags(kNodeFlagIsInformative);
ASMJIT_INLINE HintNode(Compiler* compiler, VarData* vd, uint32_t hint, uint32_t value) :
Node(compiler, kNodeTypeHint) {
orFlags(kNodeFlagIsInformative);
_vd = vd;
_hint = hint;
_value = value;
......@@ -2095,9 +2096,12 @@ struct InstNode : public Node {
// --------------------------------------------------------------------------
//! Create a new `InstNode` instance.
ASMJIT_INLINE InstNode(Compiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) : Node(compiler, kNodeTypeInst) {
_code = static_cast<uint16_t>(code);
_options = static_cast<uint8_t>(options);
ASMJIT_INLINE InstNode(Compiler* compiler, uint32_t instId, uint32_t instOptions, Operand* opList, uint32_t opCount) :
Node(compiler, kNodeTypeInst) {
_instId = static_cast<uint16_t>(instId);
_reserved = 0;
_instOptions = instOptions;
_opCount = static_cast<uint8_t>(opCount);
_opList = opList;
......@@ -2112,18 +2116,17 @@ struct InstNode : public Node {
// [Accessors]
// --------------------------------------------------------------------------
//! Get instruction code, see `kX86InstId`.
ASMJIT_INLINE uint32_t getCode() const {
return _code;
//! Get instruction ID, see `X86InstId`.
ASMJIT_INLINE uint32_t getInstId() const {
return _instId;
}
//! Set instruction code to `code`.
//! Set instruction ID to `instId`.
//!
//! Please do not modify instruction code if you are not know what you are
//! doing. Incorrect instruction code or operands can raise assertion() at
//! runtime.
ASMJIT_INLINE void setCode(uint32_t code) {
_code = static_cast<uint16_t>(code);
//! Please do not modify instruction code if you don't know what are you
//! doing. Incorrect instruction code or operands can cause assertion failure.
ASMJIT_INLINE void setInstId(uint32_t instId) {
_instId = static_cast<uint16_t>(instId);
}
//! Whether the instruction is an unconditional jump or whether the
......@@ -2134,23 +2137,23 @@ struct InstNode : public Node {
//! Get emit options.
ASMJIT_INLINE uint32_t getOptions() const {
return _options;
return _instOptions;
}
//! Set emit options.
ASMJIT_INLINE void setOptions(uint32_t options) {
_options = static_cast<uint8_t>(options);
_instOptions = options;
}
//! Add emit options.
ASMJIT_INLINE void addOptions(uint32_t options) {
_options |= static_cast<uint8_t>(options);
_instOptions |= options;
}
//! Mask emit options.
ASMJIT_INLINE void andOptions(uint32_t options) {
_options &= static_cast<uint8_t>(options);
_instOptions &= options;
}
//! Clear emit options.
ASMJIT_INLINE void delOptions(uint32_t options) {
_options &= static_cast<uint8_t>(~options);
_instOptions &= ~options;
}
//! Get operands list.
......@@ -2219,12 +2222,14 @@ _Update:
// [Members]
// --------------------------------------------------------------------------
//! Instruction code, see `kInstId`.
uint16_t _code;
//! Instruction options, see `kInstOptions`.
uint8_t _options;
//! Instruction ID, see `InstId`.
uint16_t _instId;
//! \internal
uint8_t _memOpIndex;
//! \internal
uint8_t _reserved;
//! Instruction options, see `InstOptions`.
uint32_t _instOptions;
//! Operands list.
Operand* _opList;
......@@ -2468,7 +2473,7 @@ struct FuncNode : public Node {
//! The "Red Zone" size - count of bytes which might be accessed without
//! adjusting the stack pointer.
uint16_t _redZoneSize;
//! Spill zone size (zone used by WIN64ABI).
//! Spill zone size (used by WIN64 ABI).
uint16_t _spillZoneSize;
//! Stack size needed for function arguments.
......@@ -2954,15 +2959,51 @@ struct ASMJIT_VCLASS Compiler : public CodeGen {
ASMJIT_API void alloc(Var& var);
//! Alloc variable `var` using `regIndex` as a register index.
ASMJIT_API void alloc(Var& var, uint32_t regIndex);
//! Alloc variable `var` using `reg` as a demanded register.
//! Alloc variable `var` using `reg` as a register operand.
ASMJIT_API void alloc(Var& var, const Reg& reg);
//! Spill variable `var`.
ASMJIT_API void spill(Var& var);
//! Save variable `var` if modified.
//! Save variable `var` if the status is `modified` at this point.
ASMJIT_API void save(Var& var);
//! Unuse variable `var`.
ASMJIT_API void unuse(Var& var);
//! Alloc variable `var` (if initialized), but only if it's initialized.
ASMJIT_INLINE void allocUnsafe(Var& var) {
if (var.isInitialized())
alloc(var);
}
//! Alloc variable `var` (if initialized) using `regIndex` as a register index
ASMJIT_INLINE void allocUnsafe(Var& var, uint32_t regIndex) {
if (var.isInitialized())
alloc(var, regIndex);
}
//! Alloc variable `var` (if initialized) using `reg` as a register operand.
ASMJIT_INLINE void allocUnsafe(Var& var, const Reg& reg) {
if (var.isInitialized())
alloc(var, reg);
}
//! Spill variable `var` (if initialized).
ASMJIT_INLINE void spillUnsafe(Var& var) {
if (var.isInitialized())
spill(var);
}
//! Save variable `var` (if initialized) if the status is `modified` at this point.
ASMJIT_INLINE void saveUnsafe(Var& var) {
if (var.isInitialized())
save(var);
}
//! Unuse variable `var` (if initialized).
ASMJIT_INLINE void unuseUnsafe(Var& var) {
if (var.isInitialized())
unuse(var);
}
//! Get priority of variable `var`.
ASMJIT_API uint32_t getPriority(Var& var) const;
//! Set priority of variable `var` to `priority`.
......@@ -3035,7 +3076,7 @@ struct ASMJIT_VCLASS Compiler : public CodeGen {
//! registers.
uint32_t _maxLookAhead;
//! Variable mapping (translates incoming kVarType into target).
//! Variable mapping (translates incoming VarType into target).
const uint8_t* _targetVarMapping;
//! First node.
......
......@@ -162,19 +162,6 @@ void ConstPool::reset() {
// [asmjit::ConstPool - Ops]
// ============================================================================
static ASMJIT_INLINE size_t ConstPool_getGapIndex(size_t size) {
if (size <= 1)
return ConstPool::kIndex1;
else if (size <= 3)
return ConstPool::kIndex2;
else if (size <= 7)
return ConstPool::kIndex4;
else if (size <= 15)
return ConstPool::kIndex8;
else
return ConstPool::kIndex16;
}
static ASMJIT_INLINE ConstPoolGap* ConstPool_allocGap(ConstPool* self) {
ConstPoolGap* gap = self->_gapPool;
if (gap == NULL)
......@@ -396,7 +383,7 @@ UNIT(base_constpool) {
EXPECT(prevOffset + 8 == curOffset,
"pool.add() - Returned incorrect curOffset.");
EXPECT(pool.getSize() == (i + 1) * 8,
"pool.getSize() - Reports incorrect size.");
"pool.getSize() - Reported incorrect size.");
prevOffset = curOffset;
}
......@@ -481,7 +468,6 @@ UNIT(base_constpool) {
INFO("Checking pool alignment when combined constants are added.");
{
uint8_t bytes[32] = { 0 };
uint64_t c = 0;
size_t offset;
pool.add(bytes, 1, offset);
......
......@@ -128,9 +128,12 @@ struct ConstPoolTree {
if (link != NULL) {
ASMJIT_ASSERT(top != kHeightLimit);
stack[top++] = node;
node = link;
continue;
}
_Visit:
visitor.visit(node);
link = node->_link[1];
......@@ -143,6 +146,7 @@ struct ConstPoolTree {
break;
node = stack[--top];
goto _Visit;
}
}
......
......@@ -26,8 +26,8 @@ namespace asmjit {
Context::Context(Compiler* compiler) :
_compiler(compiler),
_varMapToVaListOffset(0),
_baseZone(8192 - kZoneOverhead) {
_baseZone(8192 - kZoneOverhead),
_varMapToVaListOffset(0) {
Context::reset();
}
......@@ -217,7 +217,7 @@ Error Context::resolveCellOffsets() {
// Vars - Allocated according to alignment/width.
while (varCell != NULL) {
uint32_t size = varCell->getSize();
uint32_t offset;
uint32_t offset = 0;
switch (size) {
case 1: offset = pos1 ; pos1 += 1 ; break;
......@@ -234,13 +234,13 @@ Error Context::resolveCellOffsets() {
varCell = varCell->_next;
}
// Stack - Allocated according to alignment and width.
// Stack - Allocated according to alignment/width.
while (stackCell != NULL) {
uint32_t size = stackCell->getSize();
uint32_t alignment = stackCell->getAlignment();
uint32_t offset;
// Try to fill the gap between variables / stack first.
// Try to fill the gap between variables/stack first.
if (size <= gapSize && alignment <= gapAlignment) {
offset = gapPos;
......
......@@ -10,11 +10,11 @@
// [Dependencies - AsmJit]
#include "../base/cpuinfo.h"
#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64)
#include "../x86/x86cpuinfo.h"
#else
// ?
#endif // ASMJIT_HOST || ASMJIT_HOST_X64
#endif
// [Dependencies - Posix]
#if defined(ASMJIT_OS_POSIX)
......@@ -54,7 +54,7 @@ uint32_t CpuInfo::detectHwThreadsCount() {
// [asmjit::CpuInfo - GetHost]
// ============================================================================
#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64)
struct AutoX86CpuInfo : public X86CpuInfo {
ASMJIT_INLINE AutoX86CpuInfo() : X86CpuInfo() {
X86CpuUtil::detect(this);
......@@ -62,14 +62,14 @@ struct AutoX86CpuInfo : public X86CpuInfo {
};
#else
#error "AsmJit - Unsupported CPU."
#endif // ASMJIT_HOST || ASMJIT_HOST_X64
#endif
const CpuInfo* CpuInfo::getHost() {
#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64)
static AutoX86CpuInfo cpuInfo;
#else
#error "AsmJit - Unsupported CPU."
#endif // ASMJIT_HOST || ASMJIT_HOST_X64
#endif
return &cpuInfo;
}
......
......@@ -20,7 +20,7 @@ namespace asmjit {
//! \{
// ============================================================================
// [asmjit::kCpuVendor]
// [asmjit::CpuVendor]
// ============================================================================
//! Cpu vendor ID.
......@@ -30,7 +30,7 @@ namespace asmjit {
//! calls. Some manufacturers changed their vendor strings and AsmJit is aware
//! of that - it checks multiple combinations and decides which vendor ID should
//! be used.
ASMJIT_ENUM(kCpuVendor) {
ASMJIT_ENUM(CpuVendor) {
//! No/Unknown vendor.
kCpuVendorNone = 0,
......@@ -59,7 +59,7 @@ struct CpuInfo {
// [Construction / Destruction]
// --------------------------------------------------------------------------
ASMJIT_INLINE CpuInfo(uint32_t size = sizeof(CpuInfo)) : _size(size) {}
ASMJIT_INLINE CpuInfo(uint32_t size) : _size(size) {}
// --------------------------------------------------------------------------
// [Accessors]
......@@ -120,7 +120,7 @@ struct CpuInfo {
//! Cpu long vendor string (brand).
char _brandString[64];
//! Cpu vendor id, see `asmjit::kCpuVendor`.
//! Cpu vendor id, see \ref CpuVendor.
uint32_t _vendorId;
//! Cpu family ID.
uint32_t _family;
......
......@@ -24,7 +24,7 @@
// [Dependencies - Windows]
#if defined(ASMJIT_OS_WINDOWS)
// `_InterlockedCompareExchange` is only available as intrinsic (MS Compiler).
# if defined(_MSC_VER)
# if defined(_MSC_VER) && _MSC_VER >= 1400
# include <intrin.h>
# pragma intrinsic(_InterlockedCompareExchange)
# else
......
......@@ -64,7 +64,9 @@ static const char* findPackedString(const char* p, uint32_t id, uint32_t maxId)
while (i < id) {
while (p[0])
p++;
p++;
i++;
}
return p;
......
......@@ -8,23 +8,23 @@
#ifndef _ASMJIT_BASE_ERROR_H
#define _ASMJIT_BASE_ERROR_H
// [Api-Begin]
#include "../apibegin.h"
// [Dependencies - AsmJit]
#include "../base/globals.h"
// [Api-Begin]
#include "../apibegin.h"
namespace asmjit {
//! \addtogroup asmjit_base_general
//! \{
// ============================================================================
// [asmjit::kError]
// [asmjit::ErrorCode]
// ============================================================================
//! AsmJit error codes.
ASMJIT_ENUM(kError) {
ASMJIT_ENUM(ErrorCode) {
//! No error (success).
//!
//! This is default state and state you want.
......@@ -188,7 +188,7 @@ struct ASMJIT_VCLASS ErrorHandler {
//! Error utilities.
struct ErrorUtil {
#if !defined(ASMJIT_DISABLE_NAMES)
//! Get printable version of AsmJit `kError` code.
//! Get a printable version of AsmJit `Error` code.
static ASMJIT_API const char* asString(Error code);
#endif // ASMJIT_DISABLE_NAMES
};
......
......@@ -34,7 +34,7 @@ typedef uint64_t Ptr;
typedef int64_t SignedPtr;
// ============================================================================
// [asmjit::kGlobals]
// [asmjit::GlobalDefs]
// ============================================================================
//! Invalid index
......@@ -48,7 +48,7 @@ static const size_t kInvalidIndex = ~static_cast<size_t>(0);
static const Ptr kNoBaseAddress = static_cast<Ptr>(static_cast<SignedPtr>(-1));
//! Global constants.
ASMJIT_ENUM(kGlobals) {
ASMJIT_ENUM(GlobalDefs) {
//! Invalid value or operand id.
kInvalidValue = 0xFFFFFFFF,
......@@ -74,11 +74,11 @@ ASMJIT_ENUM(kGlobals) {
};
// ============================================================================
// [asmjit::kArch]
// [asmjit::ArchId]
// ============================================================================
//! Architecture.
ASMJIT_ENUM(kArch) {
//! CPU architecture identifier.
ASMJIT_ENUM(ArchId) {
//! No/Unknown architecture.
kArchNone = 0,
......@@ -90,17 +90,17 @@ ASMJIT_ENUM(kArch) {
//! Arm architecture.
kArchArm = 4,
#if defined(ASMJIT_HOST_X86)
#if defined(ASMJIT_ARCH_X86)
kArchHost = kArchX86,
#endif // ASMJIT_HOST_X86
#endif // ASMJIT_ARCH_X86
#if defined(ASMJIT_HOST_X64)
#if defined(ASMJIT_ARCH_X64)
kArchHost = kArchX64,
#endif // ASMJIT_HOST_X64
#endif // ASMJIT_ARCH_X64
#if defined(ASMJIT_HOST_ARM)
#if defined(ASMJIT_ARCH_ARM)
kArchHost = kArchArm,
#endif // ASMJIT_HOST_ARM
#endif // ASMJIT_ARCH_ARM
//! Whether the host is 64-bit.
kArchHost64Bit = sizeof(intptr_t) >= 8
......
......@@ -11,8 +11,9 @@
// [Dependencies - AsmJit]
#include "../base/globals.h"
#if defined(_MSC_VER)
#pragma intrinsic(_BitScanForward)
#if defined(_MSC_VER) && _MSC_VER >= 1400
# include <intrin.h>
# pragma intrinsic(_BitScanForward)
#endif // ASMJIT_OS_WINDOWS
// [Api-Begin]
......@@ -43,6 +44,31 @@ struct IntTraits {
};
};
// \internal
template<size_t Size, int IsSigned>
struct AsInt_ { typedef int64_t Int; };
template<> struct AsInt_<1, 0> { typedef int Int; };
template<> struct AsInt_<1, 1> { typedef int Int; };
template<> struct AsInt_<2, 0> { typedef int Int; };
template<> struct AsInt_<2, 1> { typedef int Int; };
template<> struct AsInt_<4, 1> { typedef int Int; };
// \internal
//
// Map an integer `T` to an `int` or `int64_t`, depending on the type. Used
// internally by AsmJit to dispatch an argument of arbitrary integer type into
// a function that accepts either `int` or `int64_t`.
template<typename T>
struct AsInt {
typedef typename AsInt_<sizeof(T), IntTraits<T>::kIsSigned>::Int Int;
};
template<typename T>
ASMJIT_INLINE typename AsInt<T>::Int asInt(T value) {
return static_cast<typename AsInt<T>::Int>(value);
}
// ============================================================================
// [asmjit::IntUtil]
// ============================================================================
......@@ -82,29 +108,29 @@ struct IntUtil {
//! Pack two 8-bit integer and one 16-bit integer into a 32-bit integer as it
//! is an array of `{u0,u1,w2}`.
static ASMJIT_INLINE uint32_t pack32_2x8_1x16(uint32_t u0, uint32_t u1, uint32_t w2) {
#if defined(ASMJIT_HOST_LE)
#if defined(ASMJIT_ARCH_LE)
return u0 + (u1 << 8) + (w2 << 16);
#else
return (u0 << 24) + (u1 << 16) + (w2);
#endif // ASMJIT_HOST
#endif
}
//! Pack four 8-bit integer into a 32-bit integer as it is an array of `{u0,u1,u2,u3}`.
static ASMJIT_INLINE uint32_t pack32_4x8(uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) {
#if defined(ASMJIT_HOST_LE)
#if defined(ASMJIT_ARCH_LE)
return u0 + (u1 << 8) + (u2 << 16) + (u3 << 24);
#else
return (u0 << 24) + (u1 << 16) + (u2 << 8) + u3;
#endif // ASMJIT_HOST
#endif
}
//! Pack two 32-bit integer into a 64-bit integer as it is an array of `{u0,u1}`.
static ASMJIT_INLINE uint64_t pack64_2x32(uint32_t u0, uint32_t u1) {
#if defined(ASMJIT_HOST_LE)
#if defined(ASMJIT_ARCH_LE)
return (static_cast<uint64_t>(u1) << 32) + u0;
#else
return (static_cast<uint64_t>(u0) << 32) + u1;
#endif // ASMJIT_HOST
#endif
}
// --------------------------------------------------------------------------
......@@ -336,7 +362,7 @@ struct IntUtil {
//! Find a first bit in `mask`.
static ASMJIT_INLINE uint32_t findFirstBit(uint32_t mask) {
#if defined(_MSC_VER)
#if defined(_MSC_VER) && _MSC_VER >= 1400
DWORD i;
if (_BitScanForward(&i, mask)) {
ASMJIT_ASSERT(findFirstBitSlow(mask) == i);
......@@ -566,6 +592,26 @@ union UInt64 {
return *this;
}
// --------------------------------------------------------------------------
// [AndNot]
// --------------------------------------------------------------------------
ASMJIT_INLINE UInt64& andNot(uint64_t val) {
u64 &= ~val;
return *this;
}
ASMJIT_INLINE UInt64& andNot(const UInt64& val) {
if (kArchHost64Bit) {
u64 &= ~val.u64;
}
else {
u32[0] &= ~val.u32[0];
u32[1] &= ~val.u32[1];
}
return *this;
}
// --------------------------------------------------------------------------
// [Or]
// --------------------------------------------------------------------------
......@@ -606,26 +652,6 @@ union UInt64 {
return *this;
}
// --------------------------------------------------------------------------
// [Del]
// --------------------------------------------------------------------------
ASMJIT_INLINE UInt64& del(uint64_t val) {
u64 &= ~val;
return *this;
}
ASMJIT_INLINE UInt64& del(const UInt64& val) {
if (kArchHost64Bit) {
u64 &= ~val.u64;
}
else {
u32[0] &= ~val.u32[0];
u32[1] &= ~val.u32[1];
}
return *this;
}
// --------------------------------------------------------------------------
// [Eq]
// --------------------------------------------------------------------------
......@@ -694,11 +720,11 @@ union UInt64 {
uint8_t u8[8];
struct {
#if defined(ASMJIT_HOST_LE)
#if defined(ASMJIT_ARCH_LE)
uint32_t lo, hi;
#else
uint32_t hi, lo;
#endif // ASMJIT_HOST_LE
#endif // ASMJIT_ARCH_LE
};
};
......
......@@ -45,9 +45,12 @@ void Logger::logFormat(uint32_t style, const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
len = vsnprintf(buf, 1023, fmt, ap);
len = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
if (len >= sizeof(buf))
len = sizeof(buf) - 1;
logString(style, buf, len);
}
......@@ -120,15 +123,6 @@ FileLogger::FileLogger(FILE* stream) : _stream(NULL) {
FileLogger::~FileLogger() {}
// ============================================================================
// [asmjit::FileLogger - Accessors]
// ============================================================================
//! Set file stream.
void FileLogger::setStream(FILE* stream) {
_stream = stream;
}
// ============================================================================
// [asmjit::FileLogger - Logging]
// ============================================================================
......
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