- update asmjit library;
This commit is contained in:
parent
a2315eb314
commit
a03d04a335
|
@ -95,40 +95,74 @@ libdesmume_a_SOURCES = \
|
||||||
if HAVE_JIT
|
if HAVE_JIT
|
||||||
libdesmume_a_SOURCES += \
|
libdesmume_a_SOURCES += \
|
||||||
arm_jit.cpp arm_jit.h instruction_attributes.h \
|
arm_jit.cpp arm_jit.h instruction_attributes.h \
|
||||||
utils/AsmJit/ApiBegin.h \
|
utils/AsmJit/asmjit.h \
|
||||||
utils/AsmJit/ApiEnd.h \
|
utils/AsmJit/config.h \
|
||||||
utils/AsmJit/AsmJit.h \
|
utils/AsmJit/core.h \
|
||||||
utils/AsmJit/Assembler.h \
|
utils/AsmJit/x86.h \
|
||||||
utils/AsmJit/AssemblerX86X64.cpp \
|
utils/AsmJit/core/apibegin.h \
|
||||||
utils/AsmJit/AssemblerX86X64.h \
|
utils/AsmJit/core/apiend.h \
|
||||||
utils/AsmJit/Build.h \
|
utils/AsmJit/core/assembler.cpp \
|
||||||
utils/AsmJit/CodeGenerator.cpp \
|
utils/AsmJit/core/assembler.h \
|
||||||
utils/AsmJit/CodeGenerator.h \
|
utils/AsmJit/core/assert.cpp \
|
||||||
utils/AsmJit/Compiler.cpp \
|
utils/AsmJit/core/assert.h \
|
||||||
utils/AsmJit/Compiler.h \
|
utils/AsmJit/core/buffer.cpp \
|
||||||
utils/AsmJit/CompilerX86X64.cpp \
|
utils/AsmJit/core/buffer.h \
|
||||||
utils/AsmJit/CompilerX86X64.h \
|
utils/AsmJit/core/build.h \
|
||||||
utils/AsmJit/Config.h \
|
utils/AsmJit/core/compiler.cpp \
|
||||||
utils/AsmJit/CpuInfo.cpp \
|
utils/AsmJit/core/compiler.h \
|
||||||
utils/AsmJit/CpuInfo.h \
|
utils/AsmJit/core/compilercontext.cpp \
|
||||||
utils/AsmJit/Defs.cpp \
|
utils/AsmJit/core/compilercontext.h \
|
||||||
utils/AsmJit/Defs.h \
|
utils/AsmJit/core/compilerfunc.cpp \
|
||||||
utils/AsmJit/DefsX86X64.cpp \
|
utils/AsmJit/core/compilerfunc.h \
|
||||||
utils/AsmJit/DefsX86X64.h \
|
utils/AsmJit/core/compileritem.cpp \
|
||||||
utils/AsmJit/Logger.cpp \
|
utils/AsmJit/core/compileritem.h \
|
||||||
utils/AsmJit/Logger.h \
|
utils/AsmJit/core/context.cpp \
|
||||||
utils/AsmJit/MemoryManager.cpp \
|
utils/AsmJit/core/context.h \
|
||||||
utils/AsmJit/MemoryManager.h \
|
utils/AsmJit/core/cpuinfo.cpp \
|
||||||
utils/AsmJit/MemoryMarker.cpp \
|
utils/AsmJit/core/cpuinfo.h \
|
||||||
utils/AsmJit/MemoryMarker.h \
|
utils/AsmJit/core/defs.cpp \
|
||||||
utils/AsmJit/Operand.h \
|
utils/AsmJit/core/defs.h \
|
||||||
utils/AsmJit/OperandX86X64.cpp \
|
utils/AsmJit/core/func.cpp \
|
||||||
utils/AsmJit/OperandX86X64.h \
|
utils/AsmJit/core/func.h \
|
||||||
utils/AsmJit/Platform.cpp \
|
utils/AsmJit/core/intutil.h \
|
||||||
utils/AsmJit/Platform.h \
|
utils/AsmJit/core/lock.h \
|
||||||
utils/AsmJit/Util.cpp \
|
utils/AsmJit/core/logger.cpp \
|
||||||
utils/AsmJit/Util.h \
|
utils/AsmJit/core/logger.h \
|
||||||
utils/AsmJit/Util_p.h
|
utils/AsmJit/core/memorymanager.cpp \
|
||||||
|
utils/AsmJit/core/memorymanager.h \
|
||||||
|
utils/AsmJit/core/memorymarker.cpp \
|
||||||
|
utils/AsmJit/core/memorymarker.h \
|
||||||
|
utils/AsmJit/core/operand.cpp \
|
||||||
|
utils/AsmJit/core/operand.h \
|
||||||
|
utils/AsmJit/core/podvector.h \
|
||||||
|
utils/AsmJit/core/stringbuilder.cpp \
|
||||||
|
utils/AsmJit/core/stringbuilder.h \
|
||||||
|
utils/AsmJit/core/stringutil.cpp \
|
||||||
|
utils/AsmJit/core/stringutil.h \
|
||||||
|
utils/AsmJit/core/virtualmemory.cpp \
|
||||||
|
utils/AsmJit/core/virtualmemory.h \
|
||||||
|
utils/AsmJit/core/zonememory.cpp \
|
||||||
|
utils/AsmJit/core/zonememory.h \
|
||||||
|
utils/AsmJit/x86/x86assembler.cpp \
|
||||||
|
utils/AsmJit/x86/x86assembler.h \
|
||||||
|
utils/AsmJit/x86/x86compiler.cpp \
|
||||||
|
utils/AsmJit/x86/x86compiler.h \
|
||||||
|
utils/AsmJit/x86/x86compilercontext.cpp \
|
||||||
|
utils/AsmJit/x86/x86compilercontext.h \
|
||||||
|
utils/AsmJit/x86/x86compilerfunc.cpp \
|
||||||
|
utils/AsmJit/x86/x86compilerfunc.h \
|
||||||
|
utils/AsmJit/x86/x86compileritem.cpp \
|
||||||
|
utils/AsmJit/x86/x86compileritem.h \
|
||||||
|
utils/AsmJit/x86/x86cpuinfo.cpp \
|
||||||
|
utils/AsmJit/x86/x86cpuinfo.h \
|
||||||
|
utils/AsmJit/x86/x86defs.cpp \
|
||||||
|
utils/AsmJit/x86/x86defs.h \
|
||||||
|
utils/AsmJit/x86/x86func.cpp \
|
||||||
|
utils/AsmJit/x86/x86func.h \
|
||||||
|
utils/AsmJit/x86/x86operand.cpp \
|
||||||
|
utils/AsmJit/x86/x86operand.h \
|
||||||
|
utils/AsmJit/x86/x86util.cpp \
|
||||||
|
utils/AsmJit/x86/x86util.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if HAVE_GL
|
if HAVE_GL
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -98,16 +98,16 @@
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
#define FASTCALL __attribute__((fastcall))
|
#define FASTCALL __attribute__((fastcall))
|
||||||
#define ASMJIT_CALL_CONV CALL_CONV_GCCFASTCALL
|
#define ASMJIT_CALL_CONV kX86FuncConvGccFastCall
|
||||||
#elif defined (__i386__) && !defined(__clang__)
|
#elif defined (__i386__) && !defined(__clang__)
|
||||||
#define FASTCALL __attribute__((regparm(3)))
|
#define FASTCALL __attribute__((regparm(3)))
|
||||||
#define ASMJIT_CALL_CONV CALL_CONV_GCCREGPARM_3
|
#define ASMJIT_CALL_CONV kX86FuncConvGccRegParm3
|
||||||
#elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
|
#elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
|
||||||
#define FASTCALL
|
#define FASTCALL
|
||||||
#define ASMJIT_CALL_CONV CALL_CONV_DEFAULT
|
#define ASMJIT_CALL_CONV kX86FuncConvDefault
|
||||||
#else
|
#else
|
||||||
#define FASTCALL
|
#define FASTCALL
|
||||||
#define ASMJIT_CALL_CONV CALL_CONV_DEFAULT
|
#define ASMJIT_CALL_CONV kX86FuncConvDefault
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
|
@ -5,22 +5,22 @@
|
||||||
// Zlib - See COPYING file in this package.
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#ifndef _ASMJIT_H
|
#ifndef _ASMJIT_ASMJIT_H
|
||||||
#define _ASMJIT_H
|
#define _ASMJIT_ASMJIT_H
|
||||||
|
|
||||||
//! @mainpage
|
//! @mainpage
|
||||||
//!
|
//!
|
||||||
//! @brief AsmJit is complete x86/x64 JIT Assembler for C++ language
|
//! @brief AsmJit is a complete x86/x64 JIT Assembler for C++ language.
|
||||||
//!
|
//!
|
||||||
//! It supports FPU, MMX, 3dNow, SSE, SSE2, SSE3 and SSE4 intrinsics, powerful
|
//! It supports FPU, MMX, 3dNow, SSE, SSE2, SSE3 and SSE4 intrinsics, powerful
|
||||||
//! compiler that helps to write portable functions for 32-bit (x86) and 64-bit
|
//! compiler that helps to write portable functions for 32-bit (x86) and 64-bit
|
||||||
//! (x64) architectures. AsmJit can be used to create functions at runtime that
|
//! (x64) architectures. AsmJit can be used to create functions at runtime that
|
||||||
//! can be called from existing (but also generated) C/C++ code.
|
//! can be called from existing (but also generated) C/C++ code.
|
||||||
//!
|
//!
|
||||||
//! AsmJit is crossplatform library that supports various compilers and
|
//! AsmJit is a cross-platform library that supports various compilers and
|
||||||
//! operating systems. Currently only limitation is x86 (32-bit) or x64 (64-bit)
|
//! operating systems. Currently only limitation is x86 (32-bit) or x64 (64-bit)
|
||||||
//! processor. Currently tested operating systems are Windows (32-bit and 64-bit),
|
//! processor. Currently tested operating systems are Windows (32-bit and 64-bit),
|
||||||
//! Linux (32-bit and 64-bit) and MacOSX (32-bit).
|
//! Linux (32-bit and 64-bit) and MacOSX (32-bit and 64-bit).
|
||||||
//!
|
//!
|
||||||
//! @section AsmJit_Main_Introduction Introduction
|
//! @section AsmJit_Main_Introduction Introduction
|
||||||
//!
|
//!
|
||||||
|
@ -51,13 +51,12 @@
|
||||||
//! @section AsmJit_Main_Configuration Configuration, Definitions and Utilities
|
//! @section AsmJit_Main_Configuration Configuration, Definitions and Utilities
|
||||||
//!
|
//!
|
||||||
//! - @ref AsmJit_Config "Configuration" - Macros used to configure AsmJit.
|
//! - @ref AsmJit_Config "Configuration" - Macros used to configure AsmJit.
|
||||||
//! - @ref AsmJit_Util "Utilities" - Utilities and helper classes.
|
|
||||||
//!
|
//!
|
||||||
//! @section AsmJit_Main_HomePage AsmJit Homepage
|
//! @section AsmJit_Main_HomePage AsmJit Homepage
|
||||||
//!
|
//!
|
||||||
//! - http://code.google.com/p/asmjit/
|
//! - http://code.google.com/p/asmjit/
|
||||||
//!
|
//!
|
||||||
//! @section AsmJit_Main_X86X64Resources External X86/X64 Assembler Resources
|
//! @section AsmJit_Main_ResourcesX86 External X86/X64 Assembler Resources
|
||||||
//! - http://www.agner.org/optimize/
|
//! - http://www.agner.org/optimize/
|
||||||
//! - http://www.mark.masmcode.com/ (Assembler Tips)
|
//! - http://www.mark.masmcode.com/ (Assembler Tips)
|
||||||
//! - http://avisynth.org/mediawiki/Filter_SDK/Assembler_optimizing (Optimizing)
|
//! - http://avisynth.org/mediawiki/Filter_SDK/Assembler_optimizing (Optimizing)
|
||||||
|
@ -140,7 +139,7 @@
|
||||||
//! Contains classes related to @c AsmJit::Compiler that can be used
|
//! Contains classes related to @c AsmJit::Compiler that can be used
|
||||||
//! to generate code using high-level constructs.
|
//! to generate code using high-level constructs.
|
||||||
//!
|
//!
|
||||||
//! - See @c AsmJit::Compiler class for high level code generation
|
//! - See @c Compiler class for high level code generation
|
||||||
//! documentation - calling conventions, function declaration
|
//! documentation - calling conventions, function declaration
|
||||||
//! and variables management.
|
//! and variables management.
|
||||||
|
|
||||||
|
@ -211,12 +210,12 @@
|
||||||
//! // Now you are able to get specific features.
|
//! // Now you are able to get specific features.
|
||||||
//!
|
//!
|
||||||
//! // Processor has SSE2
|
//! // Processor has SSE2
|
||||||
//! if (i->features & CPU_FEATURE_SSE2)
|
//! if (i->features & kX86FeatureSse2)
|
||||||
//! {
|
//! {
|
||||||
//! // your code...
|
//! // your code...
|
||||||
//! }
|
//! }
|
||||||
//! // Processor has MMX
|
//! // Processor has MMX
|
||||||
//! else if (i->features & CPU_FEATURE__MMX)
|
//! else if (i->features & kX86Feature_MMX)
|
||||||
//! {
|
//! {
|
||||||
//! // your code...
|
//! // your code...
|
||||||
//! }
|
//! }
|
||||||
|
@ -250,12 +249,11 @@
|
||||||
//! a.setLogger(&logger);
|
//! a.setLogger(&logger);
|
||||||
//! @endcode
|
//! @endcode
|
||||||
//!
|
//!
|
||||||
//! You can see that logging goes through @c AsmJit::Assembler. If you are
|
//! You can see that logging goes through @c Assembler. If you are using
|
||||||
//! using @c AsmJit::Compiler and you want to log messages in correct assembler
|
//! @c Compiler and you want to log messages in correct assembler order,
|
||||||
//! order, you should look at @c AsmJit::Compiler::comment() method. It allows
|
//! you should look at @ref Compiler::comment() method. It allows you to
|
||||||
//! you to insert text message into @c AsmJit::Emittable list and
|
//! insert text message into items stream so the @c Compiler is able to
|
||||||
//! @c AsmJit::Compiler will send your message to @c AsmJit::Assembler in
|
//! send messages to @ref Assembler in correct order.
|
||||||
//! correct order.
|
|
||||||
//!
|
//!
|
||||||
//! @sa @c AsmJit::Logger, @c AsmJit::FileLogger.
|
//! @sa @c AsmJit::Logger, @c AsmJit::FileLogger.
|
||||||
|
|
||||||
|
@ -281,7 +279,7 @@
|
||||||
//! free mechanism. It internally uses larger chunks of memory to make
|
//! free mechanism. It internally uses larger chunks of memory to make
|
||||||
//! allocation fast and effective.
|
//! allocation fast and effective.
|
||||||
//!
|
//!
|
||||||
//! Using @c AsmJit::VirtualMemory::alloc() is crossplatform way how to
|
//! Using @c AsmJit::VirtualMemory::alloc() is cross-platform way how to
|
||||||
//! allocate this kind of memory without worrying about operating system
|
//! allocate this kind of memory without worrying about operating system
|
||||||
//! and it's API. Each memory block that is no longer needed should be
|
//! and it's API. Each memory block that is no longer needed should be
|
||||||
//! freed by @c AsmJit::VirtualMemory::free() method. If you want better
|
//! freed by @c AsmJit::VirtualMemory::free() method. If you want better
|
||||||
|
@ -291,12 +289,6 @@
|
||||||
//! @sa @c AsmJit::VirtualMemory, @ AsmJit::MemoryManager.
|
//! @sa @c AsmJit::VirtualMemory, @ AsmJit::MemoryManager.
|
||||||
|
|
||||||
|
|
||||||
//! @defgroup AsmJit_Util Utilities and helper classes.
|
|
||||||
//!
|
|
||||||
//! Contains some helper classes that's used by AsmJit library.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! @addtogroup AsmJit_Config
|
//! @addtogroup AsmJit_Config
|
||||||
//! @{
|
//! @{
|
||||||
|
|
||||||
|
@ -332,21 +324,19 @@
|
||||||
//!
|
//!
|
||||||
//! There are not other namespaces used in AsmJit library.
|
//! There are not other namespaces used in AsmJit library.
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// [Dependencies - Core]
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// [Includes]
|
#include "core.h"
|
||||||
#include "Build.h"
|
|
||||||
#include "Assembler.h"
|
|
||||||
#include "CodeGenerator.h"
|
|
||||||
#include "Compiler.h"
|
|
||||||
#include "CpuInfo.h"
|
|
||||||
#include "Defs.h"
|
|
||||||
#include "Logger.h"
|
|
||||||
#include "MemoryManager.h"
|
|
||||||
#include "MemoryMarker.h"
|
|
||||||
#include "Operand.h"
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "Util.h"
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// [Dependencies - X86 / X64]
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
||||||
|
#include "x86.h"
|
||||||
|
#endif // ASMJIT_X86 || ASMJIT_X64
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#endif // _ASMJIT_H
|
#endif // _ASMJIT_ASMJIT_H
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,272 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// We are using sprintf() here.
|
|
||||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
|
||||||
#endif // _MSC_VER
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include "Assembler.h"
|
|
||||||
#include "Compiler.h"
|
|
||||||
#include "CpuInfo.h"
|
|
||||||
#include "Logger.h"
|
|
||||||
#include "Util.h"
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
// [Api-Begin]
|
|
||||||
#include "ApiBegin.h"
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Emittable]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
Emittable::Emittable(Compiler* c, uint32_t type) ASMJIT_NOTHROW :
|
|
||||||
_compiler(c),
|
|
||||||
_next(NULL),
|
|
||||||
_prev(NULL),
|
|
||||||
_comment(NULL),
|
|
||||||
_type((uint8_t)type),
|
|
||||||
_translated(false),
|
|
||||||
_reserved0(0),
|
|
||||||
_reserved1(0),
|
|
||||||
_offset(INVALID_VALUE)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Emittable::~Emittable() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Emittable::prepare(CompilerContext& cc) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
_offset = cc._currentOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
Emittable* Emittable::translate(CompilerContext& cc) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return translated();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Emittable::emit(Assembler& a) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Emittable::post(Assembler& a) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int Emittable::getMaxSize() const ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
// Default maximum size is -1 which means that it's not known.
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Emittable::_tryUnuseVar(VarData* v) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Emittable::setComment(const char* str) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
_comment = _compiler->getZone().zstrdup(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Emittable::setCommentF(const char* fmt, ...) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
// I'm really not expecting larger inline comments:)
|
|
||||||
char buf[256];
|
|
||||||
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vsnprintf(buf, 255, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
// I don't know if vsnprintf can produce non-null terminated string, in case
|
|
||||||
// it can, we terminate it here.
|
|
||||||
buf[255] = '\0';
|
|
||||||
|
|
||||||
setComment(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::EDummy]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
EDummy::EDummy(Compiler* c) ASMJIT_NOTHROW :
|
|
||||||
Emittable(c, EMITTABLE_DUMMY)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
EDummy::~EDummy() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int EDummy::getMaxSize() const ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::EFunctionEnd]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
EFunctionEnd::EFunctionEnd(Compiler* c) ASMJIT_NOTHROW :
|
|
||||||
EDummy(c)
|
|
||||||
{
|
|
||||||
_type = EMITTABLE_FUNCTION_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFunctionEnd::~EFunctionEnd() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Emittable* EFunctionEnd::translate(CompilerContext& cc) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
_translated = true;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::EComment]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
EComment::EComment(Compiler* c, const char* str) ASMJIT_NOTHROW :
|
|
||||||
Emittable(c, EMITTABLE_COMMENT)
|
|
||||||
{
|
|
||||||
setComment(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
EComment::~EComment() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void EComment::emit(Assembler& a) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
if (a.getLogger())
|
|
||||||
{
|
|
||||||
a.getLogger()->logString(getComment());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int EComment::getMaxSize() const ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::EData]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
EData::EData(Compiler* c, const void* data, sysuint_t length) ASMJIT_NOTHROW :
|
|
||||||
Emittable(c, EMITTABLE_EMBEDDED_DATA)
|
|
||||||
{
|
|
||||||
_length = length;
|
|
||||||
memcpy(_data, data, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
EData::~EData() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void EData::emit(Assembler& a) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
a.embed(_data, _length);
|
|
||||||
}
|
|
||||||
|
|
||||||
int EData::getMaxSize() const ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return (int)_length;;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::EAlign]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
EAlign::EAlign(Compiler* c, uint32_t size) ASMJIT_NOTHROW :
|
|
||||||
Emittable(c, EMITTABLE_ALIGN), _size(size)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
EAlign::~EAlign() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void EAlign::emit(Assembler& a) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
a.align(_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int EAlign::getMaxSize() const ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return (_size > 0) ? (int)_size - 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::ETarget]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
ETarget::ETarget(Compiler* c, const Label& label) ASMJIT_NOTHROW :
|
|
||||||
Emittable(c, EMITTABLE_TARGET),
|
|
||||||
_label(label),
|
|
||||||
_from(NULL),
|
|
||||||
_state(NULL),
|
|
||||||
_jumpsCount(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ETarget::~ETarget() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ETarget::prepare(CompilerContext& cc) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
_offset = cc._currentOffset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Emittable* ETarget::translate(CompilerContext& cc) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
// If this ETarget was already translated, it's needed to change the current
|
|
||||||
// state and return NULL to tell CompilerContext to process next untranslated
|
|
||||||
// emittable.
|
|
||||||
if (_translated)
|
|
||||||
{
|
|
||||||
cc._restoreState(_state);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cc._unreachable)
|
|
||||||
{
|
|
||||||
cc._unreachable = 0;
|
|
||||||
|
|
||||||
// Assign state to the compiler context.
|
|
||||||
ASMJIT_ASSERT(_state != NULL);
|
|
||||||
cc._assignState(_state);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_state = cc._saveState();
|
|
||||||
}
|
|
||||||
|
|
||||||
return translated();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ETarget::emit(Assembler& a) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
a.bind(_label);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ETarget::getMaxSize() const ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // AsmJit namespace
|
|
|
@ -1,846 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#ifndef _ASMJIT_COMPILER_H
|
|
||||||
#define _ASMJIT_COMPILER_H
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include "Build.h"
|
|
||||||
#include "Defs.h"
|
|
||||||
#include "Operand.h"
|
|
||||||
#include "Util.h"
|
|
||||||
|
|
||||||
// [Api-Begin]
|
|
||||||
#include "ApiBegin.h"
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [Forward Declarations]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
struct Assembler;
|
|
||||||
struct CodeGenerator;
|
|
||||||
struct Compiler;
|
|
||||||
struct CompilerContext;
|
|
||||||
struct CompilerCore;
|
|
||||||
struct CompilerIntrinsics;
|
|
||||||
struct MemoryManager;
|
|
||||||
|
|
||||||
struct FunctionDefinition;
|
|
||||||
|
|
||||||
struct ForwardJumpData;
|
|
||||||
|
|
||||||
struct VarData;
|
|
||||||
struct VarAllocRecord;
|
|
||||||
struct StateData;
|
|
||||||
|
|
||||||
struct Emittable;
|
|
||||||
struct EAlign;
|
|
||||||
struct ECall;
|
|
||||||
struct EComment;
|
|
||||||
struct EData;
|
|
||||||
struct EEpilog;
|
|
||||||
struct EFunction;
|
|
||||||
struct EFunctionEnd;
|
|
||||||
struct EInstruction;
|
|
||||||
struct EJmp;
|
|
||||||
struct EProlog;
|
|
||||||
struct ERet;
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::TypeToId]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
#if !defined(ASMJIT_NODOC)
|
|
||||||
|
|
||||||
#if defined(ASMJIT_HAS_PARTIAL_TEMPLATE_SPECIALIZATION)
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct TypeToId
|
|
||||||
{
|
|
||||||
#if defined(ASMJIT_NODOC)
|
|
||||||
enum { Id = INVALID_VALUE };
|
|
||||||
#endif // ASMJIT_NODOC
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct TypeToId<T*> { enum { Id = VARIABLE_TYPE_INTPTR }; };
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Same trict is used in Qt, Boost, Fog and all other libraries that need
|
|
||||||
// something similar.
|
|
||||||
//
|
|
||||||
// It's easy. It's needed to use sizeof() to determine the size
|
|
||||||
// of return value of this function. If size will be sizeof(char)
|
|
||||||
// (this is our type) then type is pointer, otherwise it's not.
|
|
||||||
template<typename T>
|
|
||||||
char TypeToId_NoPtiHelper(T*(*)());
|
|
||||||
// And specialization.
|
|
||||||
void* TypeToId_NoPtiHelper(...);
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct TypeToId
|
|
||||||
{
|
|
||||||
// TypeInfo constants
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
// This is the hackery result.
|
|
||||||
Id = (sizeof(char) == sizeof( TypeToId_NoPtiHelper((T(*)())0) )
|
|
||||||
? VARIABLE_TYPE_INTPTR
|
|
||||||
: INVALID_VALUE)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // ASMJIT_HAS_PARTIAL_TEMPLATE_SPECIALIZATION
|
|
||||||
|
|
||||||
#define ASMJIT_DECLARE_TYPE_AS_ID(__T__, __Id__) \
|
|
||||||
template<> \
|
|
||||||
struct TypeToId<__T__> { enum { Id = __Id__ }; }
|
|
||||||
|
|
||||||
// Declare void type and alternative.
|
|
||||||
struct Void {};
|
|
||||||
ASMJIT_DECLARE_TYPE_AS_ID(void, INVALID_VALUE);
|
|
||||||
ASMJIT_DECLARE_TYPE_AS_ID(Void, INVALID_VALUE);
|
|
||||||
|
|
||||||
#endif // ASMJIT_NODOC
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Function Builder]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
struct FunctionDefinition
|
|
||||||
{
|
|
||||||
//! @brief Get function arguments IDs.
|
|
||||||
inline const uint32_t* getArguments() const
|
|
||||||
{
|
|
||||||
return _arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Get function arguments count.
|
|
||||||
inline uint32_t getArgumentsCount() const
|
|
||||||
{
|
|
||||||
return _argumentsCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint32_t getArgument(uint32_t id) const
|
|
||||||
{
|
|
||||||
ASMJIT_ASSERT(id < _argumentsCount);
|
|
||||||
return _arguments[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Get function return value.
|
|
||||||
inline uint32_t getReturnValue() const
|
|
||||||
{
|
|
||||||
return _returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
inline void _setDefinition(const uint32_t* arguments, uint32_t argumentsCount, uint32_t returnValue)
|
|
||||||
{
|
|
||||||
_arguments = arguments;
|
|
||||||
_argumentsCount = argumentsCount;
|
|
||||||
_returnValue = returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t* _arguments;
|
|
||||||
uint32_t _argumentsCount;
|
|
||||||
uint32_t _returnValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Custom function builder for up to 32 function arguments.
|
|
||||||
struct FunctionBuilderX : public FunctionDefinition
|
|
||||||
{
|
|
||||||
inline FunctionBuilderX()
|
|
||||||
{
|
|
||||||
_setDefinition(_argumentsData, 0, INVALID_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline void addArgument()
|
|
||||||
{
|
|
||||||
addArgumentRaw(TypeToId<ASMJIT_TYPE_TO_TYPE(T)>::Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline void setArgument(uint32_t id)
|
|
||||||
{
|
|
||||||
setArgumentRaw(id, TypeToId<ASMJIT_TYPE_TO_TYPE(T)>::Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline void setReturnValue()
|
|
||||||
{
|
|
||||||
setReturnValueRaw(TypeToId<ASMJIT_TYPE_TO_TYPE(T)>::Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void addArgumentRaw(uint32_t type)
|
|
||||||
{
|
|
||||||
ASMJIT_ASSERT(_argumentsCount < FUNC_MAX_ARGS);
|
|
||||||
_argumentsData[_argumentsCount++] = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setArgumentRaw(uint32_t id, uint32_t type)
|
|
||||||
{
|
|
||||||
ASMJIT_ASSERT(id < _argumentsCount);
|
|
||||||
_argumentsData[id] = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setReturnValueRaw(uint32_t returnValue)
|
|
||||||
{
|
|
||||||
_returnValue = returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
uint32_t _argumentsData[FUNC_MAX_ARGS];
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Class used to build function without arguments.
|
|
||||||
template<typename RET>
|
|
||||||
struct FunctionBuilder0 : public FunctionDefinition
|
|
||||||
{
|
|
||||||
inline FunctionBuilder0()
|
|
||||||
{
|
|
||||||
_setDefinition(NULL, 0, TypeToId<RET>::Id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Class used to build function with 1 argument.
|
|
||||||
template<typename RET, typename P0>
|
|
||||||
struct FunctionBuilder1 : public FunctionDefinition
|
|
||||||
{
|
|
||||||
inline FunctionBuilder1()
|
|
||||||
{
|
|
||||||
static const uint32_t args[] =
|
|
||||||
{
|
|
||||||
TypeToId<P0>::Id
|
|
||||||
};
|
|
||||||
_setDefinition(args, ASMJIT_ARRAY_SIZE(args), TypeToId<RET>::Id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Class used to build function with 2 arguments.
|
|
||||||
template<typename RET, typename P0, typename P1>
|
|
||||||
struct FunctionBuilder2 : public FunctionDefinition
|
|
||||||
{
|
|
||||||
inline FunctionBuilder2()
|
|
||||||
{
|
|
||||||
static const uint32_t args[] =
|
|
||||||
{
|
|
||||||
TypeToId<P0>::Id,
|
|
||||||
TypeToId<P1>::Id
|
|
||||||
};
|
|
||||||
_setDefinition(args, ASMJIT_ARRAY_SIZE(args), TypeToId<RET>::Id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Class used to build function with 3 arguments.
|
|
||||||
template<typename RET, typename P0, typename P1, typename P2>
|
|
||||||
struct FunctionBuilder3 : public FunctionDefinition
|
|
||||||
{
|
|
||||||
inline FunctionBuilder3()
|
|
||||||
{
|
|
||||||
static const uint32_t args[] =
|
|
||||||
{
|
|
||||||
TypeToId<P0>::Id,
|
|
||||||
TypeToId<P1>::Id,
|
|
||||||
TypeToId<P2>::Id
|
|
||||||
};
|
|
||||||
_setDefinition(args, ASMJIT_ARRAY_SIZE(args), TypeToId<RET>::Id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Class used to build function with 4 arguments.
|
|
||||||
template<typename RET, typename P0, typename P1, typename P2, typename P3>
|
|
||||||
struct FunctionBuilder4 : public FunctionDefinition
|
|
||||||
{
|
|
||||||
inline FunctionBuilder4()
|
|
||||||
{
|
|
||||||
static const uint32_t args[] =
|
|
||||||
{
|
|
||||||
TypeToId<P0>::Id,
|
|
||||||
TypeToId<P1>::Id,
|
|
||||||
TypeToId<P2>::Id,
|
|
||||||
TypeToId<P3>::Id
|
|
||||||
};
|
|
||||||
_setDefinition(args, ASMJIT_ARRAY_SIZE(args), TypeToId<RET>::Id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Class used to build function with 5 arguments.
|
|
||||||
template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4>
|
|
||||||
struct FunctionBuilder5 : public FunctionDefinition
|
|
||||||
{
|
|
||||||
inline FunctionBuilder5()
|
|
||||||
{
|
|
||||||
static const uint32_t args[] =
|
|
||||||
{
|
|
||||||
TypeToId<P0>::Id,
|
|
||||||
TypeToId<P1>::Id,
|
|
||||||
TypeToId<P2>::Id,
|
|
||||||
TypeToId<P3>::Id,
|
|
||||||
TypeToId<P4>::Id
|
|
||||||
};
|
|
||||||
_setDefinition(args, ASMJIT_ARRAY_SIZE(args), TypeToId<RET>::Id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Class used to build function with 6 arguments.
|
|
||||||
template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
|
|
||||||
struct FunctionBuilder6 : public FunctionDefinition
|
|
||||||
{
|
|
||||||
inline FunctionBuilder6()
|
|
||||||
{
|
|
||||||
static const uint32_t args[] =
|
|
||||||
{
|
|
||||||
TypeToId<P0>::Id,
|
|
||||||
TypeToId<P1>::Id,
|
|
||||||
TypeToId<P2>::Id,
|
|
||||||
TypeToId<P3>::Id,
|
|
||||||
TypeToId<P4>::Id,
|
|
||||||
TypeToId<P5>::Id
|
|
||||||
};
|
|
||||||
_setDefinition(args, ASMJIT_ARRAY_SIZE(args), TypeToId<RET>::Id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Class used to build function with 7 arguments.
|
|
||||||
template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
|
|
||||||
struct FunctionBuilder7 : public FunctionDefinition
|
|
||||||
{
|
|
||||||
inline FunctionBuilder7()
|
|
||||||
{
|
|
||||||
static const uint32_t args[] =
|
|
||||||
{
|
|
||||||
TypeToId<P0>::Id,
|
|
||||||
TypeToId<P1>::Id,
|
|
||||||
TypeToId<P2>::Id,
|
|
||||||
TypeToId<P3>::Id,
|
|
||||||
TypeToId<P4>::Id,
|
|
||||||
TypeToId<P5>::Id,
|
|
||||||
TypeToId<P6>::Id
|
|
||||||
};
|
|
||||||
_setDefinition(args, ASMJIT_ARRAY_SIZE(args), TypeToId<RET>::Id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Class used to build function with 8 arguments.
|
|
||||||
template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
|
|
||||||
struct FunctionBuilder8 : public FunctionDefinition
|
|
||||||
{
|
|
||||||
inline FunctionBuilder8()
|
|
||||||
{
|
|
||||||
static const uint32_t args[] =
|
|
||||||
{
|
|
||||||
TypeToId<P0>::Id,
|
|
||||||
TypeToId<P1>::Id,
|
|
||||||
TypeToId<P2>::Id,
|
|
||||||
TypeToId<P3>::Id,
|
|
||||||
TypeToId<P4>::Id,
|
|
||||||
TypeToId<P5>::Id,
|
|
||||||
TypeToId<P6>::Id,
|
|
||||||
TypeToId<P7>::Id
|
|
||||||
};
|
|
||||||
_setDefinition(args, ASMJIT_ARRAY_SIZE(args), TypeToId<RET>::Id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Class used to build function with 9 arguments.
|
|
||||||
template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
|
|
||||||
struct FunctionBuilder9 : public FunctionDefinition
|
|
||||||
{
|
|
||||||
inline FunctionBuilder9()
|
|
||||||
{
|
|
||||||
static const uint32_t args[] =
|
|
||||||
{
|
|
||||||
TypeToId<P0>::Id,
|
|
||||||
TypeToId<P1>::Id,
|
|
||||||
TypeToId<P2>::Id,
|
|
||||||
TypeToId<P3>::Id,
|
|
||||||
TypeToId<P4>::Id,
|
|
||||||
TypeToId<P5>::Id,
|
|
||||||
TypeToId<P6>::Id,
|
|
||||||
TypeToId<P7>::Id,
|
|
||||||
TypeToId<P8>::Id
|
|
||||||
};
|
|
||||||
_setDefinition(args, ASMJIT_ARRAY_SIZE(args), TypeToId<RET>::Id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Class used to build function with 10 arguments.
|
|
||||||
template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
|
|
||||||
struct FunctionBuilder10 : public FunctionDefinition
|
|
||||||
{
|
|
||||||
inline FunctionBuilder10()
|
|
||||||
{
|
|
||||||
static const uint32_t args[] =
|
|
||||||
{
|
|
||||||
TypeToId<P0>::Id,
|
|
||||||
TypeToId<P1>::Id,
|
|
||||||
TypeToId<P2>::Id,
|
|
||||||
TypeToId<P3>::Id,
|
|
||||||
TypeToId<P4>::Id,
|
|
||||||
TypeToId<P5>::Id,
|
|
||||||
TypeToId<P6>::Id,
|
|
||||||
TypeToId<P7>::Id,
|
|
||||||
TypeToId<P8>::Id,
|
|
||||||
TypeToId<P9>::Id
|
|
||||||
};
|
|
||||||
_setDefinition(args, ASMJIT_ARRAY_SIZE(args), TypeToId<RET>::Id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Emittable]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Emmitable.
|
|
||||||
//!
|
|
||||||
//! Emittable is object that can emit single or more instructions. To
|
|
||||||
//! create your custom emittable it's needed to override the abstract virtual
|
|
||||||
//! method @c emit().
|
|
||||||
//!
|
|
||||||
//! When you are finished serializing instructions to the @c Compiler and you
|
|
||||||
//! call @c Compiler::make(), it will first call @c prepare() method for each
|
|
||||||
//! emittable in list, then @c translate(), @c emit() and @c post() is the last.
|
|
||||||
//! Prepare can be used to calculate something that can be only calculated when
|
|
||||||
//! emitting instructions is finished (for example @c Function uses @c prepare()
|
|
||||||
//! to relocate memory home for all memory/spilled variables). The @c emit() should
|
|
||||||
//! be used to emit instruction or multiple instructions into @a Assembler stream,
|
|
||||||
//! and the @c post() is here to allow emitting embedded data (after function
|
|
||||||
//! declaration), etc.
|
|
||||||
struct ASMJIT_API Emittable
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Construction / Destruction]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Create new emittable.
|
|
||||||
//!
|
|
||||||
//! Never create @c Emittable by @c new operator or on the stack, use
|
|
||||||
//! @c Compiler::newObject template to do that.
|
|
||||||
Emittable(Compiler* c, uint32_t type) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Destroy emittable.
|
|
||||||
//!
|
|
||||||
//! @note Never destroy emittable using @c delete keyword, @c Compiler
|
|
||||||
//! manages all emittables in internal memory pool and it will destroy
|
|
||||||
//! all emittables after you destroy it.
|
|
||||||
virtual ~Emittable() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Emit and Helpers]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Step 1. Extract emittable variables, update statistics, ...
|
|
||||||
virtual void prepare(CompilerContext& cc) ASMJIT_NOTHROW;
|
|
||||||
//! @brief Step 2. Translate instruction, alloc variables, ...
|
|
||||||
virtual Emittable* translate(CompilerContext& cc) ASMJIT_NOTHROW;
|
|
||||||
//! @brief Step 3. Emit to @c Assembler.
|
|
||||||
virtual void emit(Assembler& a) ASMJIT_NOTHROW;
|
|
||||||
//! @brief Step 4. Last post step (verify, add data, etc).
|
|
||||||
virtual void post(Assembler& a) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Utilities]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Get maximum size in bytes of this emittable (in binary).
|
|
||||||
virtual int getMaxSize() const ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Try to unuse the variable @a.
|
|
||||||
//!
|
|
||||||
//! Returns @c true only if the variable will be unused by the instruction,
|
|
||||||
//! otherwise @c false is returned.
|
|
||||||
virtual bool _tryUnuseVar(VarData* v) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Compiler]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Get associated compiler instance.
|
|
||||||
inline Compiler* getCompiler() const ASMJIT_NOTHROW { return _compiler; }
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Type / Offset]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Get emittable type, see @c EMITTABLE_TYPE.
|
|
||||||
inline uint32_t getType() const ASMJIT_NOTHROW { return _type; }
|
|
||||||
|
|
||||||
//! @brief Get whether the emittable was translated.
|
|
||||||
inline uint8_t isTranslated() const ASMJIT_NOTHROW { return _translated; }
|
|
||||||
|
|
||||||
//! @brief Get emittable offset in the stream
|
|
||||||
//!
|
|
||||||
//! Emittable offset is not byte offset, each emittable increments offset by 1
|
|
||||||
//! and this value is then used by register allocator. Emittable offset is
|
|
||||||
//! set by compiler by the register allocator, don't use it in your code.
|
|
||||||
inline uint32_t getOffset() const ASMJIT_NOTHROW { return _offset; }
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Emittables List]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Get previous emittable in list.
|
|
||||||
inline Emittable* getPrev() const ASMJIT_NOTHROW { return _prev; }
|
|
||||||
//! @brief Get next emittable in list.
|
|
||||||
inline Emittable* getNext() const ASMJIT_NOTHROW { return _next; }
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Comment]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Get comment string.
|
|
||||||
inline const char* getComment() const ASMJIT_NOTHROW { return _comment; }
|
|
||||||
|
|
||||||
//! @brief Set comment string to @a str.
|
|
||||||
void setComment(const char* str) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Format comment string using @a fmt string and variable argument list.
|
|
||||||
void setCommentF(const char* fmt, ...) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Protected]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
protected:
|
|
||||||
//! @brief Mark emittable as translated and return next.
|
|
||||||
inline Emittable* translated() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
ASMJIT_ASSERT(_translated == false);
|
|
||||||
|
|
||||||
_translated = true;
|
|
||||||
return _next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Members]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Compiler where this emittable is connected to.
|
|
||||||
Compiler* _compiler;
|
|
||||||
|
|
||||||
//! @brief Type of emittable, see @c EMITTABLE_TYPE.
|
|
||||||
uint8_t _type;
|
|
||||||
//! @brief Whether the emittable was translated, see @c translate().
|
|
||||||
uint8_t _translated;
|
|
||||||
//! @brief Reserved flags for future use.
|
|
||||||
uint8_t _reserved0;
|
|
||||||
//! @brief Reserved flags for future use.
|
|
||||||
uint8_t _reserved1;
|
|
||||||
|
|
||||||
//! @brief Emittable offset.
|
|
||||||
uint32_t _offset;
|
|
||||||
|
|
||||||
//! @brief Previous emittable.
|
|
||||||
Emittable* _prev;
|
|
||||||
//! @brief Next emittable.
|
|
||||||
Emittable* _next;
|
|
||||||
|
|
||||||
//! @brief Embedded comment string (also used by a @c Comment emittable).
|
|
||||||
const char* _comment;
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend struct CompilerCore;
|
|
||||||
|
|
||||||
ASMJIT_DISABLE_COPY(Emittable)
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::EDummy]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Dummy emittable, used as a mark.
|
|
||||||
//!
|
|
||||||
//! This emittable does nothing and it's only used by @ref Compiler to mark
|
|
||||||
//! specific location in the code.
|
|
||||||
struct ASMJIT_API EDummy : public Emittable
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Construction / Destruction]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Create a new @ref EDummy instance.
|
|
||||||
EDummy(Compiler* c) ASMJIT_NOTHROW;
|
|
||||||
//! @brief Destroy the @ref EDummy instance.
|
|
||||||
virtual ~EDummy() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Utilities]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
virtual int getMaxSize() const ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
private:
|
|
||||||
ASMJIT_DISABLE_COPY(EDummy)
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::EFunctionEnd]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief End of function.
|
|
||||||
//!
|
|
||||||
//! This emittable does nothing and it's only used by @ref Compiler to mark
|
|
||||||
//! specific location in the code. The @c EFunctionEnd is similar to @c EDummy,
|
|
||||||
//! except that it overrides @c translate() to return @c NULL.
|
|
||||||
struct ASMJIT_API EFunctionEnd : public EDummy
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Construction / Destruction]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Create a new @ref EDummy instance.
|
|
||||||
EFunctionEnd(Compiler* c) ASMJIT_NOTHROW;
|
|
||||||
//! @brief Destroy the @ref EDummy instance.
|
|
||||||
virtual ~EFunctionEnd() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Emit and Helpers]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
virtual Emittable* translate(CompilerContext& cc) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
private:
|
|
||||||
ASMJIT_DISABLE_COPY(EFunctionEnd)
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::EComment]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Emittable used to emit comment into @c Assembler logger.
|
|
||||||
//!
|
|
||||||
//! Comments allows to comment your assembler stream for better debugging
|
|
||||||
//! and visualization what's happening. Comments are ignored if logger is
|
|
||||||
//! not set.
|
|
||||||
//!
|
|
||||||
//! Comment string can't be modified after comment was created.
|
|
||||||
struct ASMJIT_API EComment : public Emittable
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Construction / Destruction]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Create a new @ref EComment instance.
|
|
||||||
EComment(Compiler* c, const char* comment) ASMJIT_NOTHROW;
|
|
||||||
//! @brief Destroy the @ref EComment instance.
|
|
||||||
virtual ~EComment() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Emit]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
virtual void emit(Assembler& a) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Utilities]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
virtual int getMaxSize() const ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend struct CompilerCore;
|
|
||||||
|
|
||||||
ASMJIT_DISABLE_COPY(EComment)
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::EData]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Emittable used to emit comment into @c Assembler logger.
|
|
||||||
//!
|
|
||||||
//! @note This class is always allocated by @c AsmJit::Compiler.
|
|
||||||
struct ASMJIT_API EData : public Emittable
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Construction / Destruction]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Create a new @ref EData instance.
|
|
||||||
EData(Compiler* c, const void* data, sysuint_t length) ASMJIT_NOTHROW;
|
|
||||||
//! @brief Destroy the @ref EData instance.
|
|
||||||
virtual ~EData() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Emit]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
virtual void emit(Assembler& a) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Utilities]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
virtual int getMaxSize() const ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Data]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Get pointer to embedded data.
|
|
||||||
uint8_t* getData() const ASMJIT_NOTHROW { return (uint8_t*)_data; }
|
|
||||||
|
|
||||||
//! @brief Get length of embedded data.
|
|
||||||
sysuint_t getLength() const ASMJIT_NOTHROW { return _length; }
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Members]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
protected:
|
|
||||||
//! @brief Data length.
|
|
||||||
sysuint_t _length;
|
|
||||||
//! @brief Data buffer (that will be embedded to the assembler stream).
|
|
||||||
uint8_t _data[sizeof(void*)];
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend struct CompilerCore;
|
|
||||||
|
|
||||||
ASMJIT_DISABLE_COPY(EData)
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::EAlign]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Emittable used to align assembler code.
|
|
||||||
struct ASMJIT_API EAlign : public Emittable
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Construction / Destruction]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Create a new @ref EAlign instance.
|
|
||||||
EAlign(Compiler* c, uint32_t size = 0) ASMJIT_NOTHROW;
|
|
||||||
//! @brief Destroy the @ref EAlign instance.
|
|
||||||
virtual ~EAlign() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Emit]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
virtual void emit(Assembler& a) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Utilities]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
virtual int getMaxSize() const ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Align Size]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Get align size in bytes.
|
|
||||||
inline uint32_t getSize() const ASMJIT_NOTHROW { return _size; }
|
|
||||||
//! @brief Set align size in bytes to @a size.
|
|
||||||
inline void setSize(uint32_t size) ASMJIT_NOTHROW { _size = size; }
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Members]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
protected:
|
|
||||||
//! @brief Align size.
|
|
||||||
uint32_t _size;
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend struct CompilerCore;
|
|
||||||
|
|
||||||
ASMJIT_DISABLE_COPY(EAlign)
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::ETarget]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Target - the bound label.
|
|
||||||
struct ASMJIT_API ETarget : public Emittable
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Construction / Destruction]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Create a new @ref ETarget instance.
|
|
||||||
ETarget(Compiler* c, const Label& target) ASMJIT_NOTHROW;
|
|
||||||
//! @brief Destroy the @ref ETarget instance.
|
|
||||||
virtual ~ETarget() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Emit]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
virtual void prepare(CompilerContext& cc) ASMJIT_NOTHROW;
|
|
||||||
virtual Emittable* translate(CompilerContext& cc) ASMJIT_NOTHROW;
|
|
||||||
virtual void emit(Assembler& a) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Utilities]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
virtual int getMaxSize() const ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Methods]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Return label bound to this target.
|
|
||||||
inline const Label& getLabel() const ASMJIT_NOTHROW { return _label; }
|
|
||||||
|
|
||||||
//! @brief Get first jmp instruction.
|
|
||||||
inline EJmp* getFrom() const ASMJIT_NOTHROW { return _from; }
|
|
||||||
|
|
||||||
//! @brief Get register allocator state for this target.
|
|
||||||
inline StateData* getState() const ASMJIT_NOTHROW { return _state; }
|
|
||||||
|
|
||||||
//! @brief Get number of jumps to this target.
|
|
||||||
inline uint32_t getJumpsCount() const ASMJIT_NOTHROW { return _jumpsCount; }
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Members]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
protected:
|
|
||||||
//! @brief Label.
|
|
||||||
Label _label;
|
|
||||||
//! @brief First jump instruction that points to this target (label).
|
|
||||||
EJmp* _from;
|
|
||||||
//! @brief State at this location.
|
|
||||||
StateData* _state;
|
|
||||||
|
|
||||||
//! @brief Count of jumps to this target (label).
|
|
||||||
uint32_t _jumpsCount;
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend struct CompilerContext;
|
|
||||||
friend struct CompilerCore;
|
|
||||||
friend struct EInstruction;
|
|
||||||
friend struct EJmp;
|
|
||||||
|
|
||||||
ASMJIT_DISABLE_COPY(ETarget)
|
|
||||||
};
|
|
||||||
|
|
||||||
} // AsmJit namespace
|
|
||||||
|
|
||||||
// [Api-End]
|
|
||||||
#include "ApiEnd.h"
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [Platform Specific]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
// [X86 / X64]
|
|
||||||
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
|
||||||
#include "CompilerX86X64.h"
|
|
||||||
#endif // ASMJIT_X86 || ASMJIT_X64
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#endif // _ASMJIT_COMPILER_H
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -4,16 +4,16 @@
|
||||||
// [License]
|
// [License]
|
||||||
// Zlib - See COPYING file in this package.
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CONFIG_H
|
||||||
|
#define _ASMJIT_CONFIG_H
|
||||||
|
|
||||||
// This file is designed to be modifyable. Platform specific changes should
|
// This file is designed to be modifyable. Platform specific changes should
|
||||||
// be applied to this file so it's guaranteed that never versions of AsmJit
|
// be applied to this file so it's guaranteed that never versions of AsmJit
|
||||||
// library will never overwrite generated config files.
|
// library will never overwrite generated config files.
|
||||||
//
|
//
|
||||||
// So modify this file by your build system or by hand.
|
// So modify this file by your build system or by hand.
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#ifndef _ASMJIT_CONFIG_H
|
|
||||||
#define _ASMJIT_CONFIG_H
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [AsmJit - OS]
|
// [AsmJit - OS]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
@ -21,8 +21,8 @@
|
||||||
// Provides definitions about your operating system. It's detected by default,
|
// Provides definitions about your operating system. It's detected by default,
|
||||||
// so override it if you have problems with automatic detection.
|
// so override it if you have problems with automatic detection.
|
||||||
//
|
//
|
||||||
// #define ASMJIT_WINDOWS 1
|
// #define ASMJIT_WINDOWS
|
||||||
// #define ASMJIT_POSIX 2
|
// #define ASMJIT_POSIX
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [AsmJit - Architecture]
|
// [AsmJit - Architecture]
|
||||||
|
@ -39,17 +39,8 @@
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// If you are embedding AsmJit library into your project (statically), undef
|
// If you are embedding AsmJit library into your project (statically), undef
|
||||||
// ASMJIT_API macro. ASMJIT_HIDDEN macro can contain visibility (used by GCC)
|
// ASMJIT_API macro.
|
||||||
// to hide some AsmJit symbols that shouldn't be never exported.
|
|
||||||
//
|
|
||||||
// If you have problems with throw() in compilation time, undef ASMJIT_NOTHROW
|
|
||||||
// to disable this feature. ASMJIT_NOTHROW marks functions that never throws
|
|
||||||
// an exception.
|
|
||||||
|
|
||||||
#define ASMJIT_HIDDEN
|
|
||||||
#define ASMJIT_API
|
#define ASMJIT_API
|
||||||
// #define ASMJIT_NOTHROW
|
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [AsmJit - Memory Management]
|
// [AsmJit - Memory Management]
|
||||||
|
|
|
@ -1,337 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include "CpuInfo.h"
|
|
||||||
|
|
||||||
#if defined(ASMJIT_WINDOWS)
|
|
||||||
# include <windows.h>
|
|
||||||
#endif // ASMJIT_WINDOWS
|
|
||||||
|
|
||||||
// 2009-02-05: Thanks to Mike Tajmajer for supporting VC7.1 compiler. This
|
|
||||||
// shouldn't affect x64 compilation, because x64 compiler starts with
|
|
||||||
// VS2005 (VC8.0).
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
# if _MSC_VER >= 1400
|
|
||||||
# include <intrin.h>
|
|
||||||
# endif // _MSC_VER >= 1400 (>= VS2005)
|
|
||||||
#endif // _MSC_VER
|
|
||||||
|
|
||||||
#if defined(ASMJIT_POSIX)
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/statvfs.h>
|
|
||||||
#include <sys/utsname.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif // ASMJIT_POSIX
|
|
||||||
|
|
||||||
// [Api-Begin]
|
|
||||||
#include "ApiBegin.h"
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
// helpers
|
|
||||||
static uint32_t detectNumberOfProcessors(void)
|
|
||||||
{
|
|
||||||
#if defined(ASMJIT_WINDOWS)
|
|
||||||
SYSTEM_INFO info;
|
|
||||||
GetSystemInfo(&info);
|
|
||||||
return info.dwNumberOfProcessors;
|
|
||||||
#elif defined(ASMJIT_POSIX) && defined(_SC_NPROCESSORS_ONLN)
|
|
||||||
// It seems that sysconf returns the number of "logical" processors on both
|
|
||||||
// mac and linux. So we get the number of "online logical" processors.
|
|
||||||
long res = sysconf(_SC_NPROCESSORS_ONLN);
|
|
||||||
if (res == -1) return 1;
|
|
||||||
|
|
||||||
return static_cast<uint32_t>(res);
|
|
||||||
#else
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is messy, I know. cpuid is implemented as intrinsic in VS2005, but
|
|
||||||
// we should support other compilers as well. Main problem is that MS compilers
|
|
||||||
// in 64-bit mode not allows to use inline assembler, so we need intrinsic and
|
|
||||||
// we need also asm version.
|
|
||||||
|
|
||||||
// cpuid() and detectCpuInfo() for x86 and x64 platforms begins here.
|
|
||||||
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
|
||||||
void cpuid(uint32_t in, CpuId* out) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
|
|
||||||
// 2009-02-05: Thanks to Mike Tajmajer for supporting VC7.1 compiler.
|
|
||||||
// ASMJIT_X64 is here only for readibility, only VS2005 can compile 64-bit code.
|
|
||||||
# if _MSC_VER >= 1400 || defined(ASMJIT_X64)
|
|
||||||
// done by intrinsics
|
|
||||||
__cpuid(reinterpret_cast<int*>(out->i), in);
|
|
||||||
# else // _MSC_VER < 1400
|
|
||||||
uint32_t cpuid_in = in;
|
|
||||||
uint32_t* cpuid_out = out->i;
|
|
||||||
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
mov eax, cpuid_in
|
|
||||||
mov edi, cpuid_out
|
|
||||||
cpuid
|
|
||||||
mov dword ptr[edi + 0], eax
|
|
||||||
mov dword ptr[edi + 4], ebx
|
|
||||||
mov dword ptr[edi + 8], ecx
|
|
||||||
mov dword ptr[edi + 12], edx
|
|
||||||
}
|
|
||||||
# endif // _MSC_VER < 1400
|
|
||||||
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
|
|
||||||
// Note, need to preserve ebx/rbx register!
|
|
||||||
# if defined(ASMJIT_X86)
|
|
||||||
# define __mycpuid(a, b, c, d, inp) \
|
|
||||||
asm ("mov %%ebx, %%edi\n" \
|
|
||||||
"cpuid\n" \
|
|
||||||
"xchg %%edi, %%ebx\n" \
|
|
||||||
: "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
|
|
||||||
# else
|
|
||||||
# define __mycpuid(a, b, c, d, inp) \
|
|
||||||
asm ("mov %%rbx, %%rdi\n" \
|
|
||||||
"cpuid\n" \
|
|
||||||
"xchg %%rdi, %%rbx\n" \
|
|
||||||
: "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
|
|
||||||
# endif
|
|
||||||
__mycpuid(out->eax, out->ebx, out->ecx, out->edx, in);
|
|
||||||
|
|
||||||
#endif // compiler
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CpuVendorInfo
|
|
||||||
{
|
|
||||||
uint32_t id;
|
|
||||||
char text[12];
|
|
||||||
};
|
|
||||||
|
|
||||||
static const CpuVendorInfo cpuVendorInfo[] =
|
|
||||||
{
|
|
||||||
{ CPU_VENDOR_INTEL , { 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'I', 'n', 't', 'e', 'l' } },
|
|
||||||
|
|
||||||
{ CPU_VENDOR_AMD , { 'A', 'u', 't', 'h', 'e', 'n', 't', 'i', 'c', 'A', 'M', 'D' } },
|
|
||||||
{ CPU_VENDOR_AMD , { 'A', 'M', 'D', 'i', 's', 'b', 'e', 't', 't', 'e', 'r', '!' } },
|
|
||||||
|
|
||||||
{ CPU_VENDOR_NSM , { 'G', 'e', 'o', 'd', 'e', ' ', 'b', 'y', ' ', 'N', 'S', 'C' } },
|
|
||||||
{ CPU_VENDOR_NSM , { 'C', 'y', 'r', 'i', 'x', 'I', 'n', 's', 't', 'e', 'a', 'd' } },
|
|
||||||
|
|
||||||
{ CPU_VENDOR_TRANSMETA, { 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'T', 'M', 'x', '8', '6' } },
|
|
||||||
{ CPU_VENDOR_TRANSMETA, { 'T', 'r', 'a', 'n', 's', 'm', 'e', 't', 'a', 'C', 'P', 'U' } },
|
|
||||||
|
|
||||||
{ CPU_VENDOR_VIA , { 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 } },
|
|
||||||
{ CPU_VENDOR_VIA , { 'C', 'e', 'n', 't', 'a', 'u', 'r', 'H', 'a', 'u', 'l', 's' } }
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline bool cpuVencorEq(const CpuVendorInfo& info, const char* vendorString)
|
|
||||||
{
|
|
||||||
const uint32_t* a = reinterpret_cast<const uint32_t*>(info.text);
|
|
||||||
const uint32_t* b = reinterpret_cast<const uint32_t*>(vendorString);
|
|
||||||
|
|
||||||
return (a[0] == b[0]) &
|
|
||||||
(a[1] == b[1]) &
|
|
||||||
(a[2] == b[2]) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void simplifyBrandString(char* s)
|
|
||||||
{
|
|
||||||
// Always clear the current character in the buffer. This ensures that there
|
|
||||||
// is no garbage after the string NULL terminator.
|
|
||||||
char* d = s;
|
|
||||||
|
|
||||||
char prev = 0;
|
|
||||||
char curr = s[0];
|
|
||||||
s[0] = '\0';
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if (curr == 0) break;
|
|
||||||
|
|
||||||
if (curr == ' ')
|
|
||||||
{
|
|
||||||
if (prev == '@') goto _Skip;
|
|
||||||
if (s[1] == ' ' || s[1] == '@') goto _Skip;
|
|
||||||
}
|
|
||||||
|
|
||||||
d[0] = curr;
|
|
||||||
d++;
|
|
||||||
prev = curr;
|
|
||||||
|
|
||||||
_Skip:
|
|
||||||
curr = *++s;
|
|
||||||
s[0] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
d[0] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void detectCpuInfo(CpuInfo* i) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
uint32_t a;
|
|
||||||
|
|
||||||
// First clear our struct
|
|
||||||
memset(i, 0, sizeof(CpuInfo));
|
|
||||||
memcpy(i->vendor, "Unknown", 8);
|
|
||||||
|
|
||||||
i->numberOfProcessors = detectNumberOfProcessors();
|
|
||||||
|
|
||||||
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
|
||||||
CpuId out;
|
|
||||||
|
|
||||||
// Get vendor string
|
|
||||||
cpuid(0, &out);
|
|
||||||
|
|
||||||
memcpy(i->vendor, &out.ebx, 4);
|
|
||||||
memcpy(i->vendor + 4, &out.edx, 4);
|
|
||||||
memcpy(i->vendor + 8, &out.ecx, 4);
|
|
||||||
|
|
||||||
for (a = 0; a < 3; a++)
|
|
||||||
{
|
|
||||||
if (cpuVencorEq(cpuVendorInfo[a], i->vendor))
|
|
||||||
{
|
|
||||||
i->vendorId = cpuVendorInfo[a].id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get feature flags in ecx/edx, and family/model in eax
|
|
||||||
cpuid(1, &out);
|
|
||||||
|
|
||||||
// family and model fields
|
|
||||||
i->family = (out.eax >> 8) & 0x0F;
|
|
||||||
i->model = (out.eax >> 4) & 0x0F;
|
|
||||||
i->stepping = (out.eax ) & 0x0F;
|
|
||||||
|
|
||||||
// use extended family and model fields
|
|
||||||
if (i->family == 0x0F)
|
|
||||||
{
|
|
||||||
i->family += ((out.eax >> 20) & 0xFF);
|
|
||||||
i->model += ((out.eax >> 16) & 0x0F) << 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
i->x86ExtendedInfo.processorType = ((out.eax >> 12) & 0x03);
|
|
||||||
i->x86ExtendedInfo.brandIndex = ((out.ebx ) & 0xFF);
|
|
||||||
i->x86ExtendedInfo.flushCacheLineSize = ((out.ebx >> 8) & 0xFF) * 8;
|
|
||||||
i->x86ExtendedInfo.maxLogicalProcessors = ((out.ebx >> 16) & 0xFF);
|
|
||||||
i->x86ExtendedInfo.apicPhysicalId = ((out.ebx >> 24) & 0xFF);
|
|
||||||
|
|
||||||
if (out.ecx & 0x00000001U) i->features |= CPU_FEATURE_SSE3;
|
|
||||||
if (out.ecx & 0x00000002U) i->features |= CPU_FEATURE_PCLMULDQ;
|
|
||||||
if (out.ecx & 0x00000008U) i->features |= CPU_FEATURE_MONITOR_MWAIT;
|
|
||||||
if (out.ecx & 0x00000200U) i->features |= CPU_FEATURE_SSSE3;
|
|
||||||
if (out.ecx & 0x00002000U) i->features |= CPU_FEATURE_CMPXCHG16B;
|
|
||||||
if (out.ecx & 0x00080000U) i->features |= CPU_FEATURE_SSE4_1;
|
|
||||||
if (out.ecx & 0x00100000U) i->features |= CPU_FEATURE_SSE4_2;
|
|
||||||
if (out.ecx & 0x00400000U) i->features |= CPU_FEATURE_MOVBE;
|
|
||||||
if (out.ecx & 0x00800000U) i->features |= CPU_FEATURE_POPCNT;
|
|
||||||
if (out.ecx & 0x10000000U) i->features |= CPU_FEATURE_AVX;
|
|
||||||
|
|
||||||
if (out.edx & 0x00000010U) i->features |= CPU_FEATURE_RDTSC;
|
|
||||||
if (out.edx & 0x00000100U) i->features |= CPU_FEATURE_CMPXCHG8B;
|
|
||||||
if (out.edx & 0x00008000U) i->features |= CPU_FEATURE_CMOV;
|
|
||||||
if (out.edx & 0x00800000U) i->features |= CPU_FEATURE_MMX;
|
|
||||||
if (out.edx & 0x01000000U) i->features |= CPU_FEATURE_FXSR;
|
|
||||||
if (out.edx & 0x02000000U) i->features |= CPU_FEATURE_SSE | CPU_FEATURE_MMX_EXT;
|
|
||||||
if (out.edx & 0x04000000U) i->features |= CPU_FEATURE_SSE | CPU_FEATURE_SSE2;
|
|
||||||
if (out.edx & 0x10000000U) i->features |= CPU_FEATURE_MULTI_THREADING;
|
|
||||||
|
|
||||||
if (i->vendorId == CPU_VENDOR_AMD && (out.edx & 0x10000000U))
|
|
||||||
{
|
|
||||||
// AMD sets Multithreading to ON if it has more cores.
|
|
||||||
if (i->numberOfProcessors == 1) i->numberOfProcessors = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This comment comes from V8 and I think that its important:
|
|
||||||
//
|
|
||||||
// Opteron Rev E has a bug in which on very rare occasions a locked
|
|
||||||
// instruction doesn't act as a read-acquire barrier if followed by a
|
|
||||||
// non-locked read-modify-write instruction. Rev F has this bug in
|
|
||||||
// pre-release versions, but not in versions released to customers,
|
|
||||||
// so we test only for Rev E, which is family 15, model 32..63 inclusive.
|
|
||||||
|
|
||||||
if (i->vendorId == CPU_VENDOR_AMD && i->family == 15 && i->model >= 32 && i->model <= 63)
|
|
||||||
{
|
|
||||||
i->bugs |= CPU_BUG_AMD_LOCK_MB;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calling cpuid with 0x80000000 as the in argument
|
|
||||||
// gets the number of valid extended IDs.
|
|
||||||
|
|
||||||
cpuid(0x80000000, &out);
|
|
||||||
|
|
||||||
uint32_t exIds = out.eax;
|
|
||||||
if (exIds > 0x80000004) exIds = 0x80000004;
|
|
||||||
|
|
||||||
uint32_t* brand = reinterpret_cast<uint32_t*>(i->brand);
|
|
||||||
|
|
||||||
for (a = 0x80000001; a <= exIds; a++)
|
|
||||||
{
|
|
||||||
cpuid(a, &out);
|
|
||||||
|
|
||||||
switch (a)
|
|
||||||
{
|
|
||||||
case 0x80000001:
|
|
||||||
if (out.ecx & 0x00000001U) i->features |= CPU_FEATURE_LAHF_SAHF;
|
|
||||||
if (out.ecx & 0x00000020U) i->features |= CPU_FEATURE_LZCNT;
|
|
||||||
if (out.ecx & 0x00000040U) i->features |= CPU_FEATURE_SSE4_A;
|
|
||||||
if (out.ecx & 0x00000080U) i->features |= CPU_FEATURE_MSSE;
|
|
||||||
if (out.ecx & 0x00000100U) i->features |= CPU_FEATURE_PREFETCH;
|
|
||||||
|
|
||||||
if (out.edx & 0x00100000U) i->features |= CPU_FEATURE_EXECUTE_DISABLE_BIT;
|
|
||||||
if (out.edx & 0x00200000U) i->features |= CPU_FEATURE_FFXSR;
|
|
||||||
if (out.edx & 0x00400000U) i->features |= CPU_FEATURE_MMX_EXT;
|
|
||||||
if (out.edx & 0x08000000U) i->features |= CPU_FEATURE_RDTSCP;
|
|
||||||
if (out.edx & 0x20000000U) i->features |= CPU_FEATURE_64_BIT;
|
|
||||||
if (out.edx & 0x40000000U) i->features |= CPU_FEATURE_3DNOW_EXT | CPU_FEATURE_MMX_EXT;
|
|
||||||
if (out.edx & 0x80000000U) i->features |= CPU_FEATURE_3DNOW;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x80000002:
|
|
||||||
case 0x80000003:
|
|
||||||
case 0x80000004:
|
|
||||||
*brand++ = out.eax;
|
|
||||||
*brand++ = out.ebx;
|
|
||||||
*brand++ = out.ecx;
|
|
||||||
*brand++ = out.edx;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Additional features can be detected in the future.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simplify the brand string (remove unnecessary spaces to make it printable).
|
|
||||||
simplifyBrandString(i->brand);
|
|
||||||
|
|
||||||
#endif // ASMJIT_X86 || ASMJIT_X64
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void detectCpuInfo(CpuInfo* i) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
memset(i, 0, sizeof(CpuInfo));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct ASMJIT_HIDDEN CpuInfoStatic
|
|
||||||
{
|
|
||||||
CpuInfoStatic() ASMJIT_NOTHROW { detectCpuInfo(&i); }
|
|
||||||
|
|
||||||
CpuInfo i;
|
|
||||||
};
|
|
||||||
|
|
||||||
CpuInfo* getCpuInfo() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
static CpuInfoStatic i;
|
|
||||||
return &i.i;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // AsmJit
|
|
||||||
|
|
||||||
// [Api-End]
|
|
||||||
#include "ApiEnd.h"
|
|
|
@ -1,226 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#ifndef _ASMJIT_CPUINFO_H
|
|
||||||
#define _ASMJIT_CPUINFO_H
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include "Build.h"
|
|
||||||
|
|
||||||
// [Api-Begin]
|
|
||||||
#include "ApiBegin.h"
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
//! @addtogroup AsmJit_CpuInfo
|
|
||||||
//! @{
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::CpuId]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
|
||||||
//! @brief Structure (union) used by cpuid() function.
|
|
||||||
union CpuId
|
|
||||||
{
|
|
||||||
//! @brief cpuid results array(eax, ebx, ecx and edx registers).
|
|
||||||
uint32_t i[4];
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
//! @brief cpuid result in eax register.
|
|
||||||
uint32_t eax;
|
|
||||||
//! @brief cpuid result in ebx register.
|
|
||||||
uint32_t ebx;
|
|
||||||
//! @brief cpuid result in ecx register.
|
|
||||||
uint32_t ecx;
|
|
||||||
//! @brief cpuid result in edx register.
|
|
||||||
uint32_t edx;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Calls CPUID instruction with eax == @a in and returns result to @a out.
|
|
||||||
//!
|
|
||||||
//! @c cpuid() function has one input parameter that is passed to cpuid through
|
|
||||||
//! eax register and results in four output values representing result of cpuid
|
|
||||||
//! instruction (eax, ebx, ecx and edx registers).
|
|
||||||
ASMJIT_API void cpuid(uint32_t in, CpuId* out) ASMJIT_NOTHROW;
|
|
||||||
#endif // ASMJIT_X86 || ASMJIT_X64
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::CPU_VENDOR]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Cpu vendor IDs.
|
|
||||||
//!
|
|
||||||
//! Cpu vendor IDs are specific for AsmJit library. Vendor ID is not directly
|
|
||||||
//! read from cpuid result, instead it's based on CPU vendor string.
|
|
||||||
enum CPU_VENDOR
|
|
||||||
{
|
|
||||||
//! @brief Unknown CPU vendor.
|
|
||||||
CPU_VENDOR_UNKNOWN = 0,
|
|
||||||
|
|
||||||
//! @brief Intel CPU vendor.
|
|
||||||
CPU_VENDOR_INTEL = 1,
|
|
||||||
//! @brief AMD CPU vendor.
|
|
||||||
CPU_VENDOR_AMD = 2,
|
|
||||||
//! @brief National Semiconductor CPU vendor (applies also to Cyrix processors).
|
|
||||||
CPU_VENDOR_NSM = 3,
|
|
||||||
//! @brief Transmeta CPU vendor.
|
|
||||||
CPU_VENDOR_TRANSMETA = 4,
|
|
||||||
//! @brief VIA CPU vendor.
|
|
||||||
CPU_VENDOR_VIA = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::CPU_FEATURE]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief X86/X64 CPU features.
|
|
||||||
enum CPU_FEATURE
|
|
||||||
{
|
|
||||||
//! @brief Cpu has RDTSC instruction.
|
|
||||||
CPU_FEATURE_RDTSC = 1U << 0,
|
|
||||||
//! @brief Cpu has RDTSCP instruction.
|
|
||||||
CPU_FEATURE_RDTSCP = 1U << 1,
|
|
||||||
//! @brief Cpu has CMOV instruction (conditional move)
|
|
||||||
CPU_FEATURE_CMOV = 1U << 2,
|
|
||||||
//! @brief Cpu has CMPXCHG8B instruction
|
|
||||||
CPU_FEATURE_CMPXCHG8B = 1U << 3,
|
|
||||||
//! @brief Cpu has CMPXCHG16B instruction (64-bit processors)
|
|
||||||
CPU_FEATURE_CMPXCHG16B = 1U << 4,
|
|
||||||
//! @brief Cpu has CLFUSH instruction
|
|
||||||
CPU_FEATURE_CLFLUSH = 1U << 5,
|
|
||||||
//! @brief Cpu has PREFETCH instruction
|
|
||||||
CPU_FEATURE_PREFETCH = 1U << 6,
|
|
||||||
//! @brief Cpu supports LAHF and SAHF instrictions.
|
|
||||||
CPU_FEATURE_LAHF_SAHF = 1U << 7,
|
|
||||||
//! @brief Cpu supports FXSAVE and FXRSTOR instructions.
|
|
||||||
CPU_FEATURE_FXSR = 1U << 8,
|
|
||||||
//! @brief Cpu supports FXSAVE and FXRSTOR instruction optimizations (FFXSR).
|
|
||||||
CPU_FEATURE_FFXSR = 1U << 9,
|
|
||||||
//! @brief Cpu has MMX.
|
|
||||||
CPU_FEATURE_MMX = 1U << 10,
|
|
||||||
//! @brief Cpu has extended MMX.
|
|
||||||
CPU_FEATURE_MMX_EXT = 1U << 11,
|
|
||||||
//! @brief Cpu has 3dNow!
|
|
||||||
CPU_FEATURE_3DNOW = 1U << 12,
|
|
||||||
//! @brief Cpu has enchanced 3dNow!
|
|
||||||
CPU_FEATURE_3DNOW_EXT = 1U << 13,
|
|
||||||
//! @brief Cpu has SSE.
|
|
||||||
CPU_FEATURE_SSE = 1U << 14,
|
|
||||||
//! @brief Cpu has SSE2.
|
|
||||||
CPU_FEATURE_SSE2 = 1U << 15,
|
|
||||||
//! @brief Cpu has SSE3.
|
|
||||||
CPU_FEATURE_SSE3 = 1U << 16,
|
|
||||||
//! @brief Cpu has Supplemental SSE3 (SSSE3).
|
|
||||||
CPU_FEATURE_SSSE3 = 1U << 17,
|
|
||||||
//! @brief Cpu has SSE4.A.
|
|
||||||
CPU_FEATURE_SSE4_A = 1U << 18,
|
|
||||||
//! @brief Cpu has SSE4.1.
|
|
||||||
CPU_FEATURE_SSE4_1 = 1U << 19,
|
|
||||||
//! @brief Cpu has SSE4.2.
|
|
||||||
CPU_FEATURE_SSE4_2 = 1U << 20,
|
|
||||||
//! @brief Cpu has AVX.
|
|
||||||
CPU_FEATURE_AVX = 1U << 22,
|
|
||||||
//! @brief Cpu has Misaligned SSE (MSSE).
|
|
||||||
CPU_FEATURE_MSSE = 1U << 23,
|
|
||||||
//! @brief Cpu supports MONITOR and MWAIT instructions.
|
|
||||||
CPU_FEATURE_MONITOR_MWAIT = 1U << 24,
|
|
||||||
//! @brief Cpu supports MOVBE instruction.
|
|
||||||
CPU_FEATURE_MOVBE = 1U << 25,
|
|
||||||
//! @brief Cpu supports POPCNT instruction.
|
|
||||||
CPU_FEATURE_POPCNT = 1U << 26,
|
|
||||||
//! @brief Cpu supports LZCNT instruction.
|
|
||||||
CPU_FEATURE_LZCNT = 1U << 27,
|
|
||||||
//! @brief Cpu supports PCLMULDQ set of instructions.
|
|
||||||
CPU_FEATURE_PCLMULDQ = 1U << 28,
|
|
||||||
//! @brief Cpu supports multithreading.
|
|
||||||
CPU_FEATURE_MULTI_THREADING = 1U << 29,
|
|
||||||
//! @brief Cpu supports execute disable bit (execute protection).
|
|
||||||
CPU_FEATURE_EXECUTE_DISABLE_BIT = 1U << 30,
|
|
||||||
//! @brief 64-bit CPU.
|
|
||||||
CPU_FEATURE_64_BIT = 1U << 31
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::CPU_BUG]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief X86/X64 CPU bugs.
|
|
||||||
enum CPU_BUG
|
|
||||||
{
|
|
||||||
//! @brief Whether the processor contains bug seen in some
|
|
||||||
//! AMD-Opteron processors.
|
|
||||||
CPU_BUG_AMD_LOCK_MB = 1U << 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::CpuInfo]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Informations about host cpu.
|
|
||||||
struct ASMJIT_HIDDEN CpuInfo
|
|
||||||
{
|
|
||||||
//! @brief Cpu short vendor string.
|
|
||||||
char vendor[16];
|
|
||||||
//! @brief Cpu long vendor string (brand).
|
|
||||||
char brand[64];
|
|
||||||
//! @brief Cpu vendor id (see @c AsmJit::CpuInfo::VendorId enum).
|
|
||||||
uint32_t vendorId;
|
|
||||||
//! @brief Cpu family ID.
|
|
||||||
uint32_t family;
|
|
||||||
//! @brief Cpu model ID.
|
|
||||||
uint32_t model;
|
|
||||||
//! @brief Cpu stepping.
|
|
||||||
uint32_t stepping;
|
|
||||||
//! @brief Number of processors or cores.
|
|
||||||
uint32_t numberOfProcessors;
|
|
||||||
//! @brief Cpu features bitfield, see @c AsmJit::CpuInfo::Feature enum).
|
|
||||||
uint32_t features;
|
|
||||||
//! @brief Cpu bugs bitfield, see @c AsmJit::CpuInfo::Bug enum).
|
|
||||||
uint32_t bugs;
|
|
||||||
|
|
||||||
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
|
||||||
//! @brief Extended information for x86/x64 compatible processors.
|
|
||||||
struct X86ExtendedInfo
|
|
||||||
{
|
|
||||||
//! @brief Processor type.
|
|
||||||
uint32_t processorType;
|
|
||||||
//! @brief Brand index.
|
|
||||||
uint32_t brandIndex;
|
|
||||||
//! @brief Flush cache line size in bytes.
|
|
||||||
uint32_t flushCacheLineSize;
|
|
||||||
//! @brief Maximum number of addressable IDs for logical processors.
|
|
||||||
uint32_t maxLogicalProcessors;
|
|
||||||
//! @brief Initial APIC ID.
|
|
||||||
uint32_t apicPhysicalId;
|
|
||||||
};
|
|
||||||
//! @brief Extended information for x86/x64 compatible processors.
|
|
||||||
X86ExtendedInfo x86ExtendedInfo;
|
|
||||||
#endif // ASMJIT_X86 || ASMJIT_X64
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Detect CPU features to CpuInfo structure @a i.
|
|
||||||
//!
|
|
||||||
//! @sa @c CpuInfo.
|
|
||||||
ASMJIT_API void detectCpuInfo(CpuInfo* i) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Return CpuInfo (detection is done only once).
|
|
||||||
//!
|
|
||||||
//! @sa @c CpuInfo.
|
|
||||||
ASMJIT_API CpuInfo* getCpuInfo() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @}
|
|
||||||
|
|
||||||
} // AsmJit namespace
|
|
||||||
|
|
||||||
// [Api-End]
|
|
||||||
#include "ApiEnd.h"
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#endif // _ASMJIT_CPUINFO_H
|
|
|
@ -1,416 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#ifndef _ASMJIT_DEFS_H
|
|
||||||
#define _ASMJIT_DEFS_H
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include "Build.h"
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
//! @addtogroup AsmJit_Core
|
|
||||||
//! @{
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::ENUM]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Uncategorized constants.
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
//! @brief Invalid operand identifier.
|
|
||||||
INVALID_VALUE = 0xFFFFFFFF,
|
|
||||||
|
|
||||||
//! @brief Maximum allowed arguments per function declaration / call.
|
|
||||||
FUNC_MAX_ARGS = 32
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::MEMORY_ALLOC_TYPE]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Types of allocation used by @c AsmJit::MemoryManager::alloc() method.
|
|
||||||
enum MEMORY_ALLOC_TYPE
|
|
||||||
{
|
|
||||||
//! @brief Allocate memory that can be freed by @c AsmJit::MemoryManager::free()
|
|
||||||
//! method.
|
|
||||||
MEMORY_ALLOC_FREEABLE = 0,
|
|
||||||
//! @brief Allocate permanent memory that will be never freed.
|
|
||||||
MEMORY_ALLOC_PERMANENT = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::ERROR_CODE]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief AsmJit error codes.
|
|
||||||
enum ERROR_CODE
|
|
||||||
{
|
|
||||||
//! @brief No error (success).
|
|
||||||
//!
|
|
||||||
//! This is default state and state you want.
|
|
||||||
ERROR_NONE = 0,
|
|
||||||
|
|
||||||
//! @brief Memory allocation error (@c ASMJIT_MALLOC returned @c NULL).
|
|
||||||
ERROR_NO_HEAP_MEMORY = 1,
|
|
||||||
//! @brief Virtual memory allocation error (@c VirtualMemory returned @c NULL).
|
|
||||||
ERROR_NO_VIRTUAL_MEMORY = 2,
|
|
||||||
|
|
||||||
//! @brief Unknown instruction. This happens only if instruction code is
|
|
||||||
//! out of bounds. Shouldn't happen.
|
|
||||||
ERROR_UNKNOWN_INSTRUCTION = 3,
|
|
||||||
//! @brief Illegal instruction, usually generated by AsmJit::AssemblerCore
|
|
||||||
//! class when emitting instruction opcode. If this error is generated the
|
|
||||||
//! target buffer is not affected by this invalid instruction.
|
|
||||||
//!
|
|
||||||
//! You can also get this error code if you are under x64 (64-bit x86) and
|
|
||||||
//! you tried to decode instruction using AH, BH, CH or DH register with REX
|
|
||||||
//! prefix. These registers can't be accessed if REX prefix is used and AsmJit
|
|
||||||
//! didn't check for this situation in intrinsics (@c Compiler takes care of
|
|
||||||
//! this and rearrange registers if needed).
|
|
||||||
//!
|
|
||||||
//! Examples that will raise @c ERROR_ILLEGAL_INSTRUCTION error (a is
|
|
||||||
//! @c Assembler instance):
|
|
||||||
//!
|
|
||||||
//! @code
|
|
||||||
//! a.mov(dword_ptr(eax), al); // Invalid address size.
|
|
||||||
//! a.mov(byte_ptr(r10), ah); // Undecodable instruction (AH used with r10
|
|
||||||
//! // which can be encoded only using REX prefix)
|
|
||||||
//! @endcode
|
|
||||||
//!
|
|
||||||
//! @note In debug mode you get assertion failure instead of setting error
|
|
||||||
//! code.
|
|
||||||
ERROR_ILLEGAL_INSTRUCTION = 4,
|
|
||||||
//! @brief Illegal addressing used (unencodable).
|
|
||||||
ERROR_ILLEGAL_ADDRESING = 5,
|
|
||||||
//! @brief Short jump instruction used, but displacement is out of bounds.
|
|
||||||
ERROR_ILLEGAL_SHORT_JUMP = 6,
|
|
||||||
|
|
||||||
//! @brief No function defined.
|
|
||||||
ERROR_NO_FUNCTION = 7,
|
|
||||||
//! @brief Function generation is not finished by using @c Compiler::endFunction()
|
|
||||||
//! or something bad happened during generation related to function. This can
|
|
||||||
//! be missing emittable, etc...
|
|
||||||
ERROR_INCOMPLETE_FUNCTION = 8,
|
|
||||||
|
|
||||||
//! @brief Compiler can't allocate registers, because all of them are used.
|
|
||||||
//!
|
|
||||||
//! @note AsmJit is able to spill registers so this error really shouldn't
|
|
||||||
//! happen unless all registers have priority 0 (which means never spill).
|
|
||||||
ERROR_NOT_ENOUGH_REGISTERS = 9,
|
|
||||||
//! @brief Compiler can't allocate one register to multiple destinations.
|
|
||||||
//!
|
|
||||||
//! This error can only happen using special instructions like cmpxchg8b and
|
|
||||||
//! others where there are more destination operands (implicit).
|
|
||||||
ERROR_REGISTERS_OVERLAP = 10,
|
|
||||||
|
|
||||||
//! @brief Tried to call function using incompatible argument.
|
|
||||||
ERROR_INCOMPATIBLE_ARGUMENT = 11,
|
|
||||||
//! @brief Incompatible return value.
|
|
||||||
ERROR_INCOMPATIBLE_RETURN_VALUE = 12,
|
|
||||||
|
|
||||||
//! @brief Count of error codes by AsmJit. Can grow in future.
|
|
||||||
_ERROR_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::OPERAND_TYPE]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Operand types that can be encoded in @c Op operand.
|
|
||||||
enum OPERAND_TYPE
|
|
||||||
{
|
|
||||||
//! @brief Operand is none, used only internally (not initialized Operand).
|
|
||||||
//!
|
|
||||||
//! This operand is not valid.
|
|
||||||
OPERAND_NONE = 0x00,
|
|
||||||
|
|
||||||
//! @brief Operand is register.
|
|
||||||
OPERAND_REG = 0x01,
|
|
||||||
//! @brief Operand is memory.
|
|
||||||
OPERAND_MEM = 0x02,
|
|
||||||
//! @brief Operand is immediate.
|
|
||||||
OPERAND_IMM = 0x04,
|
|
||||||
//! @brief Operand is label.
|
|
||||||
OPERAND_LABEL = 0x08,
|
|
||||||
//! @brief Operand is variable.
|
|
||||||
OPERAND_VAR = 0x10
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::OPERAND_MEM_TYPE]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Type of memory operand.
|
|
||||||
enum OPERAND_MEM_TYPE
|
|
||||||
{
|
|
||||||
//! @brief Operand is combination of register(s) and displacement (native).
|
|
||||||
OPERAND_MEM_NATIVE = 0,
|
|
||||||
//! @brief Operand is label.
|
|
||||||
OPERAND_MEM_LABEL = 1,
|
|
||||||
//! @brief Operand is absolute memory location (supported mainly in 32-bit
|
|
||||||
//! mode)
|
|
||||||
OPERAND_MEM_ABSOLUTE = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::OPERAND_ID]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Operand ID masks used to determine the operand type.
|
|
||||||
enum OPERAND_ID
|
|
||||||
{
|
|
||||||
//! @brief Operand id value mask (part used for IDs).
|
|
||||||
OPERAND_ID_VALUE_MASK = 0x3FFFFFFF,
|
|
||||||
//! @brief Operand id type mask (part used for operand type).
|
|
||||||
OPERAND_ID_TYPE_MASK = 0xC0000000,
|
|
||||||
//! @brief Label operand mark id.
|
|
||||||
OPERAND_ID_TYPE_LABEL = 0x40000000,
|
|
||||||
//! @brief Variable operand mark id.
|
|
||||||
OPERAND_ID_TYPE_VAR = 0x80000000
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::PROPERTY]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief @c Assembler/Compiler properties.
|
|
||||||
enum PROPERTY
|
|
||||||
{
|
|
||||||
//! @brief Optimize align for current processor.
|
|
||||||
//!
|
|
||||||
//! Default: @c true.
|
|
||||||
PROPERTY_OPTIMIZE_ALIGN = 0,
|
|
||||||
|
|
||||||
//! @brief Emit hints added to jcc() instructions.
|
|
||||||
//!
|
|
||||||
//! Default: @c true.
|
|
||||||
//!
|
|
||||||
//! @note This is X86/X64 property only.
|
|
||||||
PROPERTY_JUMP_HINTS = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::SIZE]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Size of registers and pointers.
|
|
||||||
enum SIZE
|
|
||||||
{
|
|
||||||
//! @brief 1 byte size.
|
|
||||||
SIZE_BYTE = 1,
|
|
||||||
//! @brief 2 bytes size.
|
|
||||||
SIZE_WORD = 2,
|
|
||||||
//! @brief 4 bytes size.
|
|
||||||
SIZE_DWORD = 4,
|
|
||||||
//! @brief 8 bytes size.
|
|
||||||
SIZE_QWORD = 8,
|
|
||||||
//! @brief 10 bytes size.
|
|
||||||
SIZE_TWORD = 10,
|
|
||||||
//! @brief 16 bytes size.
|
|
||||||
SIZE_DQWORD = 16
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [EMITTABLE_TYPE]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Emmitable type.
|
|
||||||
//!
|
|
||||||
//! For each emittable that is used by @c Compiler must be defined it's type.
|
|
||||||
//! Compiler can optimize instruction stream by analyzing emittables and each
|
|
||||||
//! type is hint for it. The most used emittables are instructions
|
|
||||||
//! (@c EMITTABLE_INSTRUCTION).
|
|
||||||
enum EMITTABLE_TYPE
|
|
||||||
{
|
|
||||||
//! @brief Emittable is invalid (can't be used).
|
|
||||||
EMITTABLE_NONE = 0,
|
|
||||||
//! @brief Emittable is dummy (used as a mark) (@ref EDummy).
|
|
||||||
EMITTABLE_DUMMY,
|
|
||||||
//! @brief Emittable is comment (no code) (@ref EComment).
|
|
||||||
EMITTABLE_COMMENT,
|
|
||||||
//! @brief Emittable is embedded data (@ref EData).
|
|
||||||
EMITTABLE_EMBEDDED_DATA,
|
|
||||||
//! @brief Emittable is .align directive (@ref EAlign).
|
|
||||||
EMITTABLE_ALIGN,
|
|
||||||
//! @brief Emittable is variable hint (alloc, spill, use, unuse, ...) (@ref EVariableHint).
|
|
||||||
EMITTABLE_VARIABLE_HINT,
|
|
||||||
//! @brief Emittable is single instruction (@ref EInstruction).
|
|
||||||
EMITTABLE_INSTRUCTION,
|
|
||||||
//! @brief Emittable is block of instructions.
|
|
||||||
EMITTABLE_BLOCK,
|
|
||||||
//! @brief Emittable is function declaration (@ref EFunction).
|
|
||||||
EMITTABLE_FUNCTION,
|
|
||||||
//! @brief Emittable is function prolog (@ref EProlog).
|
|
||||||
EMITTABLE_PROLOG,
|
|
||||||
//! @brief Emittable is function epilog (@ref EEpilog).
|
|
||||||
EMITTABLE_EPILOG,
|
|
||||||
//! @brief Emittable is end of function (@ref EFunctionEnd).
|
|
||||||
EMITTABLE_FUNCTION_END,
|
|
||||||
//! @brief Emittable is target (bound label).
|
|
||||||
EMITTABLE_TARGET,
|
|
||||||
//! @brief Emittable is jump table (@ref EJmp).
|
|
||||||
EMITTABLE_JUMP_TABLE,
|
|
||||||
//! @brief Emittable is function call (@ref ECall).
|
|
||||||
EMITTABLE_CALL,
|
|
||||||
//! @brief Emittable is return (@ref ERet).
|
|
||||||
EMITTABLE_RET
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::VARIABLE_STATE]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief State of variable.
|
|
||||||
//!
|
|
||||||
//! @note State of variable is used only during make process and it's not
|
|
||||||
//! visible to the developer.
|
|
||||||
enum VARIABLE_STATE
|
|
||||||
{
|
|
||||||
//! @brief Variable is currently not used.
|
|
||||||
VARIABLE_STATE_UNUSED = 0,
|
|
||||||
|
|
||||||
//! @brief Variable is in register.
|
|
||||||
//!
|
|
||||||
//! Variable is currently allocated in register.
|
|
||||||
VARIABLE_STATE_REGISTER = 1,
|
|
||||||
|
|
||||||
//! @brief Variable is in memory location or spilled.
|
|
||||||
//!
|
|
||||||
//! Variable was spilled from register to memory or variable is used for
|
|
||||||
//! memory only storage.
|
|
||||||
VARIABLE_STATE_MEMORY = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::VARIABLE_ALLOC_FLAGS]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Variable alloc mode.
|
|
||||||
enum VARIABLE_ALLOC
|
|
||||||
{
|
|
||||||
//! @brief Allocating variable to read only.
|
|
||||||
//!
|
|
||||||
//! Read only variables are used to optimize variable spilling. If variable
|
|
||||||
//! is some time ago deallocated and it's not marked as changed (so it was
|
|
||||||
//! all the life time read only) then spill is simply NOP (no mov instruction
|
|
||||||
//! is generated to move it to it's home memory location).
|
|
||||||
VARIABLE_ALLOC_READ = 0x01,
|
|
||||||
|
|
||||||
//! @brief Allocating variable to write only (overwrite).
|
|
||||||
//!
|
|
||||||
//! Overwriting means that if variable is in memory, there is no generated
|
|
||||||
//! instruction to move variable from memory to register, because that
|
|
||||||
//! register will be overwritten by next instruction. This is used as a
|
|
||||||
//! simple optimization to improve generated code by @c Compiler.
|
|
||||||
VARIABLE_ALLOC_WRITE = 0x02,
|
|
||||||
|
|
||||||
//! @brief Allocating variable to read / write.
|
|
||||||
//!
|
|
||||||
//! Variable allocated for read / write is marked as changed. This means that
|
|
||||||
//! if variable must be later spilled into memory, mov (or similar)
|
|
||||||
//! instruction will be generated.
|
|
||||||
VARIABLE_ALLOC_READWRITE = 0x03,
|
|
||||||
|
|
||||||
//! @brief Variable can be allocated in register.
|
|
||||||
VARIABLE_ALLOC_REGISTER = 0x04,
|
|
||||||
|
|
||||||
//! @brief Variable can be allocated in memory.
|
|
||||||
VARIABLE_ALLOC_MEMORY = 0x08,
|
|
||||||
|
|
||||||
//! @brief Unuse the variable after use.
|
|
||||||
VARIABLE_ALLOC_UNUSE_AFTER_USE = 0x10,
|
|
||||||
|
|
||||||
//! @brief Variable can be allocated only to one register (special allocation).
|
|
||||||
VARIABLE_ALLOC_SPECIAL = 0x20
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::VARIABLE_ALLOC_POLICY]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Variable allocation method.
|
|
||||||
//!
|
|
||||||
//! Variable allocation method is used by compiler and it means if compiler
|
|
||||||
//! should first allocate preserved registers or not. Preserved registers are
|
|
||||||
//! registers that must be saved / restored by generated function.
|
|
||||||
//!
|
|
||||||
//! This option is for people who are calling C/C++ functions from JIT code so
|
|
||||||
//! Compiler can recude generating push/pop sequences before and after call,
|
|
||||||
//! respectively.
|
|
||||||
enum VARIABLE_ALLOC_POLICY
|
|
||||||
{
|
|
||||||
//! @brief Allocate preserved registers first.
|
|
||||||
VARIABLE_ALLOC_PRESERVED_FIRST = 0,
|
|
||||||
//! @brief Allocate preserved registers last (default).
|
|
||||||
VARIABLE_ALLOC_PRESERVED_LAST = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::FUNCTION_HINT]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Function hints.
|
|
||||||
enum FUNCTION_HINT
|
|
||||||
{
|
|
||||||
//! @brief Use push/pop sequences instead of mov sequences in function prolog
|
|
||||||
//! and epilog.
|
|
||||||
FUNCTION_HINT_PUSH_POP_SEQUENCE = 0,
|
|
||||||
//! @brief Make naked function (without using ebp/erp in prolog / epilog).
|
|
||||||
FUNCTION_HINT_NAKED = 1,
|
|
||||||
//! @brief Add emms instruction to the function epilog.
|
|
||||||
FUNCTION_HINT_EMMS = 2,
|
|
||||||
//! @brief Add sfence instruction to the function epilog.
|
|
||||||
FUNCTION_HINT_SFENCE = 3,
|
|
||||||
//! @brief Add lfence instruction to the function epilog.
|
|
||||||
FUNCTION_HINT_LFENCE = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::ARGUMENT_DIR]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Arguments direction used by @c Function.
|
|
||||||
enum ARGUMENT_DIR
|
|
||||||
{
|
|
||||||
//! @brief Arguments are passed left to right.
|
|
||||||
//!
|
|
||||||
//! This arguments direction is unusual to C programming, it's used by pascal
|
|
||||||
//! compilers and in some calling conventions by Borland compiler).
|
|
||||||
ARGUMENT_DIR_LEFT_TO_RIGHT = 0,
|
|
||||||
//! @brief Arguments are passer right ro left
|
|
||||||
//!
|
|
||||||
//! This is default argument direction in C programming.
|
|
||||||
ARGUMENT_DIR_RIGHT_TO_LEFT = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::API]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Translates error code (see @c ERROR_CODE) into text representation.
|
|
||||||
ASMJIT_API const char* getErrorString(uint32_t error) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @}
|
|
||||||
|
|
||||||
} // AsmJit namespace
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [Platform Specific]
|
|
||||||
//
|
|
||||||
// Following enums must be declared by platform specific header:
|
|
||||||
// - CALL_CONV - Calling convention.
|
|
||||||
// - VARIABLE_TYPE - Variable type.
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
|
||||||
#include "DefsX86X64.h"
|
|
||||||
#endif // ASMJIT_X86 || ASMJIT_X64
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#endif // _ASMJIT_DEFS_H
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,92 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// We are using sprintf() here.
|
|
||||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
|
||||||
#endif // _MSC_VER
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include "Logger.h"
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
// [Api-Begin]
|
|
||||||
#include "ApiBegin.h"
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Logger]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
Logger::Logger() ASMJIT_NOTHROW :
|
|
||||||
_enabled(true),
|
|
||||||
_used(true),
|
|
||||||
_logBinary(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::~Logger() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::logFormat(const char* fmt, ...) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
char buf[1024];
|
|
||||||
sysuint_t len;
|
|
||||||
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
len = vsnprintf(buf, 1023, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
logString(buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::setEnabled(bool enabled) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
_enabled = enabled;
|
|
||||||
_used = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::FileLogger]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
FileLogger::FileLogger(FILE* stream) ASMJIT_NOTHROW
|
|
||||||
: _stream(NULL)
|
|
||||||
{
|
|
||||||
setStream(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileLogger::logString(const char* buf, sysuint_t len) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
if (!_used) return;
|
|
||||||
|
|
||||||
if (len == (sysuint_t)-1) len = strlen(buf);
|
|
||||||
fwrite(buf, 1, len, _stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileLogger::setEnabled(bool enabled) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
_enabled = enabled;
|
|
||||||
_used = (_enabled == true) & (_stream != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set file stream.
|
|
||||||
void FileLogger::setStream(FILE* stream) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
_stream = stream;
|
|
||||||
_used = (_enabled == true) & (_stream != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // AsmJit namespace
|
|
||||||
|
|
||||||
// [Api-End]
|
|
||||||
#include "ApiEnd.h"
|
|
|
@ -1,175 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#ifndef _ASMJIT_LOGGER_H
|
|
||||||
#define _ASMJIT_LOGGER_H
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include "Defs.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
// [Api-Begin]
|
|
||||||
#include "ApiBegin.h"
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
//! @addtogroup AsmJit_Logging
|
|
||||||
//! @{
|
|
||||||
|
|
||||||
//! @brief Abstract logging class.
|
|
||||||
//!
|
|
||||||
//! This class can be inherited and reimplemented to fit into your logging
|
|
||||||
//! subsystem. When reimplementing use @c AsmJit::Logger::log() method to
|
|
||||||
//! log into your stream.
|
|
||||||
//!
|
|
||||||
//! This class also contain @c _enabled member that can be used to enable
|
|
||||||
//! or disable logging.
|
|
||||||
struct ASMJIT_API Logger
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Construction / Destruction]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Create logger.
|
|
||||||
Logger() ASMJIT_NOTHROW;
|
|
||||||
//! @brief Destroy logger.
|
|
||||||
virtual ~Logger() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Logging]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Abstract method to log output.
|
|
||||||
//!
|
|
||||||
//! Default implementation that is in @c AsmJit::Logger is to do nothing.
|
|
||||||
//! It's virtual to fit to your logging system.
|
|
||||||
virtual void logString(const char* buf, sysuint_t len = (sysuint_t)-1) ASMJIT_NOTHROW = 0;
|
|
||||||
|
|
||||||
//! @brief Log formatter message (like sprintf) sending output to @c logString() method.
|
|
||||||
virtual void logFormat(const char* fmt, ...) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Enabled]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Return @c true if logging is enabled.
|
|
||||||
inline bool isEnabled() const ASMJIT_NOTHROW { return _enabled; }
|
|
||||||
|
|
||||||
//! @brief Set logging to enabled or disabled.
|
|
||||||
virtual void setEnabled(bool enabled) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Used]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Get whether the logger should be used.
|
|
||||||
inline bool isUsed() const ASMJIT_NOTHROW { return _used; }
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [LogBinary]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Get whether logging binary output.
|
|
||||||
inline bool getLogBinary() const { return _logBinary; }
|
|
||||||
//! @brief Get whether to log binary output.
|
|
||||||
inline void setLogBinary(bool val) { _logBinary = val; }
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Members]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//! @brief Whether logger is enabled or disabled.
|
|
||||||
//!
|
|
||||||
//! Default @c true.
|
|
||||||
bool _enabled;
|
|
||||||
|
|
||||||
//! @brief Whether logger is enabled and can be used.
|
|
||||||
//!
|
|
||||||
//! This value can be set by inherited classes to inform @c Logger that
|
|
||||||
//! assigned stream (or something that can log output) is invalid. If
|
|
||||||
//! @c _used is false it means that there is no logging output and AsmJit
|
|
||||||
//! shouldn't use this logger (because all messages will be lost).
|
|
||||||
//!
|
|
||||||
//! This is designed only to optimize cases that logger exists, but its
|
|
||||||
//! configured not to output messages. The API inside Logging and AsmJit
|
|
||||||
//! should only check this value when needed. The API outside AsmJit should
|
|
||||||
//! check only whether logging is @c _enabled.
|
|
||||||
//!
|
|
||||||
//! Default @c true.
|
|
||||||
bool _used;
|
|
||||||
|
|
||||||
//! @brief Whether to log instruction in binary form.
|
|
||||||
bool _logBinary;
|
|
||||||
|
|
||||||
private:
|
|
||||||
ASMJIT_DISABLE_COPY(Logger)
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Logger that can log to standard C @c FILE* stream.
|
|
||||||
struct ASMJIT_API FileLogger : public Logger
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Construction / Destruction]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Create new @c FileLogger.
|
|
||||||
//! @param stream FILE stream where logging will be sent (can be @c NULL
|
|
||||||
//! to disable logging).
|
|
||||||
FileLogger(FILE* stream = NULL) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Logging]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
virtual void logString(const char* buf, sysuint_t len = (sysuint_t)-1) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Enabled]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
virtual void setEnabled(bool enabled) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Stream]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Get @c FILE* stream.
|
|
||||||
//!
|
|
||||||
//! @note Return value can be @c NULL.
|
|
||||||
inline FILE* getStream() const ASMJIT_NOTHROW { return _stream; }
|
|
||||||
|
|
||||||
//! @brief Set @c FILE* stream.
|
|
||||||
//!
|
|
||||||
//! @param stream @c FILE stream where to log output (can be @c NULL to
|
|
||||||
//! disable logging).
|
|
||||||
void setStream(FILE* stream) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Members]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
protected:
|
|
||||||
//! @brief C file stream.
|
|
||||||
FILE* _stream;
|
|
||||||
|
|
||||||
ASMJIT_DISABLE_COPY(FileLogger)
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @}
|
|
||||||
|
|
||||||
} // AsmJit namespace
|
|
||||||
|
|
||||||
// [Api-End]
|
|
||||||
#include "ApiEnd.h"
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#endif // _ASMJIT_LOGGER_H
|
|
|
@ -1,34 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#ifndef _ASMJIT_OPERAND_H
|
|
||||||
#define _ASMJIT_OPERAND_H
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include "Build.h"
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
//! @addtogroup AsmJit_Core
|
|
||||||
//! @{
|
|
||||||
|
|
||||||
// There is currently no platform independent code.
|
|
||||||
|
|
||||||
//! @}
|
|
||||||
|
|
||||||
} // AsmJit namespace
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [Platform Specific]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
|
||||||
#include "OperandX86X64.h"
|
|
||||||
#endif // ASMJIT_X86 || ASMJIT_X64
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#endif // _ASMJIT_OPERAND_H
|
|
|
@ -1,425 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include "Defs.h"
|
|
||||||
#include "Operand.h"
|
|
||||||
|
|
||||||
// [Api-Begin]
|
|
||||||
#include "ApiBegin.h"
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Registers - no_reg]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
const GPReg no_reg(_Initialize(), INVALID_VALUE);
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Registers - 8-bit]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
const GPReg al(_Initialize(), REG_AL);
|
|
||||||
const GPReg cl(_Initialize(), REG_CL);
|
|
||||||
const GPReg dl(_Initialize(), REG_DL);
|
|
||||||
const GPReg bl(_Initialize(), REG_BL);
|
|
||||||
|
|
||||||
#if defined(ASMJIT_X64)
|
|
||||||
const GPReg spl(_Initialize(), REG_SPL);
|
|
||||||
const GPReg bpl(_Initialize(), REG_BPL);
|
|
||||||
const GPReg sil(_Initialize(), REG_SIL);
|
|
||||||
const GPReg dil(_Initialize(), REG_DIL);
|
|
||||||
|
|
||||||
const GPReg r8b(_Initialize(), REG_R8B);
|
|
||||||
const GPReg r9b(_Initialize(), REG_R9B);
|
|
||||||
const GPReg r10b(_Initialize(), REG_R10B);
|
|
||||||
const GPReg r11b(_Initialize(), REG_R11B);
|
|
||||||
const GPReg r12b(_Initialize(), REG_R12B);
|
|
||||||
const GPReg r13b(_Initialize(), REG_R13B);
|
|
||||||
const GPReg r14b(_Initialize(), REG_R14B);
|
|
||||||
const GPReg r15b(_Initialize(), REG_R15B);
|
|
||||||
#endif // ASMJIT_X64
|
|
||||||
|
|
||||||
const GPReg ah(_Initialize(), REG_AH);
|
|
||||||
const GPReg ch(_Initialize(), REG_CH);
|
|
||||||
const GPReg dh(_Initialize(), REG_DH);
|
|
||||||
const GPReg bh(_Initialize(), REG_BH);
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Registers - 16-bit]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
const GPReg ax(_Initialize(), REG_AX);
|
|
||||||
const GPReg cx(_Initialize(), REG_CX);
|
|
||||||
const GPReg dx(_Initialize(), REG_DX);
|
|
||||||
const GPReg bx(_Initialize(), REG_BX);
|
|
||||||
const GPReg sp(_Initialize(), REG_SP);
|
|
||||||
const GPReg bp(_Initialize(), REG_BP);
|
|
||||||
const GPReg si(_Initialize(), REG_SI);
|
|
||||||
const GPReg di(_Initialize(), REG_DI);
|
|
||||||
|
|
||||||
#if defined(ASMJIT_X64)
|
|
||||||
const GPReg r8w(_Initialize(), REG_R8W);
|
|
||||||
const GPReg r9w(_Initialize(), REG_R9W);
|
|
||||||
const GPReg r10w(_Initialize(), REG_R10W);
|
|
||||||
const GPReg r11w(_Initialize(), REG_R11W);
|
|
||||||
const GPReg r12w(_Initialize(), REG_R12W);
|
|
||||||
const GPReg r13w(_Initialize(), REG_R13W);
|
|
||||||
const GPReg r14w(_Initialize(), REG_R14W);
|
|
||||||
const GPReg r15w(_Initialize(), REG_R15W);
|
|
||||||
#endif // ASMJIT_X64
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Registers - 32-bit]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
const GPReg eax(_Initialize(), REG_EAX);
|
|
||||||
const GPReg ecx(_Initialize(), REG_ECX);
|
|
||||||
const GPReg edx(_Initialize(), REG_EDX);
|
|
||||||
const GPReg ebx(_Initialize(), REG_EBX);
|
|
||||||
const GPReg esp(_Initialize(), REG_ESP);
|
|
||||||
const GPReg ebp(_Initialize(), REG_EBP);
|
|
||||||
const GPReg esi(_Initialize(), REG_ESI);
|
|
||||||
const GPReg edi(_Initialize(), REG_EDI);
|
|
||||||
|
|
||||||
#if defined(ASMJIT_X64)
|
|
||||||
const GPReg r8d(_Initialize(), REG_R8D);
|
|
||||||
const GPReg r9d(_Initialize(), REG_R9D);
|
|
||||||
const GPReg r10d(_Initialize(), REG_R10D);
|
|
||||||
const GPReg r11d(_Initialize(), REG_R11D);
|
|
||||||
const GPReg r12d(_Initialize(), REG_R12D);
|
|
||||||
const GPReg r13d(_Initialize(), REG_R13D);
|
|
||||||
const GPReg r14d(_Initialize(), REG_R14D);
|
|
||||||
const GPReg r15d(_Initialize(), REG_R15D);
|
|
||||||
#endif // ASMJIT_X64
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Registers - 64-bit]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
#if defined(ASMJIT_X64)
|
|
||||||
const GPReg rax(_Initialize(), REG_RAX);
|
|
||||||
const GPReg rcx(_Initialize(), REG_RCX);
|
|
||||||
const GPReg rdx(_Initialize(), REG_RDX);
|
|
||||||
const GPReg rbx(_Initialize(), REG_RBX);
|
|
||||||
const GPReg rsp(_Initialize(), REG_RSP);
|
|
||||||
const GPReg rbp(_Initialize(), REG_RBP);
|
|
||||||
const GPReg rsi(_Initialize(), REG_RSI);
|
|
||||||
const GPReg rdi(_Initialize(), REG_RDI);
|
|
||||||
|
|
||||||
const GPReg r8(_Initialize(), REG_R8);
|
|
||||||
const GPReg r9(_Initialize(), REG_R9);
|
|
||||||
const GPReg r10(_Initialize(), REG_R10);
|
|
||||||
const GPReg r11(_Initialize(), REG_R11);
|
|
||||||
const GPReg r12(_Initialize(), REG_R12);
|
|
||||||
const GPReg r13(_Initialize(), REG_R13);
|
|
||||||
const GPReg r14(_Initialize(), REG_R14);
|
|
||||||
const GPReg r15(_Initialize(), REG_R15);
|
|
||||||
#endif // ASMJIT_X64
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Registers - Native (AsmJit extension)]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
const GPReg nax(_Initialize(), REG_NAX);
|
|
||||||
const GPReg ncx(_Initialize(), REG_NCX);
|
|
||||||
const GPReg ndx(_Initialize(), REG_NDX);
|
|
||||||
const GPReg nbx(_Initialize(), REG_NBX);
|
|
||||||
const GPReg nsp(_Initialize(), REG_NSP);
|
|
||||||
const GPReg nbp(_Initialize(), REG_NBP);
|
|
||||||
const GPReg nsi(_Initialize(), REG_NSI);
|
|
||||||
const GPReg ndi(_Initialize(), REG_NDI);
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Registers - MM]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
const MMReg mm0(_Initialize(), REG_MM0);
|
|
||||||
const MMReg mm1(_Initialize(), REG_MM1);
|
|
||||||
const MMReg mm2(_Initialize(), REG_MM2);
|
|
||||||
const MMReg mm3(_Initialize(), REG_MM3);
|
|
||||||
const MMReg mm4(_Initialize(), REG_MM4);
|
|
||||||
const MMReg mm5(_Initialize(), REG_MM5);
|
|
||||||
const MMReg mm6(_Initialize(), REG_MM6);
|
|
||||||
const MMReg mm7(_Initialize(), REG_MM7);
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Registers - XMM]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
const XMMReg xmm0(_Initialize(), REG_XMM0);
|
|
||||||
const XMMReg xmm1(_Initialize(), REG_XMM1);
|
|
||||||
const XMMReg xmm2(_Initialize(), REG_XMM2);
|
|
||||||
const XMMReg xmm3(_Initialize(), REG_XMM3);
|
|
||||||
const XMMReg xmm4(_Initialize(), REG_XMM4);
|
|
||||||
const XMMReg xmm5(_Initialize(), REG_XMM5);
|
|
||||||
const XMMReg xmm6(_Initialize(), REG_XMM6);
|
|
||||||
const XMMReg xmm7(_Initialize(), REG_XMM7);
|
|
||||||
|
|
||||||
#if defined(ASMJIT_X64)
|
|
||||||
const XMMReg xmm8(_Initialize(), REG_XMM8);
|
|
||||||
const XMMReg xmm9(_Initialize(), REG_XMM9);
|
|
||||||
const XMMReg xmm10(_Initialize(), REG_XMM10);
|
|
||||||
const XMMReg xmm11(_Initialize(), REG_XMM11);
|
|
||||||
const XMMReg xmm12(_Initialize(), REG_XMM12);
|
|
||||||
const XMMReg xmm13(_Initialize(), REG_XMM13);
|
|
||||||
const XMMReg xmm14(_Initialize(), REG_XMM14);
|
|
||||||
const XMMReg xmm15(_Initialize(), REG_XMM15);
|
|
||||||
#endif // ASMJIT_X64
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Registers - Segment]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
const SegmentReg cs(_Initialize(), REG_CS);
|
|
||||||
const SegmentReg ss(_Initialize(), REG_SS);
|
|
||||||
const SegmentReg ds(_Initialize(), REG_DS);
|
|
||||||
const SegmentReg es(_Initialize(), REG_ES);
|
|
||||||
const SegmentReg fs(_Initialize(), REG_FS);
|
|
||||||
const SegmentReg gs(_Initialize(), REG_GS);
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Immediate]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Create signed immediate value operand.
|
|
||||||
Imm imm(sysint_t i) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return Imm(i, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Create unsigned immediate value operand.
|
|
||||||
Imm uimm(sysuint_t i) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return Imm((sysint_t)i, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::BaseVar]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
Mem _BaseVarMem(const BaseVar& var, uint32_t ptrSize) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
Mem m; //(_DontInitialize());
|
|
||||||
|
|
||||||
m._mem.op = OPERAND_MEM;
|
|
||||||
m._mem.size = (ptrSize == INVALID_VALUE) ? var.getSize() : (uint8_t)ptrSize;
|
|
||||||
m._mem.type = OPERAND_MEM_NATIVE;
|
|
||||||
m._mem.segmentPrefix = SEGMENT_NONE;
|
|
||||||
m._mem.sizePrefix = 0;
|
|
||||||
m._mem.shift = 0;
|
|
||||||
|
|
||||||
m._mem.id = var.getId();
|
|
||||||
m._mem.base = INVALID_VALUE;
|
|
||||||
m._mem.index = INVALID_VALUE;
|
|
||||||
|
|
||||||
m._mem.target = NULL;
|
|
||||||
m._mem.displacement = 0;
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Mem _BaseVarMem(const BaseVar& var, uint32_t ptrSize, sysint_t disp) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
Mem m; //(_DontInitialize());
|
|
||||||
|
|
||||||
m._mem.op = OPERAND_MEM;
|
|
||||||
m._mem.size = (ptrSize == INVALID_VALUE) ? var.getSize() : (uint8_t)ptrSize;
|
|
||||||
m._mem.type = OPERAND_MEM_NATIVE;
|
|
||||||
m._mem.segmentPrefix = SEGMENT_NONE;
|
|
||||||
m._mem.sizePrefix = 0;
|
|
||||||
m._mem.shift = 0;
|
|
||||||
|
|
||||||
m._mem.id = var.getId();
|
|
||||||
|
|
||||||
m._mem.base = INVALID_VALUE;
|
|
||||||
m._mem.index = INVALID_VALUE;
|
|
||||||
|
|
||||||
m._mem.target = NULL;
|
|
||||||
m._mem.displacement = disp;
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mem _BaseVarMem(const BaseVar& var, uint32_t ptrSize, const GPVar& index, uint32_t shift, sysint_t disp) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
Mem m; //(_DontInitialize());
|
|
||||||
|
|
||||||
m._mem.op = OPERAND_MEM;
|
|
||||||
m._mem.size = (ptrSize == INVALID_VALUE) ? var.getSize() : (uint8_t)ptrSize;
|
|
||||||
m._mem.type = OPERAND_MEM_NATIVE;
|
|
||||||
m._mem.segmentPrefix = SEGMENT_NONE;
|
|
||||||
m._mem.sizePrefix = 0;
|
|
||||||
m._mem.shift = shift;
|
|
||||||
|
|
||||||
m._mem.id = var.getId();
|
|
||||||
|
|
||||||
m._mem.base = INVALID_VALUE;
|
|
||||||
m._mem.index = index.getId();
|
|
||||||
|
|
||||||
m._mem.target = NULL;
|
|
||||||
m._mem.displacement = disp;
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Mem - ptr[]]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
Mem _MemPtrBuild(
|
|
||||||
const Label& label, sysint_t disp, uint32_t ptrSize)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return Mem(label, disp, ptrSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
Mem _MemPtrBuild(
|
|
||||||
const Label& label,
|
|
||||||
const GPReg& index, uint32_t shift, sysint_t disp, uint32_t ptrSize)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
Mem m(label, disp, ptrSize);
|
|
||||||
|
|
||||||
m._mem.index = index.getRegIndex();
|
|
||||||
m._mem.shift = shift;
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mem _MemPtrBuild(
|
|
||||||
const Label& label,
|
|
||||||
const GPVar& index, uint32_t shift, sysint_t disp, uint32_t ptrSize)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
Mem m(label, disp, ptrSize);
|
|
||||||
|
|
||||||
m._mem.index = index.getId();
|
|
||||||
m._mem.shift = shift;
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Mem - ptr[] - Absolute Addressing]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
ASMJIT_API Mem _MemPtrAbs(
|
|
||||||
void* target, sysint_t disp,
|
|
||||||
uint32_t segmentPrefix, uint32_t ptrSize)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
Mem m;
|
|
||||||
|
|
||||||
m._mem.size = ptrSize;
|
|
||||||
m._mem.type = OPERAND_MEM_ABSOLUTE;
|
|
||||||
m._mem.segmentPrefix = segmentPrefix;
|
|
||||||
|
|
||||||
m._mem.target = target;
|
|
||||||
m._mem.displacement = disp;
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASMJIT_API Mem _MemPtrAbs(
|
|
||||||
void* target,
|
|
||||||
const GPReg& index, uint32_t shift, sysint_t disp,
|
|
||||||
uint32_t segmentPrefix, uint32_t ptrSize)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
Mem m;// (_DontInitialize());
|
|
||||||
|
|
||||||
m._mem.op = OPERAND_MEM;
|
|
||||||
m._mem.size = ptrSize;
|
|
||||||
m._mem.type = OPERAND_MEM_ABSOLUTE;
|
|
||||||
m._mem.segmentPrefix = (uint8_t)segmentPrefix;
|
|
||||||
|
|
||||||
#if defined(ASMJIT_X86)
|
|
||||||
m._mem.sizePrefix = index.getSize() != 4;
|
|
||||||
#else
|
|
||||||
m._mem.sizePrefix = index.getSize() != 8;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m._mem.shift = shift;
|
|
||||||
|
|
||||||
m._mem.id = INVALID_VALUE;
|
|
||||||
m._mem.base = INVALID_VALUE;
|
|
||||||
m._mem.index = index.getRegIndex();
|
|
||||||
|
|
||||||
m._mem.target = target;
|
|
||||||
m._mem.displacement = disp;
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASMJIT_API Mem _MemPtrAbs(
|
|
||||||
void* target,
|
|
||||||
const GPVar& index, uint32_t shift, sysint_t disp,
|
|
||||||
uint32_t segmentPrefix, uint32_t ptrSize)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
Mem m;// (_DontInitialize());
|
|
||||||
|
|
||||||
m._mem.op = OPERAND_MEM;
|
|
||||||
m._mem.size = ptrSize;
|
|
||||||
m._mem.type = OPERAND_MEM_ABSOLUTE;
|
|
||||||
m._mem.segmentPrefix = (uint8_t)segmentPrefix;
|
|
||||||
|
|
||||||
#if defined(ASMJIT_X86)
|
|
||||||
m._mem.sizePrefix = index.getSize() != 4;
|
|
||||||
#else
|
|
||||||
m._mem.sizePrefix = index.getSize() != 8;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m._mem.shift = shift;
|
|
||||||
|
|
||||||
m._mem.id = INVALID_VALUE;
|
|
||||||
m._mem.base = INVALID_VALUE;
|
|
||||||
m._mem.index = index.getId();
|
|
||||||
|
|
||||||
m._mem.target = target;
|
|
||||||
m._mem.displacement = disp;
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Mem - ptr[base + displacement]]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
Mem _MemPtrBuild(
|
|
||||||
const GPReg& base, sysint_t disp, uint32_t ptrSize)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return Mem(base, disp, ptrSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
Mem _MemPtrBuild(
|
|
||||||
const GPReg& base,
|
|
||||||
const GPReg& index, uint32_t shift, sysint_t disp, uint32_t ptrSize)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return Mem(base, index, shift, disp, ptrSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
Mem _MemPtrBuild(
|
|
||||||
const GPVar& base, sysint_t disp, uint32_t ptrSize)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return Mem(base, disp, ptrSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
Mem _MemPtrBuild(
|
|
||||||
const GPVar& base,
|
|
||||||
const GPVar& index, uint32_t shift, sysint_t disp, uint32_t ptrSize)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return Mem(base, index, shift, disp, ptrSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // AsmJit namespace
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,222 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
|
|
||||||
// [Api-Begin]
|
|
||||||
#include "ApiBegin.h"
|
|
||||||
|
|
||||||
// helpers
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Assert]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
void assertionFailure(const char* file, int line, const char* exp)
|
|
||||||
{
|
|
||||||
fprintf(stderr,
|
|
||||||
"*** ASSERTION FAILURE at %s (line %d)\n"
|
|
||||||
"*** %s\n", file, line, exp);
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Helpers]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
static bool isAligned(sysuint_t base, sysuint_t alignment)
|
|
||||||
{
|
|
||||||
return base % alignment == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static sysuint_t roundUp(sysuint_t base, sysuint_t pageSize)
|
|
||||||
{
|
|
||||||
sysuint_t over = base % pageSize;
|
|
||||||
return base + (over > 0 ? pageSize - over : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
|
|
||||||
// figure 3-3, page 48, where the function is called clp2.
|
|
||||||
static sysuint_t roundUpToPowerOf2(sysuint_t base)
|
|
||||||
{
|
|
||||||
base -= 1;
|
|
||||||
|
|
||||||
base = base | (base >> 1);
|
|
||||||
base = base | (base >> 2);
|
|
||||||
base = base | (base >> 4);
|
|
||||||
base = base | (base >> 8);
|
|
||||||
base = base | (base >> 16);
|
|
||||||
|
|
||||||
// I'm trying to make this portable and MSVC strikes me the warning C4293:
|
|
||||||
// "Shift count negative or too big, undefined behavior"
|
|
||||||
// Fixing...
|
|
||||||
#if _MSC_VER
|
|
||||||
# pragma warning(disable: 4293)
|
|
||||||
#endif // _MSC_VER
|
|
||||||
|
|
||||||
if (sizeof(sysuint_t) >= 8)
|
|
||||||
base = base | (base >> 32);
|
|
||||||
|
|
||||||
return base + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // AsmJit namespace
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::VirtualMemory::Windows]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
#if defined(ASMJIT_WINDOWS)
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
struct ASMJIT_HIDDEN VirtualMemoryLocal
|
|
||||||
{
|
|
||||||
VirtualMemoryLocal() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
SYSTEM_INFO info;
|
|
||||||
GetSystemInfo(&info);
|
|
||||||
|
|
||||||
alignment = info.dwAllocationGranularity;
|
|
||||||
pageSize = roundUpToPowerOf2(info.dwPageSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
sysuint_t alignment;
|
|
||||||
sysuint_t pageSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
static VirtualMemoryLocal& vm() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
static VirtualMemoryLocal vm;
|
|
||||||
return vm;
|
|
||||||
};
|
|
||||||
|
|
||||||
void* VirtualMemory::alloc(sysuint_t length, sysuint_t* allocated, bool canExecute)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return allocProcessMemory(GetCurrentProcess(), length, allocated, canExecute);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualMemory::free(void* addr, sysuint_t length)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return freeProcessMemory(GetCurrentProcess(), addr, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* VirtualMemory::allocProcessMemory(HANDLE hProcess, sysuint_t length, sysuint_t* allocated, bool canExecute) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
// VirtualAlloc rounds allocated size to page size automatically.
|
|
||||||
sysuint_t msize = roundUp(length, vm().pageSize);
|
|
||||||
|
|
||||||
// Windows XP SP2 / Vista allow Data Excution Prevention (DEP).
|
|
||||||
WORD protect = canExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
|
|
||||||
LPVOID mbase = VirtualAllocEx(hProcess, NULL, msize, MEM_COMMIT | MEM_RESERVE, protect);
|
|
||||||
if (mbase == NULL) return NULL;
|
|
||||||
|
|
||||||
ASMJIT_ASSERT(isAligned(reinterpret_cast<sysuint_t>(mbase), vm().alignment));
|
|
||||||
|
|
||||||
if (allocated) *allocated = msize;
|
|
||||||
return mbase;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualMemory::freeProcessMemory(HANDLE hProcess, void* addr, sysuint_t /* length */) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
VirtualFreeEx(hProcess, addr, 0, MEM_RELEASE);
|
|
||||||
}
|
|
||||||
|
|
||||||
sysuint_t VirtualMemory::getAlignment()
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return vm().alignment;
|
|
||||||
}
|
|
||||||
|
|
||||||
sysuint_t VirtualMemory::getPageSize()
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return vm().pageSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // AsmJit
|
|
||||||
|
|
||||||
#endif // ASMJIT_WINDOWS
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::VirtualMemory::Posix]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
#if defined(ASMJIT_POSIX)
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
// MacOS uses MAP_ANON instead of MAP_ANONYMOUS
|
|
||||||
#ifndef MAP_ANONYMOUS
|
|
||||||
# define MAP_ANONYMOUS MAP_ANON
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
struct ASMJIT_HIDDEN VirtualMemoryLocal
|
|
||||||
{
|
|
||||||
VirtualMemoryLocal() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
alignment = pageSize = getpagesize();
|
|
||||||
}
|
|
||||||
|
|
||||||
sysuint_t alignment;
|
|
||||||
sysuint_t pageSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
static VirtualMemoryLocal& vm()
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
static VirtualMemoryLocal vm;
|
|
||||||
return vm;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* VirtualMemory::alloc(sysuint_t length, sysuint_t* allocated, bool canExecute)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sysuint_t msize = roundUp(length, vm().pageSize);
|
|
||||||
int protection = PROT_READ | PROT_WRITE | (canExecute ? PROT_EXEC : 0);
|
|
||||||
void* mbase = mmap(NULL, msize, protection, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
|
||||||
if (mbase == MAP_FAILED) return NULL;
|
|
||||||
if (allocated) *allocated = msize;
|
|
||||||
return mbase;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualMemory::free(void* addr, sysuint_t length)
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
munmap(addr, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
sysuint_t VirtualMemory::getAlignment()
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return vm().alignment;
|
|
||||||
}
|
|
||||||
|
|
||||||
sysuint_t VirtualMemory::getPageSize()
|
|
||||||
ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return vm().pageSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // AsmJit
|
|
||||||
|
|
||||||
#endif // ASMJIT_POSIX
|
|
||||||
|
|
||||||
// [Api-End]
|
|
||||||
#include "ApiEnd.h"
|
|
|
@ -1,208 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#ifndef _ASMJIT_PLATFORM_H
|
|
||||||
#define _ASMJIT_PLATFORM_H
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include "Build.h"
|
|
||||||
|
|
||||||
#if defined(ASMJIT_WINDOWS)
|
|
||||||
#include <windows.h>
|
|
||||||
#endif // ASMJIT_WINDOWS
|
|
||||||
|
|
||||||
#if defined(ASMJIT_POSIX)
|
|
||||||
#include <pthread.h>
|
|
||||||
#endif // ASMJIT_POSIX
|
|
||||||
|
|
||||||
// [Api-Begin]
|
|
||||||
#include "ApiBegin.h"
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
//! @addtogroup AsmJit_Util
|
|
||||||
//! @{
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Assert]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Called in debug build on assertion failure.
|
|
||||||
//! @param file Source file name where it happened.
|
|
||||||
//! @param line Line in the source file.
|
|
||||||
//! @param exp Expression what failed.
|
|
||||||
//!
|
|
||||||
//! If you have problems with assertions simply put a breakpoint into
|
|
||||||
//! AsmJit::assertionFailure() method (see AsmJit/Platform.cpp file) and see
|
|
||||||
//! call stack.
|
|
||||||
ASMJIT_API void assertionFailure(const char* file, int line, const char* exp);
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Lock]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Lock - used in thread-safe code for locking.
|
|
||||||
struct ASMJIT_HIDDEN Lock
|
|
||||||
{
|
|
||||||
#if defined(ASMJIT_WINDOWS)
|
|
||||||
typedef CRITICAL_SECTION Handle;
|
|
||||||
#endif // ASMJIT_WINDOWS
|
|
||||||
#if defined(ASMJIT_POSIX)
|
|
||||||
typedef pthread_mutex_t Handle;
|
|
||||||
#endif // ASMJIT_POSIX
|
|
||||||
|
|
||||||
//! @brief Create a new @ref Lock instance.
|
|
||||||
inline Lock() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
#if defined(ASMJIT_WINDOWS)
|
|
||||||
InitializeCriticalSection(&_handle);
|
|
||||||
// InitializeLockAndSpinCount(&_handle, 2000);
|
|
||||||
#endif // ASMJIT_WINDOWS
|
|
||||||
#if defined(ASMJIT_POSIX)
|
|
||||||
pthread_mutex_init(&_handle, NULL);
|
|
||||||
#endif // ASMJIT_POSIX
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Destroy the @ref Lock instance.
|
|
||||||
inline ~Lock() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
#if defined(ASMJIT_WINDOWS)
|
|
||||||
DeleteCriticalSection(&_handle);
|
|
||||||
#endif // ASMJIT_WINDOWS
|
|
||||||
#if defined(ASMJIT_POSIX)
|
|
||||||
pthread_mutex_destroy(&_handle);
|
|
||||||
#endif // ASMJIT_POSIX
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Get handle.
|
|
||||||
inline Handle& getHandle() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return _handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @overload
|
|
||||||
inline const Handle& getHandle() const ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return _handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Lock.
|
|
||||||
inline void lock() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
#if defined(ASMJIT_WINDOWS)
|
|
||||||
EnterCriticalSection(&_handle);
|
|
||||||
#endif // ASMJIT_WINDOWS
|
|
||||||
#if defined(ASMJIT_POSIX)
|
|
||||||
pthread_mutex_lock(&_handle);
|
|
||||||
#endif // ASMJIT_POSIX
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Unlock.
|
|
||||||
inline void unlock() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
#if defined(ASMJIT_WINDOWS)
|
|
||||||
LeaveCriticalSection(&_handle);
|
|
||||||
#endif // ASMJIT_WINDOWS
|
|
||||||
#if defined(ASMJIT_POSIX)
|
|
||||||
pthread_mutex_unlock(&_handle);
|
|
||||||
#endif // ASMJIT_POSIX
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
//! @brief Handle.
|
|
||||||
Handle _handle;
|
|
||||||
|
|
||||||
// Disable copy.
|
|
||||||
ASMJIT_DISABLE_COPY(Lock)
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::AutoLock]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Scope auto locker.
|
|
||||||
struct ASMJIT_HIDDEN AutoLock
|
|
||||||
{
|
|
||||||
//! @brief Locks @a target.
|
|
||||||
inline AutoLock(Lock& target) ASMJIT_NOTHROW : _target(target)
|
|
||||||
{
|
|
||||||
_target.lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Unlocks target.
|
|
||||||
inline ~AutoLock() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
_target.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
//! @brief Pointer to target (lock).
|
|
||||||
Lock& _target;
|
|
||||||
|
|
||||||
// Disable copy.
|
|
||||||
ASMJIT_DISABLE_COPY(AutoLock)
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::VirtualMemory]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Class that helps with allocating memory for executing code
|
|
||||||
//! generated by JIT compiler.
|
|
||||||
//!
|
|
||||||
//! There are defined functions that provides facility to allocate and free
|
|
||||||
//! memory where can be executed code. If processor and operating system
|
|
||||||
//! supports execution protection then you can't run code from normally
|
|
||||||
//! malloc()'ed memory.
|
|
||||||
//!
|
|
||||||
//! Functions are internally implemented by operating system dependent way.
|
|
||||||
//! VirtualAlloc() function is used for Windows operating system and mmap()
|
|
||||||
//! for posix ones. If you want to study or create your own functions, look
|
|
||||||
//! at VirtualAlloc() or mmap() documentation (depends on you target OS).
|
|
||||||
//!
|
|
||||||
//! Under posix operating systems is also useable mprotect() function, that
|
|
||||||
//! can enable execution protection to malloc()'ed memory block.
|
|
||||||
struct ASMJIT_API VirtualMemory
|
|
||||||
{
|
|
||||||
//! @brief Allocate virtual memory.
|
|
||||||
//!
|
|
||||||
//! Pages are readable/writeable, but they are not guaranteed to be
|
|
||||||
//! executable unless 'canExecute' is true. Returns the address of
|
|
||||||
//! allocated memory, or NULL if failed.
|
|
||||||
static void* alloc(sysuint_t length, sysuint_t* allocated, bool canExecute) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Free memory allocated by @c alloc()
|
|
||||||
static void free(void* addr, sysuint_t length) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
#if defined(ASMJIT_WINDOWS)
|
|
||||||
//! @brief Allocate virtual memory of @a hProcess.
|
|
||||||
//!
|
|
||||||
//! @note This function is windows specific and unportable.
|
|
||||||
static void* allocProcessMemory(HANDLE hProcess, sysuint_t length, sysuint_t* allocated, bool canExecute) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Free virtual memory of @a hProcess.
|
|
||||||
//!
|
|
||||||
//! @note This function is windows specific and unportable.
|
|
||||||
static void freeProcessMemory(HANDLE hProcess, void* addr, sysuint_t length) ASMJIT_NOTHROW;
|
|
||||||
#endif // ASMJIT_WINDOWS
|
|
||||||
|
|
||||||
//! @brief Get the alignment guaranteed by alloc().
|
|
||||||
static sysuint_t getAlignment() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Get size of single page.
|
|
||||||
static sysuint_t getPageSize() ASMJIT_NOTHROW;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @}
|
|
||||||
|
|
||||||
} // AsmJit namespace
|
|
||||||
|
|
||||||
// [Api-End]
|
|
||||||
#include "ApiEnd.h"
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#endif // _ASMJIT_PLATFORM_H
|
|
|
@ -1,115 +0,0 @@
|
||||||
AsmJit - Complete x86/x64 JIT Assembler for C++ Language - Version 1.0
|
|
||||||
======================================================================
|
|
||||||
|
|
||||||
http://code.google.com/p/asmjit/
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
============
|
|
||||||
|
|
||||||
AsmJit is complete x86/x64 JIT Assembler for C++ language. It supports FPU,
|
|
||||||
MMX, 3dNow, SSE, SSE2, SSE3 and SSE4 intrinsics, powerful compiler that helps
|
|
||||||
to write portable functions for 32-bit (x86) and 64-bit (x64) architectures.
|
|
||||||
AsmJit can be used to create functions at runtime that can be called from
|
|
||||||
existing (but also generated) C/C++ code.
|
|
||||||
|
|
||||||
AsmJit is crossplatform library that supports various compilers and operating
|
|
||||||
systems. Currently only limitation is x86 (32-bit) or x64 (64-bit) processor.
|
|
||||||
Currently tested operating systems are Windows (32 bit and 64 bit), Linux (32
|
|
||||||
bit and 64 bit) and MacOSX (32 bit).
|
|
||||||
|
|
||||||
Assembler / Compiler
|
|
||||||
====================
|
|
||||||
|
|
||||||
AsmJit library contains two main classes for code generation with different
|
|
||||||
goals. First main code generation class is called Assembler and contains low
|
|
||||||
level API that can be used to generate JIT binary code. It directly emits
|
|
||||||
binary stream that represents encoded x86/x64 assembler opcodes. Together
|
|
||||||
with operands and labels it can be used to generate complete code.
|
|
||||||
|
|
||||||
There is also class named Compiler that allows to develop crossplatform
|
|
||||||
assembler code without worring about function calling conventions and
|
|
||||||
registers allocation. It can be also used to write 32 bit and 64 bit portable
|
|
||||||
code. Compiler is recommended class to use for high level code generation.
|
|
||||||
|
|
||||||
Building & Configuring
|
|
||||||
======================
|
|
||||||
|
|
||||||
You have two choices when using AsmJit library:
|
|
||||||
|
|
||||||
1. Embed files into your project - This is simplest way how to use AsmJit
|
|
||||||
library. If you want to do this, edit AsmJit/Config.h file and undefine
|
|
||||||
"// #define ASMJIT_API" macro or define ASMJIT_API using your IDE or
|
|
||||||
makefiles (for example gcc can accept -DASMJIT_API to define it).
|
|
||||||
|
|
||||||
You will bypass shared library (dll) support by defining ASMJIT_API .
|
|
||||||
|
|
||||||
2. Build shared library and link your project to it. This is now default way
|
|
||||||
for using AsmJit library, but can be easily changed. To build dynamically
|
|
||||||
linked library use cmake (http://www.cmake.org/) that can generate
|
|
||||||
makefiles and project files for your IDE (included is Visual Studio,
|
|
||||||
Code::Blocks, Eclipse, KDevelop and more...).
|
|
||||||
|
|
||||||
To build shared library use this cmake command (or use provided scripts):
|
|
||||||
cmake {Replace this with AsmJit directory} DASMJIT_BUILD_LIBRARY=1
|
|
||||||
|
|
||||||
Directory structure
|
|
||||||
===================
|
|
||||||
|
|
||||||
AsmJit - Directory where are sources needed to compile AsmJit. This directory
|
|
||||||
is designed to be embeddable to your application as easy as possible. There is
|
|
||||||
also AsmJit/Config.h header where you can configure platform (if autodetection
|
|
||||||
not works for you) and application specific features. Look at platform macros
|
|
||||||
to change some backends to your preferences.
|
|
||||||
|
|
||||||
Test - Directory with cmake project to test AsmJit library. It generates simple
|
|
||||||
command line applications for testing AsmJit functionality. It's only here as a
|
|
||||||
demonstration how easy this can be done. These applications are also examples
|
|
||||||
how to use AsmJit API. For example look at testjit for simple code generation,
|
|
||||||
testcpu for cpuid() and cpuInfo() demonstration, testcompiler for compiler
|
|
||||||
example, etc...
|
|
||||||
|
|
||||||
Supported compilers
|
|
||||||
===================
|
|
||||||
|
|
||||||
AsmJit is successfully tested by following compilers:
|
|
||||||
- MSVC (VC6.0, VC7.1, VC8.0)
|
|
||||||
- GCC (3.4.X+ including MinGW and 4.1.X+, 4.3.X+, 4.4.X+)
|
|
||||||
|
|
||||||
If you are using different compiler and you have troubles, please use AsmJit
|
|
||||||
mailing list or create an Issue (see project home page).
|
|
||||||
|
|
||||||
Supported platforms
|
|
||||||
===================
|
|
||||||
|
|
||||||
Fully supported platforms at this time are X86 (32-bit) and X86_64/X64 (64-bit).
|
|
||||||
Other platforms need volunteers. Also note that AsmJit is designed to generate
|
|
||||||
assembler binary only for host CPU, don't try to generate 64-bit assembler in
|
|
||||||
32 bit mode and vica versa - this is not designed to work and will not work.
|
|
||||||
|
|
||||||
Examples
|
|
||||||
========
|
|
||||||
|
|
||||||
Examples and tests can be found in these places:
|
|
||||||
- AsmJit home page <http://code.google.com/p/asmjit/>
|
|
||||||
- AsmJit wiki <http://code.google.com/p/asmjit/w/list>
|
|
||||||
- AsmJit Test directory (in this package)
|
|
||||||
|
|
||||||
License
|
|
||||||
=======
|
|
||||||
|
|
||||||
AsmJit can be distributed under zlib license:
|
|
||||||
<http://www.opensource.org/licenses/zlib-license.php>
|
|
||||||
|
|
||||||
Google Groups and Mailing Lists
|
|
||||||
===============================
|
|
||||||
|
|
||||||
AsmJit google group:
|
|
||||||
* http://groups.google.com/group/asmjit-dev
|
|
||||||
|
|
||||||
AsmJit mailing list:
|
|
||||||
* asmjit-dev@googlegroups.com
|
|
||||||
|
|
||||||
Contact Author/Maintainer
|
|
||||||
=========================
|
|
||||||
|
|
||||||
Petr Kobalicek <kobalicek.petr@gmail.com>
|
|
|
@ -1,97 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# [Regenerate.py - Description]
|
|
||||||
#
|
|
||||||
# This Python script will regenerate instruction names in Assembler{$ARCH}.cpp
|
|
||||||
# files. Idea is that there can be big instruction table and this script tries
|
|
||||||
# to minimize runtime relocation data of AsmJit library.
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# [Configuration]
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# Files to process.
|
|
||||||
FILES = [
|
|
||||||
"DefsX86X64.cpp"
|
|
||||||
]
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# [Imports]
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
import os, re, string
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# [Helpers]
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
def readFile(fileName):
|
|
||||||
handle = open(fileName, "rb")
|
|
||||||
data = handle.read()
|
|
||||||
handle.close()
|
|
||||||
return data
|
|
||||||
|
|
||||||
def writeFile(fileName, data):
|
|
||||||
handle = open(fileName, "wb")
|
|
||||||
handle.truncate()
|
|
||||||
handle.write(data)
|
|
||||||
handle.close()
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# [Main]
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
def processFile(fileName):
|
|
||||||
data = readFile(fileName);
|
|
||||||
|
|
||||||
din = data
|
|
||||||
r = re.compile(r"instructionDescription\[\][\s]*=[\s]*{(?P<BLOCK>[^}])*}")
|
|
||||||
m = r.search(din)
|
|
||||||
|
|
||||||
if not m:
|
|
||||||
print "Cannot match instruction data in " + fileName
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
din = din[m.start():m.end()]
|
|
||||||
dout = ""
|
|
||||||
|
|
||||||
dinst = []
|
|
||||||
daddr = []
|
|
||||||
hinst = {}
|
|
||||||
|
|
||||||
r = re.compile(r'\"(?P<INST>[A-Za-z0-9_ ]+)\"')
|
|
||||||
dpos = 0
|
|
||||||
for m in r.finditer(din):
|
|
||||||
inst = m.group("INST")
|
|
||||||
|
|
||||||
if not inst in hinst:
|
|
||||||
dinst.append(inst)
|
|
||||||
hinst[inst] = dpos
|
|
||||||
|
|
||||||
daddr.append(dpos)
|
|
||||||
dpos += len(inst) + 1
|
|
||||||
|
|
||||||
dout += "const char instructionName[] =\n"
|
|
||||||
for i in xrange(len(dinst)):
|
|
||||||
dout += " \"" + dinst[i] + "\\0\"\n"
|
|
||||||
dout += " ;\n"
|
|
||||||
|
|
||||||
dout += "\n"
|
|
||||||
|
|
||||||
for i in xrange(len(dinst)):
|
|
||||||
dout += "#define INST_" + dinst[i].upper().replace(" ", "_") + "_INDEX" + " " + str(daddr[i]) + "\n"
|
|
||||||
|
|
||||||
mb_string = "// ${INSTRUCTION_DATA_BEGIN}\n"
|
|
||||||
me_string = "// ${INSTRUCTION_DATA_END}\n"
|
|
||||||
|
|
||||||
mb = data.index(mb_string)
|
|
||||||
me = data.index(me_string)
|
|
||||||
|
|
||||||
data = data[:mb + len(mb_string)] + dout + data[me:]
|
|
||||||
|
|
||||||
writeFile(fileName, data)
|
|
||||||
|
|
||||||
for fileName in FILES:
|
|
||||||
processFile(fileName)
|
|
|
@ -1,266 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include "Build.h"
|
|
||||||
#include "Util_p.h"
|
|
||||||
|
|
||||||
// [Api-Begin]
|
|
||||||
#include "ApiBegin.h"
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Util]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
static const char letters[] = "0123456789ABCDEF";
|
|
||||||
|
|
||||||
char* Util::mycpy(char* dst, const char* src, sysuint_t len) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
if (src == NULL) return dst;
|
|
||||||
|
|
||||||
if (len == (sysuint_t)-1)
|
|
||||||
{
|
|
||||||
while (*src) *dst++ = *src++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(dst, src, len);
|
|
||||||
dst += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* Util::myfill(char* dst, const int c, sysuint_t len) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
memset(dst, c, len);
|
|
||||||
return dst + len;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* Util::myhex(char* dst, const uint8_t* src, sysuint_t len) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
for (sysuint_t i = len; i; i--, dst += 2, src += 1)
|
|
||||||
{
|
|
||||||
dst[0] = letters[(src[0] >> 4) & 0xF];
|
|
||||||
dst[1] = letters[(src[0] ) & 0xF];
|
|
||||||
}
|
|
||||||
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not too efficient, but this is mainly for debugging:)
|
|
||||||
char* Util::myutoa(char* dst, sysuint_t i, sysuint_t base) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
ASMJIT_ASSERT(base <= 16);
|
|
||||||
|
|
||||||
char buf[128];
|
|
||||||
char* p = buf + 128;
|
|
||||||
|
|
||||||
do {
|
|
||||||
sysint_t b = i % base;
|
|
||||||
*--p = letters[b];
|
|
||||||
i /= base;
|
|
||||||
} while (i);
|
|
||||||
|
|
||||||
return Util::mycpy(dst, p, (sysuint_t)(buf + 128 - p));
|
|
||||||
}
|
|
||||||
|
|
||||||
char* Util::myitoa(char* dst, sysint_t i, sysuint_t base) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
if (i < 0)
|
|
||||||
{
|
|
||||||
*dst++ = '-';
|
|
||||||
i = -i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Util::myutoa(dst, (sysuint_t)i, base);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Buffer]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
void Buffer::emitData(const void* dataPtr, sysuint_t dataLen) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sysint_t max = getCapacity() - getOffset();
|
|
||||||
if ((sysuint_t)max < dataLen)
|
|
||||||
{
|
|
||||||
if (!realloc(getOffset() + dataLen)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(_cur, dataPtr, dataLen);
|
|
||||||
_cur += dataLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Buffer::realloc(sysint_t to) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
if (getCapacity() < to)
|
|
||||||
{
|
|
||||||
sysint_t len = getOffset();
|
|
||||||
|
|
||||||
uint8_t *newdata;
|
|
||||||
if (_data)
|
|
||||||
newdata = (uint8_t*)ASMJIT_REALLOC(_data, to);
|
|
||||||
else
|
|
||||||
newdata = (uint8_t*)ASMJIT_MALLOC(to);
|
|
||||||
if (!newdata) return false;
|
|
||||||
|
|
||||||
_data = newdata;
|
|
||||||
_cur = newdata + len;
|
|
||||||
_max = newdata + to;
|
|
||||||
_max -= (to >= _growThreshold) ? _growThreshold : to;
|
|
||||||
|
|
||||||
_capacity = to;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Buffer::grow() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sysint_t to = _capacity;
|
|
||||||
|
|
||||||
if (to < 512)
|
|
||||||
to = 1024;
|
|
||||||
else if (to > 65536)
|
|
||||||
to += 65536;
|
|
||||||
else
|
|
||||||
to <<= 1;
|
|
||||||
|
|
||||||
return realloc(to);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Buffer::clear() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
_cur = _data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Buffer::free() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
if (!_data) return;
|
|
||||||
ASMJIT_FREE(_data);
|
|
||||||
|
|
||||||
_data = NULL;
|
|
||||||
_cur = NULL;
|
|
||||||
_max = NULL;
|
|
||||||
_capacity = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* Buffer::take() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
uint8_t* data = _data;
|
|
||||||
|
|
||||||
_data = NULL;
|
|
||||||
_cur = NULL;
|
|
||||||
_max = NULL;
|
|
||||||
_capacity = 0;
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Zone]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
Zone::Zone(sysuint_t chunkSize) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
_chunks = NULL;
|
|
||||||
_total = 0;
|
|
||||||
_chunkSize = chunkSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
Zone::~Zone() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
freeAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
void* Zone::zalloc(sysuint_t size) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
// Align to 4 or 8 bytes.
|
|
||||||
size = (size + sizeof(sysint_t)-1) & ~(sizeof(sysint_t)-1);
|
|
||||||
|
|
||||||
Chunk* cur = _chunks;
|
|
||||||
|
|
||||||
if (!cur || cur->getRemainingBytes() < size)
|
|
||||||
{
|
|
||||||
sysuint_t chSize = _chunkSize;
|
|
||||||
if (chSize < size) chSize = size;
|
|
||||||
|
|
||||||
cur = (Chunk*)ASMJIT_MALLOC(sizeof(Chunk) - sizeof(void*) + chSize);
|
|
||||||
if (!cur) return NULL;
|
|
||||||
|
|
||||||
cur->prev = _chunks;
|
|
||||||
cur->pos = 0;
|
|
||||||
cur->size = _chunkSize;
|
|
||||||
_chunks = cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* p = cur->data + cur->pos;
|
|
||||||
cur->pos += size;
|
|
||||||
_total += size;
|
|
||||||
return (void*)p;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* Zone::zstrdup(const char* str) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
if (str == NULL) return NULL;
|
|
||||||
|
|
||||||
sysuint_t len = strlen(str);
|
|
||||||
if (len == 0) return NULL;
|
|
||||||
|
|
||||||
// Include NULL terminator.
|
|
||||||
len++;
|
|
||||||
|
|
||||||
// Limit string length.
|
|
||||||
if (len > 256) len = 256;
|
|
||||||
|
|
||||||
char* m = reinterpret_cast<char*>(zalloc((len + 15) & ~15));
|
|
||||||
if (!m) return NULL;
|
|
||||||
|
|
||||||
memcpy(m, str, len);
|
|
||||||
m[len-1] = '\0';
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Zone::clear() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
Chunk* cur = _chunks;
|
|
||||||
if (!cur) return;
|
|
||||||
|
|
||||||
_chunks->pos = 0;
|
|
||||||
_chunks->prev = NULL;
|
|
||||||
_total = 0;
|
|
||||||
|
|
||||||
cur = cur->prev;
|
|
||||||
while (cur)
|
|
||||||
{
|
|
||||||
Chunk* prev = cur->prev;
|
|
||||||
ASMJIT_FREE(cur);
|
|
||||||
cur = prev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Zone::freeAll() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
Chunk* cur = _chunks;
|
|
||||||
|
|
||||||
_chunks = NULL;
|
|
||||||
_total = 0;
|
|
||||||
|
|
||||||
while (cur)
|
|
||||||
{
|
|
||||||
Chunk* prev = cur->prev;
|
|
||||||
ASMJIT_FREE(cur);
|
|
||||||
cur = prev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // AsmJit namespace
|
|
||||||
|
|
||||||
// [Api-End]
|
|
||||||
#include "ApiEnd.h"
|
|
|
@ -1,914 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#ifndef _ASMJIT_UTIL_H
|
|
||||||
#define _ASMJIT_UTIL_H
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include "Build.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
//! @addtogroup AsmJit_Util
|
|
||||||
//! @{
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Macros]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
// Skip documenting this.
|
|
||||||
#if !defined(ASMJIT_NODOC)
|
|
||||||
struct ASMJIT_HIDDEN _DontInitialize {};
|
|
||||||
struct ASMJIT_HIDDEN _Initialize {};
|
|
||||||
#endif // !ASMJIT_NODOC
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Util]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
namespace Util {
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Util::isInt?]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Returns @c true if a given integer @a x is signed 8-bit integer
|
|
||||||
static inline bool isInt8(sysint_t x) ASMJIT_NOTHROW { return x >= -128 && x <= 127; }
|
|
||||||
//! @brief Returns @c true if a given integer @a x is unsigned 8-bit integer
|
|
||||||
static inline bool isUInt8(sysint_t x) ASMJIT_NOTHROW { return x >= 0 && x <= 255; }
|
|
||||||
|
|
||||||
//! @brief Returns @c true if a given integer @a x is signed 16-bit integer
|
|
||||||
static inline bool isInt16(sysint_t x) ASMJIT_NOTHROW { return x >= -32768 && x <= 32767; }
|
|
||||||
//! @brief Returns @c true if a given integer @a x is unsigned 16-bit integer
|
|
||||||
static inline bool isUInt16(sysint_t x) ASMJIT_NOTHROW { return x >= 0 && x <= 65535; }
|
|
||||||
|
|
||||||
//! @brief Returns @c true if a given integer @a x is signed 16-bit integer
|
|
||||||
static inline bool isInt32(sysint_t x) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
#if defined(ASMJIT_X86)
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return x >= ASMJIT_INT64_C(-2147483648) && x <= ASMJIT_INT64_C(2147483647);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
//! @brief Returns @c true if a given integer @a x is unsigned 16-bit integer
|
|
||||||
static inline bool isUInt32(sysint_t x) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
#if defined(ASMJIT_X86)
|
|
||||||
return x >= 0;
|
|
||||||
#else
|
|
||||||
return x >= 0 && x <= ASMJIT_INT64_C(4294967295);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [Bit Utils]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
static inline uint32_t maskFromIndex(uint32_t x)
|
|
||||||
{
|
|
||||||
return (1U << x);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t maskUpToIndex(uint32_t x)
|
|
||||||
{
|
|
||||||
if (x >= 32)
|
|
||||||
return 0xFFFFFFFF;
|
|
||||||
else
|
|
||||||
return (1U << x) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// From http://graphics.stanford.edu/~seander/bithacks.html .
|
|
||||||
static inline uint32_t bitCount(uint32_t x)
|
|
||||||
{
|
|
||||||
x = x - ((x >> 1) & 0x55555555U);
|
|
||||||
x = (x & 0x33333333U) + ((x >> 2) & 0x33333333U);
|
|
||||||
return (((x + (x >> 4)) & 0xF0F0F0FU) * 0x1010101U) >> 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t findFirstBit(uint32_t mask) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0, bit = 1; i < sizeof(uint32_t) * 8; i++, bit <<= 1)
|
|
||||||
{
|
|
||||||
if (mask & bit) return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// INVALID_VALUE.
|
|
||||||
return 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [Alignment]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
// Align variable @a x to 16-bytes.
|
|
||||||
template<typename T>
|
|
||||||
static inline T alignTo16(const T& x)
|
|
||||||
{
|
|
||||||
return (x + (T)15) & (T)~15;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the size needed to align variable @a x to 16-bytes.
|
|
||||||
template<typename T>
|
|
||||||
static inline T deltaTo16(const T& x)
|
|
||||||
{
|
|
||||||
T aligned = alignTo16(x);
|
|
||||||
return aligned - x;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // Util namespace
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::function_cast<>]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Cast used to cast pointer to function. It's like reinterpret_cast<>,
|
|
||||||
//! but uses internally C style cast to work with MinGW.
|
|
||||||
//!
|
|
||||||
//! If you are using single compiler and @c reinterpret_cast<> works for you,
|
|
||||||
//! there is no reason to use @c AsmJit::function_cast<>. If you are writing
|
|
||||||
//! cross-platform software with various compiler support, consider using
|
|
||||||
//! @c AsmJit::function_cast<> instead of @c reinterpret_cast<>.
|
|
||||||
template<typename T, typename Z>
|
|
||||||
static inline T function_cast(Z* p) ASMJIT_NOTHROW { return (T)p; }
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::(X)MMData]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Structure used for MMX specific data (64-bit).
|
|
||||||
//!
|
|
||||||
//! This structure can be used to load / store data from / to MMX register.
|
|
||||||
union ASMJIT_HIDDEN MMData
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Methods]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Set all eight signed 8-bit integers.
|
|
||||||
inline void setSB(
|
|
||||||
int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sb[0] = x0; sb[1] = x1; sb[2] = x2; sb[3] = x3; sb[4] = x4; sb[5] = x5; sb[6] = x6; sb[7] = x7;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all eight unsigned 8-bit integers.
|
|
||||||
inline void setUB(
|
|
||||||
uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
ub[0] = x0; ub[1] = x1; ub[2] = x2; ub[3] = x3; ub[4] = x4; ub[5] = x5; ub[6] = x6; ub[7] = x7;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all four signed 16-bit integers.
|
|
||||||
inline void setSW(
|
|
||||||
int16_t x0, int16_t x1, int16_t x2, int16_t x3) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all four unsigned 16-bit integers.
|
|
||||||
inline void setUW(
|
|
||||||
uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all two signed 32-bit integers.
|
|
||||||
inline void setSD(
|
|
||||||
int32_t x0, int32_t x1) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sd[0] = x0; sd[1] = x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all two unsigned 32-bit integers.
|
|
||||||
inline void setUD(
|
|
||||||
uint32_t x0, uint32_t x1) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
ud[0] = x0; ud[1] = x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set signed 64-bit integer.
|
|
||||||
inline void setSQ(
|
|
||||||
int64_t x0) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sq[0] = x0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set unsigned 64-bit integer.
|
|
||||||
inline void setUQ(
|
|
||||||
uint64_t x0) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
uq[0] = x0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all two SP-FP values.
|
|
||||||
inline void setSF(
|
|
||||||
float x0, float x1) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sf[0] = x0; sf[1] = x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Members]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Array of eight signed 8-bit integers.
|
|
||||||
int8_t sb[8];
|
|
||||||
//! @brief Array of eight unsigned 8-bit integers.
|
|
||||||
uint8_t ub[8];
|
|
||||||
//! @brief Array of four signed 16-bit integers.
|
|
||||||
int16_t sw[4];
|
|
||||||
//! @brief Array of four unsigned 16-bit integers.
|
|
||||||
uint16_t uw[4];
|
|
||||||
//! @brief Array of two signed 32-bit integers.
|
|
||||||
int32_t sd[2];
|
|
||||||
//! @brief Array of two unsigned 32-bit integers.
|
|
||||||
uint32_t ud[2];
|
|
||||||
//! @brief Array of one signed 64-bit integer.
|
|
||||||
int64_t sq[1];
|
|
||||||
//! @brief Array of one unsigned 64-bit integer.
|
|
||||||
uint64_t uq[1];
|
|
||||||
|
|
||||||
//! @brief Array of two SP-FP values.
|
|
||||||
float sf[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Structure used for SSE specific data (128-bit).
|
|
||||||
//!
|
|
||||||
//! This structure can be used to load / store data from / to SSE register.
|
|
||||||
//!
|
|
||||||
//! @note Always align SSE data to 16-bytes.
|
|
||||||
union ASMJIT_HIDDEN XMMData
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Methods]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Set all sixteen signed 8-bit integers.
|
|
||||||
inline void setSB(
|
|
||||||
int8_t x0, int8_t x1, int8_t x2 , int8_t x3 , int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
|
|
||||||
int8_t x8, int8_t x9, int8_t x10, int8_t x11, int8_t x12, int8_t x13, int8_t x14, int8_t x15) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sb[0] = x0; sb[1] = x1; sb[ 2] = x2 ; sb[3 ] = x3 ; sb[4 ] = x4 ; sb[5 ] = x5 ; sb[6 ] = x6 ; sb[7 ] = x7 ;
|
|
||||||
sb[8] = x8; sb[9] = x9; sb[10] = x10; sb[11] = x11; sb[12] = x12; sb[13] = x13; sb[14] = x14; sb[15] = x15;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all sixteen unsigned 8-bit integers.
|
|
||||||
inline void setUB(
|
|
||||||
uint8_t x0, uint8_t x1, uint8_t x2 , uint8_t x3 , uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
|
|
||||||
uint8_t x8, uint8_t x9, uint8_t x10, uint8_t x11, uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
ub[0] = x0; ub[1] = x1; ub[ 2] = x2 ; ub[3 ] = x3 ; ub[4 ] = x4 ; ub[5 ] = x5 ; ub[6 ] = x6 ; ub[7 ] = x7 ;
|
|
||||||
ub[8] = x8; ub[9] = x9; ub[10] = x10; ub[11] = x11; ub[12] = x12; ub[13] = x13; ub[14] = x14; ub[15] = x15;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all eight signed 16-bit integers.
|
|
||||||
inline void setSW(
|
|
||||||
int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3; sw[4] = x4; sw[5] = x5; sw[6] = x6; sw[7] = x7;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all eight unsigned 16-bit integers.
|
|
||||||
inline void setUW(
|
|
||||||
uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3; uw[4] = x4; uw[5] = x5; uw[6] = x6; uw[7] = x7;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all four signed 32-bit integers.
|
|
||||||
inline void setSD(
|
|
||||||
int32_t x0, int32_t x1, int32_t x2, int32_t x3) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all four unsigned 32-bit integers.
|
|
||||||
inline void setUD(
|
|
||||||
uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all two signed 64-bit integers.
|
|
||||||
inline void setSQ(
|
|
||||||
int64_t x0, int64_t x1) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sq[0] = x0; sq[1] = x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all two unsigned 64-bit integers.
|
|
||||||
inline void setUQ(
|
|
||||||
uint64_t x0, uint64_t x1) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
uq[0] = x0; uq[1] = x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all four SP-FP floats.
|
|
||||||
inline void setSF(
|
|
||||||
float x0, float x1, float x2, float x3) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sf[0] = x0; sf[1] = x1; sf[2] = x2; sf[3] = x3;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set all two DP-FP floats.
|
|
||||||
inline void setDF(
|
|
||||||
double x0, double x1) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
df[0] = x0; df[1] = x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Members]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Array of sixteen signed 8-bit integers.
|
|
||||||
int8_t sb[16];
|
|
||||||
//! @brief Array of sixteen unsigned 8-bit integers.
|
|
||||||
uint8_t ub[16];
|
|
||||||
//! @brief Array of eight signed 16-bit integers.
|
|
||||||
int16_t sw[8];
|
|
||||||
//! @brief Array of eight unsigned 16-bit integers.
|
|
||||||
uint16_t uw[8];
|
|
||||||
//! @brief Array of four signed 32-bit integers.
|
|
||||||
int32_t sd[4];
|
|
||||||
//! @brief Array of four unsigned 32-bit integers.
|
|
||||||
uint32_t ud[4];
|
|
||||||
//! @brief Array of two signed 64-bit integers.
|
|
||||||
int64_t sq[2];
|
|
||||||
//! @brief Array of two unsigned 64-bit integers.
|
|
||||||
uint64_t uq[2];
|
|
||||||
|
|
||||||
//! @brief Array of four 32-bit single precision floating points.
|
|
||||||
float sf[4];
|
|
||||||
//! @brief Array of two 64-bit double precision floating points.
|
|
||||||
double df[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Buffer]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Buffer used to store instruction stream in AsmJit.
|
|
||||||
//!
|
|
||||||
//! This class can be dangerous, if you don't know how it works. Assembler
|
|
||||||
//! instruction stream is usually constructed by multiple calls of emit
|
|
||||||
//! functions that emits bytes, words, dwords or qwords. But to decrease
|
|
||||||
//! AsmJit library size and improve performance, we are not checking for
|
|
||||||
//! buffer overflow for each emit operation, but only once in highler level
|
|
||||||
//! emit instruction.
|
|
||||||
//!
|
|
||||||
//! So, if you want to use this class, you need to do buffer checking yourself
|
|
||||||
//! by using @c ensureSpace() method. It's designed to grow buffer if needed.
|
|
||||||
//! Threshold for growing is named @c growThreshold() and it means count of
|
|
||||||
//! bytes for emitting single operation. Default size is set to 16 bytes,
|
|
||||||
//! because x86 and x64 instruction can't be larger (so it's space to hold 1
|
|
||||||
//! instruction).
|
|
||||||
//!
|
|
||||||
//! Example using Buffer:
|
|
||||||
//!
|
|
||||||
//! @code
|
|
||||||
//! // Buffer instance, growThreshold == 16
|
|
||||||
//! // (no memory allocated in constructor).
|
|
||||||
//! AsmJit::Buffer buf(16);
|
|
||||||
//!
|
|
||||||
//! // Begin of emit stream, ensure space can fail on out of memory error.
|
|
||||||
//! if (buf.ensureSpace())
|
|
||||||
//! {
|
|
||||||
//! // here, you can emit up to 16 (growThreshold) bytes
|
|
||||||
//! buf.emitByte(0x00);
|
|
||||||
//! buf.emitByte(0x01);
|
|
||||||
//! buf.emitByte(0x02);
|
|
||||||
//! buf.emitByte(0x03);
|
|
||||||
//! ...
|
|
||||||
//! }
|
|
||||||
//! @endcode
|
|
||||||
struct ASMJIT_API Buffer
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Construction / Destruction]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
inline Buffer(sysint_t growThreshold = 16) ASMJIT_NOTHROW :
|
|
||||||
_data(NULL),
|
|
||||||
_cur(NULL),
|
|
||||||
_max(NULL),
|
|
||||||
_capacity(0),
|
|
||||||
_growThreshold(growThreshold)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ~Buffer() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
if (_data) ASMJIT_FREE(_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Get start of buffer.
|
|
||||||
inline uint8_t* getData() const ASMJIT_NOTHROW { return _data; }
|
|
||||||
|
|
||||||
//! @brief Get current pointer in code buffer.
|
|
||||||
inline uint8_t* getCur() const ASMJIT_NOTHROW { return _cur; }
|
|
||||||
|
|
||||||
//! @brief Get maximum pointer in code buffer for growing.
|
|
||||||
inline uint8_t* getMax() const ASMJIT_NOTHROW { return _max; }
|
|
||||||
|
|
||||||
//! @brief Get current offset in buffer.
|
|
||||||
inline sysint_t getOffset() const ASMJIT_NOTHROW { return (sysint_t)(_cur - _data); }
|
|
||||||
|
|
||||||
//! @brief Get capacity of buffer.
|
|
||||||
inline sysint_t getCapacity() const ASMJIT_NOTHROW { return _capacity; }
|
|
||||||
|
|
||||||
//! @brief Get grow threshold.
|
|
||||||
inline sysint_t getGrowThreshold() const ASMJIT_NOTHROW { return _growThreshold; }
|
|
||||||
|
|
||||||
//! @brief Ensure space for next instruction
|
|
||||||
inline bool ensureSpace() ASMJIT_NOTHROW { return (_cur >= _max) ? grow() : true; }
|
|
||||||
|
|
||||||
//! @brief Sets offset to @a o and returns previous offset.
|
|
||||||
//!
|
|
||||||
//! This method can be used to truncate buffer or it's used to
|
|
||||||
//! overwrite specific position in buffer by Assembler.
|
|
||||||
inline sysint_t toOffset(sysint_t o) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
ASMJIT_ASSERT(o < _capacity);
|
|
||||||
|
|
||||||
sysint_t prev = (sysint_t)(_cur - _data);
|
|
||||||
_cur = _data + o;
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Reallocate buffer.
|
|
||||||
//!
|
|
||||||
//! It's only used for growing, buffer is never reallocated to smaller
|
|
||||||
//! number than current capacity() is.
|
|
||||||
bool realloc(sysint_t to) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Used to grow the buffer.
|
|
||||||
//!
|
|
||||||
//! It will typically realloc to twice size of capacity(), but if capacity()
|
|
||||||
//! is large, it will use smaller steps.
|
|
||||||
bool grow() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Clear everything, but not deallocate buffer.
|
|
||||||
void clear() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Free buffer and NULL all pointers.
|
|
||||||
void free() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Take ownership of the buffer data and purge @c Buffer instance.
|
|
||||||
uint8_t* take() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Emit]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Emit Byte.
|
|
||||||
inline void emitByte(uint8_t x) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
*_cur++ = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Emit Word (2 bytes).
|
|
||||||
inline void emitWord(uint16_t x) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
*(uint16_t *)_cur = x;
|
|
||||||
_cur += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Emit DWord (4 bytes).
|
|
||||||
inline void emitDWord(uint32_t x) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
*(uint32_t *)_cur = x;
|
|
||||||
_cur += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Emit QWord (8 bytes).
|
|
||||||
inline void emitQWord(uint64_t x) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
*(uint64_t *)_cur = x;
|
|
||||||
_cur += 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Emit system signed integer (4 or 8 bytes).
|
|
||||||
inline void emitSysInt(sysint_t x) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
*(sysint_t *)_cur = x;
|
|
||||||
_cur += sizeof(sysint_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Emit system unsigned integer (4 or 8 bytes).
|
|
||||||
inline void emitSysUInt(sysuint_t x) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
*(sysuint_t *)_cur = x;
|
|
||||||
_cur += sizeof(sysuint_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Emit custom data.
|
|
||||||
void emitData(const void* ptr, sysuint_t len) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Get / Set]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Set byte at position @a pos.
|
|
||||||
inline uint8_t getByteAt(sysint_t pos) const ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return *reinterpret_cast<const uint8_t*>(_data + pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set word at position @a pos.
|
|
||||||
inline uint16_t getWordAt(sysint_t pos) const ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return *reinterpret_cast<const uint16_t*>(_data + pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set word at position @a pos.
|
|
||||||
inline uint32_t getDWordAt(sysint_t pos) const ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return *reinterpret_cast<const uint32_t*>(_data + pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set word at position @a pos.
|
|
||||||
inline uint64_t getQWordAt(sysint_t pos) const ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return *reinterpret_cast<const uint64_t*>(_data + pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set byte at position @a pos.
|
|
||||||
inline void setByteAt(sysint_t pos, uint8_t x) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
*reinterpret_cast<uint8_t*>(_data + pos) = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set word at position @a pos.
|
|
||||||
inline void setWordAt(sysint_t pos, uint16_t x) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
*reinterpret_cast<uint16_t*>(_data + pos) = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set word at position @a pos.
|
|
||||||
inline void setDWordAt(sysint_t pos, uint32_t x) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
*reinterpret_cast<uint32_t*>(_data + pos) = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Set word at position @a pos.
|
|
||||||
inline void setQWordAt(sysint_t pos, uint64_t x) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
*reinterpret_cast<uint64_t*>(_data + pos) = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Members]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// All members are public, because they can be accessed and modified by
|
|
||||||
// Assembler/Compiler directly.
|
|
||||||
|
|
||||||
//! @brief Beginning position of buffer.
|
|
||||||
uint8_t* _data;
|
|
||||||
//! @brief Current position in buffer.
|
|
||||||
uint8_t* _cur;
|
|
||||||
//! @brief Maximum position in buffer for realloc.
|
|
||||||
uint8_t* _max;
|
|
||||||
|
|
||||||
//! @brief Buffer capacity (in bytes).
|
|
||||||
sysint_t _capacity;
|
|
||||||
|
|
||||||
//! @brief Grow threshold
|
|
||||||
sysint_t _growThreshold;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::PodVector<>]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Template used to store and manage array of POD data.
|
|
||||||
//!
|
|
||||||
//! This template has these adventages over other vector<> templates:
|
|
||||||
//! - Non-copyable (designed to be non-copyable, we want it)
|
|
||||||
//! - No copy-on-write (some implementations of stl can use it)
|
|
||||||
//! - Optimized for working only with POD types
|
|
||||||
//! - Uses ASMJIT_... memory management macros
|
|
||||||
template <typename T>
|
|
||||||
struct PodVector
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Construction / Destruction]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Create new instance of PodVector template. Data will not
|
|
||||||
//! be allocated (will be NULL).
|
|
||||||
inline PodVector() ASMJIT_NOTHROW : _data(NULL), _length(0), _capacity(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Destroy PodVector and free all data.
|
|
||||||
inline ~PodVector() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
if (_data) ASMJIT_FREE(_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Data]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Get vector data.
|
|
||||||
inline T* getData() ASMJIT_NOTHROW { return _data; }
|
|
||||||
//! @overload
|
|
||||||
inline const T* getData() const ASMJIT_NOTHROW { return _data; }
|
|
||||||
//! @brief Get vector length.
|
|
||||||
inline sysuint_t getLength() const ASMJIT_NOTHROW { return _length; }
|
|
||||||
//! @brief get vector capacity (allocation capacity).
|
|
||||||
inline sysuint_t getCapacity() const ASMJIT_NOTHROW { return _capacity; }
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Manipulation]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Clear vector data, but not free internal buffer.
|
|
||||||
void clear() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
_length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Clear vector data and free internal buffer.
|
|
||||||
void free() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
if (_data)
|
|
||||||
{
|
|
||||||
ASMJIT_FREE(_data);
|
|
||||||
_data = 0;
|
|
||||||
_length = 0;
|
|
||||||
_capacity = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Prepend @a item to vector.
|
|
||||||
bool prepend(const T& item) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
if (_length == _capacity && !_grow()) return false;
|
|
||||||
|
|
||||||
memmove(_data + 1, _data, sizeof(T) * _length);
|
|
||||||
memcpy(_data, &item, sizeof(T));
|
|
||||||
|
|
||||||
_length++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Insert an @a item at the @a index.
|
|
||||||
bool insert(sysuint_t index, const T& item) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
ASMJIT_ASSERT(index <= _length);
|
|
||||||
if (_length == _capacity && !_grow()) return false;
|
|
||||||
|
|
||||||
T* dst = _data + index;
|
|
||||||
memmove(dst + 1, dst, _length - index);
|
|
||||||
memcpy(dst, &item, sizeof(T));
|
|
||||||
|
|
||||||
_length++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Append @a item to vector.
|
|
||||||
bool append(const T& item) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
if (_length == _capacity && !_grow()) return false;
|
|
||||||
|
|
||||||
memcpy(_data + _length, &item, sizeof(T));
|
|
||||||
|
|
||||||
_length++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Get index of @a val or (sysuint_t)-1 if not found.
|
|
||||||
sysuint_t indexOf(const T& val) const ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sysuint_t i = 0, len = _length;
|
|
||||||
for (i = 0; i < len; i++) { if (_data[i] == val) return i; }
|
|
||||||
return (sysuint_t)-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Remove element at index @a i.
|
|
||||||
void removeAt(sysuint_t i) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
ASMJIT_ASSERT(i < _length);
|
|
||||||
|
|
||||||
T* dst = _data + i;
|
|
||||||
_length--;
|
|
||||||
memmove(dst, dst + 1, _length - i);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Swap this pod-vector with @a other.
|
|
||||||
void swap(PodVector<T>& other) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
T* _tmp_data = _data;
|
|
||||||
sysuint_t _tmp_length = _length;
|
|
||||||
sysuint_t _tmp_capacity = _capacity;
|
|
||||||
|
|
||||||
_data = other._data;
|
|
||||||
_length = other._length;
|
|
||||||
_capacity = other._capacity;
|
|
||||||
|
|
||||||
other._data = _tmp_data;
|
|
||||||
other._length = _tmp_length;
|
|
||||||
other._capacity = _tmp_capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Get item at position @a i.
|
|
||||||
inline T& operator[](sysuint_t i) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
ASMJIT_ASSERT(i < _length);
|
|
||||||
return _data[i];
|
|
||||||
}
|
|
||||||
//! @brief Get item at position @a i.
|
|
||||||
inline const T& operator[](sysuint_t i) const ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
ASMJIT_ASSERT(i < _length);
|
|
||||||
return _data[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Append the item and return address so it can be initialized.
|
|
||||||
T* newItem() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
if (_length == _capacity && !_grow()) return NULL;
|
|
||||||
return _data + (_length++);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Private]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
private:
|
|
||||||
//! @brief Called to grow internal array.
|
|
||||||
bool _grow() ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
return _realloc(_capacity < 16 ? 16 : _capacity * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Realloc internal array to fit @a to items.
|
|
||||||
bool _realloc(sysuint_t to) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
ASMJIT_ASSERT(to >= _length);
|
|
||||||
|
|
||||||
T* p = reinterpret_cast<T*>(_data
|
|
||||||
? ASMJIT_REALLOC(_data, to * sizeof(T))
|
|
||||||
: ASMJIT_MALLOC(to * sizeof(T)));
|
|
||||||
if (!p) return false;
|
|
||||||
|
|
||||||
_data = p;
|
|
||||||
_capacity = to;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Members]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Items data.
|
|
||||||
T* _data;
|
|
||||||
//! @brief Length of buffer (count of items in array).
|
|
||||||
sysuint_t _length;
|
|
||||||
//! @brief Capacity of buffer (maximum items that can fit to current array).
|
|
||||||
sysuint_t _capacity;
|
|
||||||
|
|
||||||
private:
|
|
||||||
ASMJIT_DISABLE_COPY(PodVector<T>)
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Zone]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
//! @brief Memory allocator designed to fast alloc memory that will be freed
|
|
||||||
//! in one step.
|
|
||||||
//!
|
|
||||||
//! @note This is hackery for performance. Concept is that objects created
|
|
||||||
//! by @c Zone are freed all at once. This means that lifetime of
|
|
||||||
//! these objects are same as zone object itselt.
|
|
||||||
//!
|
|
||||||
//! All emittables, variables, labels and states allocated by @c Compiler are
|
|
||||||
//! allocated through @c Zone object.
|
|
||||||
struct ASMJIT_API Zone
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Construction / Destruction]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Create new instance of @c Zone.
|
|
||||||
//! @param chunkSize Default size for one zone chunk.
|
|
||||||
Zone(sysuint_t chunkSize) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Destroy zone instance.
|
|
||||||
~Zone() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Methods]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @brief Allocate @c size bytes of memory and return pointer to it.
|
|
||||||
//!
|
|
||||||
//! Pointer allocated by this way will be valid until @c Zone object is
|
|
||||||
//! destroyed. To create class by this way use placement @c new and
|
|
||||||
//! @c delete operators:
|
|
||||||
//!
|
|
||||||
//! @code
|
|
||||||
//! // Example of allocating simple class
|
|
||||||
//!
|
|
||||||
//! // Your class
|
|
||||||
//! class Object
|
|
||||||
//! {
|
|
||||||
//! // members...
|
|
||||||
//! };
|
|
||||||
//!
|
|
||||||
//! // Your function
|
|
||||||
//! void f()
|
|
||||||
//! {
|
|
||||||
//! // We are using AsmJit namespace
|
|
||||||
//! using namespace AsmJit
|
|
||||||
//!
|
|
||||||
//! // Create zone object with chunk size of 65536 bytes.
|
|
||||||
//! Zone zone(65536);
|
|
||||||
//!
|
|
||||||
//! // Create your objects using zone object allocating, for example:
|
|
||||||
//! Object* obj = new(zone.alloc(sizeof(YourClass))) Object();
|
|
||||||
//!
|
|
||||||
//! // ... lifetime of your objects ...
|
|
||||||
//!
|
|
||||||
//! // Destroy your objects:
|
|
||||||
//! obj->~Object();
|
|
||||||
//!
|
|
||||||
//! // Zone destructor will free all memory allocated through it,
|
|
||||||
//! // alternative is to call @c zone.freeAll().
|
|
||||||
//! }
|
|
||||||
//! @endcode
|
|
||||||
void* zalloc(sysuint_t size) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Helper to duplicate string.
|
|
||||||
char* zstrdup(const char* str) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Free all allocated memory except first block that remains for reuse.
|
|
||||||
//!
|
|
||||||
//! Note that this method will invalidate all instances using this memory
|
|
||||||
//! allocated by this zone instance.
|
|
||||||
void clear() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Free all allocated memory at once.
|
|
||||||
//!
|
|
||||||
//! Note that this method will invalidate all instances using this memory
|
|
||||||
//! allocated by this zone instance.
|
|
||||||
void freeAll() ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
//! @brief Get total size of allocated objects - by @c alloc().
|
|
||||||
inline sysuint_t getTotal() const ASMJIT_NOTHROW { return _total; }
|
|
||||||
//! @brief Get (default) chunk size.
|
|
||||||
inline sysuint_t getChunkSize() const ASMJIT_NOTHROW { return _chunkSize; }
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Chunk]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @internal
|
|
||||||
//!
|
|
||||||
//! @brief One allocated chunk of memory.
|
|
||||||
struct ASMJIT_HIDDEN Chunk
|
|
||||||
{
|
|
||||||
//! @brief Link to previous chunk.
|
|
||||||
Chunk* prev;
|
|
||||||
//! @brief Position in this chunk.
|
|
||||||
sysuint_t pos;
|
|
||||||
//! @brief Size of this chunk (in bytes).
|
|
||||||
sysuint_t size;
|
|
||||||
|
|
||||||
//! @brief Data.
|
|
||||||
uint8_t data[sizeof(void*)];
|
|
||||||
|
|
||||||
//! @brief Get count of remaining (unused) bytes in chunk.
|
|
||||||
inline sysuint_t getRemainingBytes() const ASMJIT_NOTHROW { return size - pos; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Members]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
private:
|
|
||||||
//! @brief Last allocated chunk of memory.
|
|
||||||
Chunk* _chunks;
|
|
||||||
//! @brief Total size of allocated objects - by @c alloc() method.
|
|
||||||
sysuint_t _total;
|
|
||||||
//! @brief One chunk size.
|
|
||||||
sysuint_t _chunkSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @}
|
|
||||||
|
|
||||||
} // AsmJit namespace
|
|
||||||
|
|
||||||
#endif // _ASMJIT_UTIL_H
|
|
|
@ -1,111 +0,0 @@
|
||||||
// [AsmJit]
|
|
||||||
// Complete JIT Assembler for C++ Language.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See COPYING file in this package.
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#ifndef _ASMJIT_UTIL_P_H
|
|
||||||
#define _ASMJIT_UTIL_P_H
|
|
||||||
|
|
||||||
// [Dependencies]
|
|
||||||
#include "Util.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
namespace AsmJit {
|
|
||||||
|
|
||||||
//! @addtogroup AsmJit_Util
|
|
||||||
//! @{
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::Util]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
namespace Util
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [AsmJit::floatAsInt32, int32AsFloat]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! @internal
|
|
||||||
//!
|
|
||||||
//! @brief used to cast from float to 32-bit integer and vica versa.
|
|
||||||
union I32FPUnion
|
|
||||||
{
|
|
||||||
//! @brief 32-bit signed integer value.
|
|
||||||
int32_t i;
|
|
||||||
//! @brief 32-bit SP-FP value.
|
|
||||||
float f;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @internal
|
|
||||||
//!
|
|
||||||
//! @brief used to cast from double to 64-bit integer and vica versa.
|
|
||||||
union I64FPUnion
|
|
||||||
{
|
|
||||||
//! @brief 64-bit signed integer value.
|
|
||||||
int64_t i;
|
|
||||||
//! @brief 64-bit DP-FP value.
|
|
||||||
double f;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! @brief Binary cast from 32-bit integer to SP-FP value (@c float).
|
|
||||||
static inline float int32AsFloat(int32_t i) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
I32FPUnion u;
|
|
||||||
u.i = i;
|
|
||||||
return u.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Binary cast SP-FP value (@c float) to 32-bit integer.
|
|
||||||
static inline int32_t floatAsInt32(float f) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
I32FPUnion u;
|
|
||||||
u.f = f;
|
|
||||||
return u.i;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Binary cast from 64-bit integer to DP-FP value (@c double).
|
|
||||||
static inline double int64AsDouble(int64_t i) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
I64FPUnion u;
|
|
||||||
u.i = i;
|
|
||||||
return u.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Binary cast from DP-FP value (@c double) to 64-bit integer.
|
|
||||||
static inline int64_t doubleAsInt64(double f) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
I64FPUnion u;
|
|
||||||
u.f = f;
|
|
||||||
return u.i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Str Utils]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
ASMJIT_HIDDEN char* mycpy(char* dst, const char* src, sysuint_t len = (sysuint_t)-1) ASMJIT_NOTHROW;
|
|
||||||
ASMJIT_HIDDEN char* myfill(char* dst, const int c, sysuint_t len) ASMJIT_NOTHROW;
|
|
||||||
ASMJIT_HIDDEN char* myhex(char* dst, const uint8_t* src, sysuint_t len) ASMJIT_NOTHROW;
|
|
||||||
ASMJIT_HIDDEN char* myutoa(char* dst, sysuint_t i, sysuint_t base = 10) ASMJIT_NOTHROW;
|
|
||||||
ASMJIT_HIDDEN char* myitoa(char* dst, sysint_t i, sysuint_t base = 10) ASMJIT_NOTHROW;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Mem Utils]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static inline void memset32(uint32_t* p, uint32_t c, sysuint_t len) ASMJIT_NOTHROW
|
|
||||||
{
|
|
||||||
sysuint_t i;
|
|
||||||
for (i = 0; i < len; i++) p[i] = c;
|
|
||||||
}
|
|
||||||
} // Util namespace
|
|
||||||
|
|
||||||
//! @}
|
|
||||||
|
|
||||||
} // AsmJit namespace
|
|
||||||
|
|
||||||
#endif // _ASMJIT_UTIL_P_H
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_H
|
||||||
|
#define _ASMJIT_CORE_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "core/build.h"
|
||||||
|
|
||||||
|
#include "core/assembler.h"
|
||||||
|
#include "core/assert.h"
|
||||||
|
#include "core/buffer.h"
|
||||||
|
#include "core/compiler.h"
|
||||||
|
#include "core/compilercontext.h"
|
||||||
|
#include "core/compilerfunc.h"
|
||||||
|
#include "core/compileritem.h"
|
||||||
|
#include "core/cpuinfo.h"
|
||||||
|
#include "core/defs.h"
|
||||||
|
#include "core/func.h"
|
||||||
|
#include "core/intutil.h"
|
||||||
|
#include "core/lock.h"
|
||||||
|
#include "core/logger.h"
|
||||||
|
#include "core/memorymanager.h"
|
||||||
|
#include "core/memorymarker.h"
|
||||||
|
#include "core/operand.h"
|
||||||
|
#include "core/podvector.h"
|
||||||
|
#include "core/stringbuilder.h"
|
||||||
|
#include "core/stringutil.h"
|
||||||
|
#include "core/virtualmemory.h"
|
||||||
|
#include "core/zonememory.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_H
|
|
@ -4,7 +4,7 @@
|
||||||
// [License]
|
// [License]
|
||||||
// Zlib - See COPYING file in this package.
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
// MSVC
|
// [MSVC]
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
// Disable some warnings we know about
|
// Disable some warnings we know about
|
||||||
|
@ -22,3 +22,12 @@
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
|
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
// [GNUC]
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
// GCC warnings fix: I can't understand why GCC has no interface to push/pop
|
||||||
|
// specific warnings.
|
||||||
|
// # if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 402001
|
||||||
|
// # pragma GCC diagnostic ignored "-w"
|
||||||
|
// # endif
|
||||||
|
#endif // __GNUC__
|
|
@ -4,6 +4,7 @@
|
||||||
// [License]
|
// [License]
|
||||||
// Zlib - See COPYING file in this package.
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [MSVC]
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
// Pop disabled warnings by ApiBegin.h
|
// Pop disabled warnings by ApiBegin.h
|
||||||
|
@ -14,3 +15,7 @@
|
||||||
#undef snprintf
|
#undef snprintf
|
||||||
|
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
// [GNUC]
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#endif // __GNUC__
|
|
@ -0,0 +1,217 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/assembler.h"
|
||||||
|
#include "../core/memorymanager.h"
|
||||||
|
#include "../core/intutil.h"
|
||||||
|
|
||||||
|
// [Dependenceis - C]
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Assembler - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
Assembler::Assembler(Context* context) :
|
||||||
|
_zoneMemory(16384 - sizeof(ZoneChunk) - 32),
|
||||||
|
_buffer(),
|
||||||
|
_context(context != NULL
|
||||||
|
? context
|
||||||
|
: static_cast<Context*>(JitContext::getGlobal())),
|
||||||
|
_logger(NULL),
|
||||||
|
_error(kErrorOk),
|
||||||
|
_properties(0),
|
||||||
|
_emitOptions(0),
|
||||||
|
_trampolineSize(0),
|
||||||
|
_inlineComment(NULL),
|
||||||
|
_unusedLinks(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Assembler::~Assembler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Assembler - Logging]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Assembler::setLogger(Logger* logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Assembler - Error Handling]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Assembler::setError(uint32_t error)
|
||||||
|
{
|
||||||
|
_error = error;
|
||||||
|
if (_error == kErrorOk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_logger)
|
||||||
|
_logger->logFormat("*** ASSEMBLER ERROR: %s (%u).\n", getErrorString(error), (unsigned int)error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Assembler - Properties]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
uint32_t Assembler::getProperty(uint32_t propertyId) const
|
||||||
|
{
|
||||||
|
if (propertyId > 31)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (_properties & (IntUtil::maskFromIndex(propertyId))) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Assembler::setProperty(uint32_t propertyId, uint32_t value)
|
||||||
|
{
|
||||||
|
if (propertyId > 31)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
_properties |= IntUtil::maskFromIndex(propertyId);
|
||||||
|
else
|
||||||
|
_properties &= ~IntUtil::maskFromIndex(propertyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Assembler - TakeCode]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
uint8_t* Assembler::takeCode()
|
||||||
|
{
|
||||||
|
uint8_t* code = _buffer.take();
|
||||||
|
_relocData.clear();
|
||||||
|
_zoneMemory.clear();
|
||||||
|
|
||||||
|
if (_error != kErrorOk)
|
||||||
|
setError(kErrorOk);
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Assembler - Clear / Reset]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Assembler::clear()
|
||||||
|
{
|
||||||
|
_purge();
|
||||||
|
|
||||||
|
if (_error != kErrorOk)
|
||||||
|
setError(kErrorOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Assembler::reset()
|
||||||
|
{
|
||||||
|
_purge();
|
||||||
|
|
||||||
|
_zoneMemory.reset();
|
||||||
|
_buffer.reset();
|
||||||
|
|
||||||
|
_labels.reset();
|
||||||
|
_relocData.reset();
|
||||||
|
|
||||||
|
if (_error != kErrorOk)
|
||||||
|
setError(kErrorOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Assembler::_purge()
|
||||||
|
{
|
||||||
|
_zoneMemory.clear();
|
||||||
|
_buffer.clear();
|
||||||
|
|
||||||
|
_emitOptions = 0;
|
||||||
|
_trampolineSize = 0;
|
||||||
|
|
||||||
|
_inlineComment = NULL;
|
||||||
|
_unusedLinks = NULL;
|
||||||
|
|
||||||
|
_labels.clear();
|
||||||
|
_relocData.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Assembler - Emit]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Assembler::embed(const void* data, size_t len)
|
||||||
|
{
|
||||||
|
if (!canEmit())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_logger)
|
||||||
|
{
|
||||||
|
size_t i, j;
|
||||||
|
size_t max;
|
||||||
|
|
||||||
|
char buf[128];
|
||||||
|
char dot[] = ".data ";
|
||||||
|
char* p;
|
||||||
|
|
||||||
|
memcpy(buf, dot, ASMJIT_ARRAY_SIZE(dot) - 1);
|
||||||
|
|
||||||
|
for (i = 0; i < len; i += 16)
|
||||||
|
{
|
||||||
|
max = (len - i < 16) ? len - i : 16;
|
||||||
|
p = buf + ASMJIT_ARRAY_SIZE(dot) - 1;
|
||||||
|
|
||||||
|
for (j = 0; j < max; j++)
|
||||||
|
p += sprintf(p, "%02X", reinterpret_cast<const uint8_t *>(data)[i+j]);
|
||||||
|
|
||||||
|
*p++ = '\n';
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
_logger->logString(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_buffer.emitData(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Assembler - Helpers]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
Assembler::LabelLink* Assembler::_newLabelLink()
|
||||||
|
{
|
||||||
|
LabelLink* link = _unusedLinks;
|
||||||
|
|
||||||
|
if (link)
|
||||||
|
{
|
||||||
|
_unusedLinks = link->prev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
link = (LabelLink*)_zoneMemory.alloc(sizeof(LabelLink));
|
||||||
|
if (link == NULL) return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean link
|
||||||
|
link->prev = NULL;
|
||||||
|
link->offset = 0;
|
||||||
|
link->displacement = 0;
|
||||||
|
link->relocId = -1;
|
||||||
|
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,500 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_ASSEMBLER_H
|
||||||
|
#define _ASMJIT_CORE_ASSEMBLER_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/buffer.h"
|
||||||
|
#include "../core/context.h"
|
||||||
|
#include "../core/defs.h"
|
||||||
|
#include "../core/logger.h"
|
||||||
|
#include "../core/podvector.h"
|
||||||
|
#include "../core/zonememory.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Core
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Assembler]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Base class for @ref Assembler.
|
||||||
|
//!
|
||||||
|
//! This class implements core setialization API only. The platform specific
|
||||||
|
//! methods and intrinsics is implemented by derived classes.
|
||||||
|
//!
|
||||||
|
//! @sa @c Assembler.
|
||||||
|
struct Assembler
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Creates Assembler instance.
|
||||||
|
ASMJIT_API Assembler(Context* context);
|
||||||
|
//! @brief Destroys Assembler instance
|
||||||
|
ASMJIT_API virtual ~Assembler();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [LabelLink]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Data structure used to link linked-labels.
|
||||||
|
struct LabelLink
|
||||||
|
{
|
||||||
|
//! @brief Previous link.
|
||||||
|
LabelLink* prev;
|
||||||
|
//! @brief Offset.
|
||||||
|
sysint_t offset;
|
||||||
|
//! @brief Inlined displacement.
|
||||||
|
sysint_t displacement;
|
||||||
|
//! @brief RelocId if link must be absolute when relocated.
|
||||||
|
sysint_t relocId;
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [LabelData]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Label data.
|
||||||
|
struct LabelData
|
||||||
|
{
|
||||||
|
//! @brief Label offset.
|
||||||
|
sysint_t offset;
|
||||||
|
//! @brief Label links chain.
|
||||||
|
LabelLink* links;
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [RelocData]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// X86 architecture uses 32-bit absolute addressing model by memory operands,
|
||||||
|
// but 64-bit mode uses relative addressing model (RIP + displacement). In
|
||||||
|
// code we are always using relative addressing model for referencing labels
|
||||||
|
// and embedded data. In 32-bit mode we must patch all references to absolute
|
||||||
|
// address before we can call generated function. We are patching only memory
|
||||||
|
// operands.
|
||||||
|
|
||||||
|
//! @brief Code relocation data (relative vs absolute addresses).
|
||||||
|
struct RelocData
|
||||||
|
{
|
||||||
|
//! @brief Type of relocation.
|
||||||
|
uint32_t type;
|
||||||
|
//! @brief Size of relocation (4 or 8 bytes).
|
||||||
|
uint32_t size;
|
||||||
|
//! @brief Offset from code begin address.
|
||||||
|
sysint_t offset;
|
||||||
|
|
||||||
|
//! @brief Relative displacement or absolute address.
|
||||||
|
union
|
||||||
|
{
|
||||||
|
//! @brief Relative displacement from code begin address (not to @c offset).
|
||||||
|
sysint_t destination;
|
||||||
|
//! @brief Absolute address where to jump;
|
||||||
|
void* address;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Context]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get code generator.
|
||||||
|
inline Context* getContext() const
|
||||||
|
{ return _context; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Memory Management]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get zone memory manager.
|
||||||
|
inline ZoneMemory* getZoneMemory() const
|
||||||
|
{ return const_cast<ZoneMemory*>(&_zoneMemory); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Logging]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get logger.
|
||||||
|
inline Logger* getLogger() const
|
||||||
|
{ return _logger; }
|
||||||
|
|
||||||
|
//! @brief Set logger to @a logger.
|
||||||
|
ASMJIT_API virtual void setLogger(Logger* logger);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Error Handling]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get error code.
|
||||||
|
inline uint32_t getError() const
|
||||||
|
{ return _error; }
|
||||||
|
|
||||||
|
//! @brief Set error code.
|
||||||
|
//!
|
||||||
|
//! This method is virtual, because higher classes can use it to catch all
|
||||||
|
//! errors.
|
||||||
|
ASMJIT_API virtual void setError(uint32_t error);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Properties]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get assembler property.
|
||||||
|
ASMJIT_API virtual uint32_t getProperty(uint32_t propertyId) const;
|
||||||
|
|
||||||
|
//! @brief Set assembler property.
|
||||||
|
ASMJIT_API virtual void setProperty(uint32_t propertyId, uint32_t value);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Capacity]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get capacity of internal code buffer.
|
||||||
|
inline size_t getCapacity() const
|
||||||
|
{ return _buffer.getCapacity(); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Offset]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Return current offset in buffer.
|
||||||
|
inline size_t getOffset() const
|
||||||
|
{ return _buffer.getOffset(); }
|
||||||
|
|
||||||
|
//! @brief Set offset to @a o and returns previous offset.
|
||||||
|
//!
|
||||||
|
//! This method can be used to truncate code (previous offset is not
|
||||||
|
//! recorded) or to overwrite instruction stream at position @a o.
|
||||||
|
//!
|
||||||
|
//! @return Previous offset value that can be uset to set offset back later.
|
||||||
|
inline size_t toOffset(size_t o)
|
||||||
|
{ return _buffer.toOffset(o); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [GetCode / GetCodeSize]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Return start of assembler code buffer.
|
||||||
|
//!
|
||||||
|
//! Note that buffer address can change if you emit instruction or something
|
||||||
|
//! else. Use this pointer only when you finished or make sure you do not
|
||||||
|
//! use returned pointer after emitting.
|
||||||
|
inline uint8_t* getCode() const
|
||||||
|
{ return _buffer.getData(); }
|
||||||
|
|
||||||
|
//! @brief Return current offset in buffer (same as <code>getOffset() + getTramplineSize()</code>).
|
||||||
|
inline size_t getCodeSize() const
|
||||||
|
{ return _buffer.getOffset() + getTrampolineSize(); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [TakeCode]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Take internal code buffer and NULL all pointers (you take the ownership).
|
||||||
|
ASMJIT_API uint8_t* takeCode();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Clear / Reset]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Clear everything, but not deallocate buffers.
|
||||||
|
ASMJIT_API void clear();
|
||||||
|
|
||||||
|
//! @brief Reset everything (means also to free all buffers).
|
||||||
|
ASMJIT_API void reset();
|
||||||
|
|
||||||
|
//! @brief Called by clear() and reset() to clear all data related to derived
|
||||||
|
//! class implementation.
|
||||||
|
ASMJIT_API virtual void _purge();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [EnsureSpace]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Ensure space for next instruction.
|
||||||
|
//!
|
||||||
|
//! Note that this method can return false. It's rare and probably you never
|
||||||
|
//! get this, but in some situations it's still possible.
|
||||||
|
inline bool ensureSpace()
|
||||||
|
{ return _buffer.ensureSpace(); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [GetTrampolineSize]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get size of all possible trampolines needed to successfuly generate
|
||||||
|
//! relative jumps to absolute addresses. This value is only non-zero if jmp
|
||||||
|
//! of call instructions were used with immediate operand (this means jump or
|
||||||
|
//! call absolute address directly).
|
||||||
|
//!
|
||||||
|
//! Currently only _emitJmpOrCallReloc() method can increase trampoline size
|
||||||
|
//! value.
|
||||||
|
inline size_t getTrampolineSize() const
|
||||||
|
{ return _trampolineSize; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Buffer - Getters]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get byte at position @a pos.
|
||||||
|
inline uint8_t getByteAt(size_t pos) const
|
||||||
|
{ return _buffer.getByteAt(pos); }
|
||||||
|
|
||||||
|
//! @brief Get word at position @a pos.
|
||||||
|
inline uint16_t getWordAt(size_t pos) const
|
||||||
|
{ return _buffer.getWordAt(pos); }
|
||||||
|
|
||||||
|
//! @brief Get dword at position @a pos.
|
||||||
|
inline uint32_t getDWordAt(size_t pos) const
|
||||||
|
{ return _buffer.getDWordAt(pos); }
|
||||||
|
|
||||||
|
//! @brief Get qword at position @a pos.
|
||||||
|
inline uint64_t getQWordAt(size_t pos) const
|
||||||
|
{ return _buffer.getQWordAt(pos); }
|
||||||
|
|
||||||
|
//! @brief Get int32_t at position @a pos.
|
||||||
|
inline int32_t getInt32At(size_t pos) const
|
||||||
|
{ return (int32_t)_buffer.getDWordAt(pos); }
|
||||||
|
|
||||||
|
//! @brief Get int64_t at position @a pos.
|
||||||
|
inline int64_t getInt64At(size_t pos) const
|
||||||
|
{ return (int64_t)_buffer.getQWordAt(pos); }
|
||||||
|
|
||||||
|
//! @brief Get intptr_t at position @a pos.
|
||||||
|
inline intptr_t getIntPtrTAt(size_t pos) const
|
||||||
|
{ return _buffer.getIntPtrTAt(pos); }
|
||||||
|
|
||||||
|
//! @brief Get uintptr_t at position @a pos.
|
||||||
|
inline uintptr_t getUIntPtrTAt(size_t pos) const
|
||||||
|
{ return _buffer.getUIntPtrTAt(pos); }
|
||||||
|
|
||||||
|
//! @brief Get uintptr_t at position @a pos.
|
||||||
|
inline size_t getSizeTAt(size_t pos) const
|
||||||
|
{ return _buffer.getSizeTAt(pos); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Buffer - Setters]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Set byte at position @a pos.
|
||||||
|
inline void setByteAt(size_t pos, uint8_t x)
|
||||||
|
{ _buffer.setByteAt(pos, x); }
|
||||||
|
|
||||||
|
//! @brief Set word at position @a pos.
|
||||||
|
inline void setWordAt(size_t pos, uint16_t x)
|
||||||
|
{ _buffer.setWordAt(pos, x); }
|
||||||
|
|
||||||
|
//! @brief Set dword at position @a pos.
|
||||||
|
inline void setDWordAt(size_t pos, uint32_t x)
|
||||||
|
{ _buffer.setDWordAt(pos, x); }
|
||||||
|
|
||||||
|
//! @brief Set qword at position @a pos.
|
||||||
|
inline void setQWordAt(size_t pos, uint64_t x)
|
||||||
|
{ _buffer.setQWordAt(pos, x); }
|
||||||
|
|
||||||
|
//! @brief Set int32_t at position @a pos.
|
||||||
|
inline void setInt32At(size_t pos, int32_t x)
|
||||||
|
{ _buffer.setDWordAt(pos, (uint32_t)x); }
|
||||||
|
|
||||||
|
//! @brief Set int64_t at position @a pos.
|
||||||
|
inline void setInt64At(size_t pos, int64_t x)
|
||||||
|
{ _buffer.setQWordAt(pos, (uint64_t)x); }
|
||||||
|
|
||||||
|
//! @brief Set intptr_t at position @a pos.
|
||||||
|
inline void setIntPtrTAt(size_t pos, intptr_t x)
|
||||||
|
{ _buffer.setIntPtrTAt(pos, x); }
|
||||||
|
|
||||||
|
//! @brief Set uintptr_t at position @a pos.
|
||||||
|
inline void setUInt64At(size_t pos, uintptr_t x)
|
||||||
|
{ _buffer.setUIntPtrTAt(pos, x); }
|
||||||
|
|
||||||
|
//! @brief Set size_t at position @a pos.
|
||||||
|
inline void setSizeTAt(size_t pos, size_t x)
|
||||||
|
{ _buffer.setSizeTAt(pos, x); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [CanEmit]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get whether the instruction can be emitted.
|
||||||
|
//!
|
||||||
|
//! This function behaves like @c ensureSpace(), but it also checks if
|
||||||
|
//! assembler is in error state and in that case it returns @c false.
|
||||||
|
//! Assembler internally always uses this function before new instruction is
|
||||||
|
//! emitted.
|
||||||
|
//!
|
||||||
|
//! It's implemented like:
|
||||||
|
//! <code>return ensureSpace() && !getError();</code>
|
||||||
|
inline bool canEmit()
|
||||||
|
{
|
||||||
|
// If there is an error, we can't emit another instruction until last error
|
||||||
|
// is cleared by calling @c setError(kErrorOk). If something caused the
|
||||||
|
// error while generating code it's probably fatal in all cases. You can't
|
||||||
|
// use generated code anymore, because you are not sure about the status.
|
||||||
|
if (_error)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// The ensureSpace() method returns true on success and false on failure. We
|
||||||
|
// are catching return value and setting error code here.
|
||||||
|
if (ensureSpace())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// If we are here, there is memory allocation error. Note that this is HEAP
|
||||||
|
// allocation error, virtual allocation error can be caused only by
|
||||||
|
// AsmJit::VirtualMemory class!
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Emit]
|
||||||
|
//
|
||||||
|
// These functions are not protected against buffer overrun. Each place of
|
||||||
|
// code which calls these functions ensures that there is some space using
|
||||||
|
// canEmit() method. Emitters are internally protected in AsmJit::Buffer,
|
||||||
|
// but only in debug builds.
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Emit Byte to internal buffer.
|
||||||
|
inline void _emitByte(uint8_t x)
|
||||||
|
{ _buffer.emitByte(x); }
|
||||||
|
|
||||||
|
//! @brief Emit word (2 bytes) to internal buffer.
|
||||||
|
inline void _emitWord(uint16_t x)
|
||||||
|
{ _buffer.emitWord(x); }
|
||||||
|
|
||||||
|
//! @brief Emit dword (4 bytes) to internal buffer.
|
||||||
|
inline void _emitDWord(uint32_t x)
|
||||||
|
{ _buffer.emitDWord(x); }
|
||||||
|
|
||||||
|
//! @brief Emit qword (8 bytes) to internal buffer.
|
||||||
|
inline void _emitQWord(uint64_t x)
|
||||||
|
{ _buffer.emitQWord(x); }
|
||||||
|
|
||||||
|
//! @brief Emit Int32 (4 bytes) to internal buffer.
|
||||||
|
inline void _emitInt32(int32_t x)
|
||||||
|
{ _buffer.emitDWord((uint32_t)x); }
|
||||||
|
|
||||||
|
//! @brief Emit Int64 (8 bytes) to internal buffer.
|
||||||
|
inline void _emitInt64(int64_t x)
|
||||||
|
{ _buffer.emitQWord((uint64_t)x); }
|
||||||
|
|
||||||
|
//! @brief Emit intptr_t (4 or 8 bytes) to internal buffer.
|
||||||
|
inline void _emitIntPtrT(intptr_t x)
|
||||||
|
{ _buffer.emitIntPtrT(x); }
|
||||||
|
|
||||||
|
//! @brief Emit uintptr_t (4 or 8 bytes) to internal buffer.
|
||||||
|
inline void _emitUIntPtrT(uintptr_t x)
|
||||||
|
{ _buffer.emitUIntPtrT(x); }
|
||||||
|
|
||||||
|
//! @brief Emit size_t (4 or 8 bytes) to internal buffer.
|
||||||
|
inline void _emitSizeT(size_t x)
|
||||||
|
{ _buffer.emitSizeT(x); }
|
||||||
|
|
||||||
|
//! @brief Embed data into instruction stream.
|
||||||
|
ASMJIT_API void embed(const void* data, size_t len);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Reloc]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Relocate code to a given address @a dst.
|
||||||
|
//!
|
||||||
|
//! @param dst Where the relocated code should me stored. The pointer can be
|
||||||
|
//! address returned by virtual memory allocator or your own address if you
|
||||||
|
//! want only to store the code for later reuse (or load, etc...).
|
||||||
|
//! @param addressBase Base address used for relocation. When using JIT code
|
||||||
|
//! generation, this will be the same as @a dst, only casted to system
|
||||||
|
//! integer type. But when generating code for remote process then the value
|
||||||
|
//! can be different.
|
||||||
|
//!
|
||||||
|
//! @retval The bytes used. Code-generator can create trampolines which are
|
||||||
|
//! used when calling other functions inside the JIT code. However, these
|
||||||
|
//! trampolines can be unused so the relocCode() returns the exact size needed
|
||||||
|
//! for the function.
|
||||||
|
//!
|
||||||
|
//! A given buffer will be overwritten, to get number of bytes required use
|
||||||
|
//! @c getCodeSize().
|
||||||
|
virtual size_t relocCode(void* dst, sysuint_t addressBase) const = 0;
|
||||||
|
|
||||||
|
//! @brief Simplifed version of @c relocCode() method designed for JIT.
|
||||||
|
//!
|
||||||
|
//! @overload
|
||||||
|
inline size_t relocCode(void* dst) const
|
||||||
|
{ return relocCode(dst, (uintptr_t)dst); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Make]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Make is convenience method to make currently serialized code and
|
||||||
|
//! return pointer to generated function.
|
||||||
|
//!
|
||||||
|
//! What you need is only to cast this pointer to your function type and call
|
||||||
|
//! it. Note that if there was an error and calling @c getError() method not
|
||||||
|
//! returns @c kErrorOk (zero) then this function always return @c NULL and
|
||||||
|
//! error value remains the same.
|
||||||
|
virtual void* make() = 0;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Helpers]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API LabelLink* _newLabelLink();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief ZoneMemory management.
|
||||||
|
ZoneMemory _zoneMemory;
|
||||||
|
//! @brief Binary code buffer.
|
||||||
|
Buffer _buffer;
|
||||||
|
|
||||||
|
//! @brief Context (for example @ref JitContext).
|
||||||
|
Context* _context;
|
||||||
|
//! @brief Logger.
|
||||||
|
Logger* _logger;
|
||||||
|
|
||||||
|
//! @brief Error code.
|
||||||
|
uint32_t _error;
|
||||||
|
//! @brief Properties.
|
||||||
|
uint32_t _properties;
|
||||||
|
//! @brief Emit flags for next instruction (cleared after emit).
|
||||||
|
uint32_t _emitOptions;
|
||||||
|
//! @brief Size of possible trampolines.
|
||||||
|
uint32_t _trampolineSize;
|
||||||
|
|
||||||
|
//! @brief Inline comment that will be logged by the next instruction and
|
||||||
|
//! set to NULL.
|
||||||
|
const char* _inlineComment;
|
||||||
|
//! @brief Linked list of unused links (@c LabelLink* structures)
|
||||||
|
LabelLink* _unusedLinks;
|
||||||
|
|
||||||
|
//! @brief Labels data.
|
||||||
|
PodVector<LabelData> _labels;
|
||||||
|
//! @brief Relocations data.
|
||||||
|
PodVector<RelocData> _relocData;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_ASSEMBLER_H
|
|
@ -0,0 +1,34 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/assert.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
// helpers
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Assert]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void assertionFailure(const char* file, int line, const char* exp)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"*** ASSERTION FAILURE at %s (line %d)\n"
|
||||||
|
"*** %s\n", file, line, exp);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,65 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_ASSERT_H
|
||||||
|
#define _ASMJIT_CORE_ASSERT_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/build.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Core
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Assert]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Called in debug build on assertion failure.
|
||||||
|
//! @param file Source file name where it happened.
|
||||||
|
//! @param line Line in the source file.
|
||||||
|
//! @param exp Expression what failed.
|
||||||
|
//!
|
||||||
|
//! If you have problems with assertions simply put a breakpoint into
|
||||||
|
//! AsmJit::assertionFailure() method (AsmJit/Core/Assert.cpp file) and examine
|
||||||
|
//! call stack.
|
||||||
|
ASMJIT_API void assertionFailure(const char* file, int line, const char* exp);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [ASMJIT_ASSERT]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
#if defined(ASMJIT_DEBUG)
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_ASSERT)
|
||||||
|
#define ASMJIT_ASSERT(exp) \
|
||||||
|
do { \
|
||||||
|
if (!(exp)) ::AsmJit::assertionFailure(__FILE__, __LINE__, #exp); \
|
||||||
|
} while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_ASSERT)
|
||||||
|
#define ASMJIT_ASSERT(exp) ASMJIT_NOP()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_ASSERT_H
|
|
@ -0,0 +1,102 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/buffer.h"
|
||||||
|
#include "../core/defs.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Buffer]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Buffer::emitData(const void* ptr, size_t len)
|
||||||
|
{
|
||||||
|
size_t max = getCapacity() - getOffset();
|
||||||
|
|
||||||
|
if (max < len && !realloc(getOffset() + len))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(_cur, ptr, len);
|
||||||
|
_cur += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Buffer::realloc(size_t to)
|
||||||
|
{
|
||||||
|
if (getCapacity() < to)
|
||||||
|
{
|
||||||
|
size_t len = getOffset();
|
||||||
|
uint8_t *newdata;
|
||||||
|
|
||||||
|
if (_data != NULL)
|
||||||
|
newdata = (uint8_t*)ASMJIT_REALLOC(_data, to);
|
||||||
|
else
|
||||||
|
newdata = (uint8_t*)ASMJIT_MALLOC(to);
|
||||||
|
|
||||||
|
if (newdata == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_data = newdata;
|
||||||
|
_cur = newdata + len;
|
||||||
|
_max = newdata + to;
|
||||||
|
_max -= (to >= kBufferGrow) ? kBufferGrow : to;
|
||||||
|
|
||||||
|
_capacity = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Buffer::grow()
|
||||||
|
{
|
||||||
|
size_t to = _capacity;
|
||||||
|
|
||||||
|
if (to < 512)
|
||||||
|
to = 1024;
|
||||||
|
else if (to > 65536)
|
||||||
|
to += 65536;
|
||||||
|
else
|
||||||
|
to <<= 1;
|
||||||
|
|
||||||
|
return realloc(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::reset()
|
||||||
|
{
|
||||||
|
if (_data == NULL)
|
||||||
|
return;
|
||||||
|
ASMJIT_FREE(_data);
|
||||||
|
|
||||||
|
_data = NULL;
|
||||||
|
_cur = NULL;
|
||||||
|
_max = NULL;
|
||||||
|
_capacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* Buffer::take()
|
||||||
|
{
|
||||||
|
uint8_t* data = _data;
|
||||||
|
|
||||||
|
_data = NULL;
|
||||||
|
_cur = NULL;
|
||||||
|
_max = NULL;
|
||||||
|
_capacity = 0;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,348 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_BUFFER_H
|
||||||
|
#define _ASMJIT_CORE_BUFFER_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/assert.h"
|
||||||
|
#include "../core/build.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Core
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [Forward Declarations]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
struct Buffer;
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Buffer]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Buffer used to store instruction stream in AsmJit.
|
||||||
|
//!
|
||||||
|
//! This class can be dangerous, if you don't know how it works. Assembler
|
||||||
|
//! instruction stream is usually constructed by multiple calls of emit
|
||||||
|
//! functions that emits bytes, words, dwords or qwords. But to decrease
|
||||||
|
//! AsmJit library size and improve performance, we are not checking for
|
||||||
|
//! buffer overflow for each emit operation, but only once in highler level
|
||||||
|
//! emit instruction.
|
||||||
|
//!
|
||||||
|
//! So, if you want to use this class, you need to do buffer checking yourself
|
||||||
|
//! by using @c ensureSpace() method. It's designed to grow buffer if needed.
|
||||||
|
//! Threshold for growing is named @c growThreshold() and it means count of
|
||||||
|
//! bytes for emitting single operation. Default size is set to 16 bytes,
|
||||||
|
//! because x86 and x64 instruction can't be larger (so it's space to hold 1
|
||||||
|
//! instruction).
|
||||||
|
//!
|
||||||
|
//! Example using Buffer:
|
||||||
|
//!
|
||||||
|
//! @code
|
||||||
|
//! // Buffer instance, growThreshold == 16
|
||||||
|
//! // (no memory allocated in constructor).
|
||||||
|
//! AsmJit::Buffer buf(16);
|
||||||
|
//!
|
||||||
|
//! // Begin of emit stream, ensure space can fail on out of memory error.
|
||||||
|
//! if (buf.ensureSpace())
|
||||||
|
//! {
|
||||||
|
//! // here, you can emit up to 16 (growThreshold) bytes
|
||||||
|
//! buf.emitByte(0x00);
|
||||||
|
//! buf.emitByte(0x01);
|
||||||
|
//! buf.emitByte(0x02);
|
||||||
|
//! buf.emitByte(0x03);
|
||||||
|
//! ...
|
||||||
|
//! }
|
||||||
|
//! @endcode
|
||||||
|
struct Buffer
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline Buffer() :
|
||||||
|
_data(NULL),
|
||||||
|
_cur(NULL),
|
||||||
|
_max(NULL),
|
||||||
|
_capacity(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ~Buffer()
|
||||||
|
{
|
||||||
|
if (_data) ASMJIT_FREE(_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Get start of buffer.
|
||||||
|
inline uint8_t* getData() const { return _data; }
|
||||||
|
|
||||||
|
//! @brief Get current pointer in code buffer.
|
||||||
|
inline uint8_t* getCur() const { return _cur; }
|
||||||
|
|
||||||
|
//! @brief Get maximum pointer in code buffer for growing.
|
||||||
|
inline uint8_t* getMax() const { return _max; }
|
||||||
|
|
||||||
|
//! @brief Get current offset in buffer.
|
||||||
|
inline size_t getOffset() const { return (size_t)(_cur - _data); }
|
||||||
|
|
||||||
|
//! @brief Get capacity of buffer.
|
||||||
|
inline size_t getCapacity() const { return _capacity; }
|
||||||
|
|
||||||
|
//! @brief Ensure space for next instruction
|
||||||
|
inline bool ensureSpace() { return (_cur >= _max) ? grow() : true; }
|
||||||
|
|
||||||
|
//! @brief Sets offset to @a o and returns previous offset.
|
||||||
|
//!
|
||||||
|
//! This method can be used to truncate buffer or it's used to
|
||||||
|
//! overwrite specific position in buffer by Assembler.
|
||||||
|
inline size_t toOffset(size_t offset)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(offset < _capacity);
|
||||||
|
|
||||||
|
size_t prev = (size_t)(_cur - _data);
|
||||||
|
_cur = _data + offset;
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Reallocate buffer.
|
||||||
|
//!
|
||||||
|
//! It's only used for growing, buffer is never reallocated to smaller
|
||||||
|
//! number than current capacity() is.
|
||||||
|
ASMJIT_API bool realloc(size_t to);
|
||||||
|
|
||||||
|
//! @brief Used to grow the buffer.
|
||||||
|
//!
|
||||||
|
//! It will typically realloc to twice size of capacity(), but if capacity()
|
||||||
|
//! is large, it will use smaller steps.
|
||||||
|
ASMJIT_API bool grow();
|
||||||
|
|
||||||
|
//! @brief Clear everything, but not deallocate buffer.
|
||||||
|
inline void clear() { _cur = _data; }
|
||||||
|
|
||||||
|
//! @brief Free buffer and NULL all pointers.
|
||||||
|
ASMJIT_API void reset();
|
||||||
|
|
||||||
|
//! @brief Take ownership of the buffer data and purge @c Buffer instance.
|
||||||
|
ASMJIT_API uint8_t* take();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Emit]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Emit Byte.
|
||||||
|
inline void emitByte(uint8_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(getOffset() + 1 <= _capacity);
|
||||||
|
|
||||||
|
*_cur++ = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Emit Word (2 bytes).
|
||||||
|
inline void emitWord(uint16_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(getOffset() + 2 <= _capacity);
|
||||||
|
|
||||||
|
*(uint16_t *)_cur = x;
|
||||||
|
_cur += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Emit DWord (4 bytes).
|
||||||
|
inline void emitDWord(uint32_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(getOffset() + 4 <= _capacity);
|
||||||
|
|
||||||
|
*(uint32_t *)_cur = x;
|
||||||
|
_cur += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Emit QWord (8 bytes).
|
||||||
|
inline void emitQWord(uint64_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(getOffset() + 8 <= _capacity);
|
||||||
|
|
||||||
|
*(uint64_t *)_cur = x;
|
||||||
|
_cur += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Emit intptr_t (4 or 8 bytes).
|
||||||
|
inline void emitIntPtrT(intptr_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(getOffset() + sizeof(intptr_t) <= _capacity);
|
||||||
|
|
||||||
|
*(intptr_t *)_cur = x;
|
||||||
|
_cur += sizeof(intptr_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Emit uintptr_t (4 or 8 bytes).
|
||||||
|
inline void emitUIntPtrT(uintptr_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(getOffset() + sizeof(uintptr_t) <= _capacity);
|
||||||
|
|
||||||
|
*(uintptr_t *)_cur = x;
|
||||||
|
_cur += sizeof(uintptr_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Emit size_t (4 or 8 bytes).
|
||||||
|
inline void emitSizeT(size_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(getOffset() + sizeof(size_t) <= _capacity);
|
||||||
|
|
||||||
|
*(size_t *)_cur = x;
|
||||||
|
_cur += sizeof(size_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Emit custom data.
|
||||||
|
ASMJIT_API void emitData(const void* ptr, size_t len);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Get / Set]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Set byte at position @a pos.
|
||||||
|
inline uint8_t getByteAt(size_t pos) const
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + 1 <= _capacity);
|
||||||
|
|
||||||
|
return *reinterpret_cast<const uint8_t*>(_data + pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set word at position @a pos.
|
||||||
|
inline uint16_t getWordAt(size_t pos) const
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + 2 <= _capacity);
|
||||||
|
|
||||||
|
return *reinterpret_cast<const uint16_t*>(_data + pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set dword at position @a pos.
|
||||||
|
inline uint32_t getDWordAt(size_t pos) const
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + 4 <= _capacity);
|
||||||
|
|
||||||
|
return *reinterpret_cast<const uint32_t*>(_data + pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set qword at position @a pos.
|
||||||
|
inline uint64_t getQWordAt(size_t pos) const
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + 8 <= _capacity);
|
||||||
|
|
||||||
|
return *reinterpret_cast<const uint64_t*>(_data + pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set intptr_t at position @a pos.
|
||||||
|
inline intptr_t getIntPtrTAt(size_t pos) const
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + sizeof(intptr_t) <= _capacity);
|
||||||
|
|
||||||
|
return *reinterpret_cast<const intptr_t*>(_data + pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set uintptr_t at position @a pos.
|
||||||
|
inline uintptr_t getUIntPtrTAt(size_t pos) const
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + sizeof(uintptr_t) <= _capacity);
|
||||||
|
|
||||||
|
return *reinterpret_cast<const uintptr_t*>(_data + pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set size_t at position @a pos.
|
||||||
|
inline uintptr_t getSizeTAt(size_t pos) const
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + sizeof(size_t) <= _capacity);
|
||||||
|
|
||||||
|
return *reinterpret_cast<const size_t*>(_data + pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set byte at position @a pos.
|
||||||
|
inline void setByteAt(size_t pos, uint8_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + 1 <= _capacity);
|
||||||
|
|
||||||
|
*reinterpret_cast<uint8_t*>(_data + pos) = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set word at position @a pos.
|
||||||
|
inline void setWordAt(size_t pos, uint16_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + 2 <= _capacity);
|
||||||
|
|
||||||
|
*reinterpret_cast<uint16_t*>(_data + pos) = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set dword at position @a pos.
|
||||||
|
inline void setDWordAt(size_t pos, uint32_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + 4 <= _capacity);
|
||||||
|
|
||||||
|
*reinterpret_cast<uint32_t*>(_data + pos) = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set qword at position @a pos.
|
||||||
|
inline void setQWordAt(size_t pos, uint64_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + 8 <= _capacity);
|
||||||
|
|
||||||
|
*reinterpret_cast<uint64_t*>(_data + pos) = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set intptr_t at position @a pos.
|
||||||
|
inline void setIntPtrTAt(size_t pos, intptr_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + sizeof(intptr_t) <= _capacity);
|
||||||
|
|
||||||
|
*reinterpret_cast<intptr_t*>(_data + pos) = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set uintptr_t at position @a pos.
|
||||||
|
inline void setUIntPtrTAt(size_t pos, uintptr_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + sizeof(uintptr_t) <= _capacity);
|
||||||
|
|
||||||
|
*reinterpret_cast<uintptr_t*>(_data + pos) = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set size_t at position @a pos.
|
||||||
|
inline void setSizeTAt(size_t pos, size_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(pos + sizeof(size_t) <= _capacity);
|
||||||
|
|
||||||
|
*reinterpret_cast<size_t*>(_data + pos) = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// All members are public, because they can be accessed and modified by
|
||||||
|
// Assembler/Compiler directly.
|
||||||
|
|
||||||
|
//! @brief Beginning position of buffer.
|
||||||
|
uint8_t* _data;
|
||||||
|
//! @brief Current position in buffer.
|
||||||
|
uint8_t* _cur;
|
||||||
|
//! @brief Maximum position in buffer for realloc.
|
||||||
|
uint8_t* _max;
|
||||||
|
|
||||||
|
//! @brief Buffer capacity (in bytes).
|
||||||
|
size_t _capacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
#endif // _ASMJIT_CORE_BUFFER_H
|
|
@ -5,23 +5,32 @@
|
||||||
// Zlib - See COPYING file in this package.
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#ifndef _ASMJIT_BUILD_H
|
#ifndef _ASMJIT_CORE_BUILD_H
|
||||||
#define _ASMJIT_BUILD_H
|
#define _ASMJIT_CORE_BUILD_H
|
||||||
|
|
||||||
// [Include]
|
// [Include]
|
||||||
#include "Config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
|
#if defined(ASMJIT_EXPORTS)
|
||||||
|
# if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
||||||
|
# define _CRT_SECURE_NO_WARNINGS
|
||||||
|
# endif // _MSC_VER
|
||||||
|
#endif // ASMJIT_EXPORTS
|
||||||
|
|
||||||
// Here should be optional include files that's needed fo successfuly
|
// Here should be optional include files that's needed fo successfuly
|
||||||
// use macros defined here. Remember, AsmJit uses only AsmJit namespace
|
// use macros defined here. Remember, AsmJit uses only AsmJit namespace
|
||||||
// and all macros are used within it.
|
// and all macros are used within it.
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
#include <new>
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
// [AsmJit - OS]
|
// [AsmJit - OS]
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
|
|
||||||
#if defined(WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(_WIN64)
|
#if defined(WINDOWS) || defined(_WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(_WIN64)
|
||||||
# define ASMJIT_WINDOWS
|
# define ASMJIT_WINDOWS
|
||||||
#elif defined(__linux__) || defined(__unix__) || \
|
#elif defined(__linux__) || defined(__unix__) || \
|
||||||
defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
|
defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
|
||||||
|
@ -33,9 +42,9 @@
|
||||||
# define ASMJIT_POSIX
|
# define ASMJIT_POSIX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
// [AsmJit - Architecture]
|
// [AsmJit - Architecture]
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
|
|
||||||
// define it only if it's not defined. In some systems we can
|
// define it only if it's not defined. In some systems we can
|
||||||
// use -D command in compiler to bypass this autodetection.
|
// use -D command in compiler to bypass this autodetection.
|
||||||
|
@ -49,32 +58,25 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
// [AsmJit - API]
|
// [AsmJit - API]
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
|
|
||||||
// Hide AsmJit symbols that we don't want to export (AssemblerIntrinsics class for example).
|
|
||||||
#if !defined(ASMJIT_HIDDEN)
|
|
||||||
# if defined(__GNUC__) && __GNUC__ >= 4
|
|
||||||
# define ASMJIT_HIDDEN __attribute__((visibility("hidden")))
|
|
||||||
# endif // __GNUC__ && __GNUC__ >= 4
|
|
||||||
#endif // ASMJIT_HIDDEN
|
|
||||||
|
|
||||||
// Make AsmJit as shared library by default.
|
// Make AsmJit as shared library by default.
|
||||||
#if !defined(ASMJIT_API)
|
#if !defined(ASMJIT_API)
|
||||||
# if defined(ASMJIT_WINDOWS)
|
# if defined(ASMJIT_WINDOWS)
|
||||||
# if defined(__GNUC__)
|
# if defined(__GNUC__)
|
||||||
# if defined(AsmJit_EXPORTS)
|
# if defined(ASMJIT_EXPORTS)
|
||||||
# define ASMJIT_API __attribute__((dllexport))
|
# define ASMJIT_API __attribute__((dllexport))
|
||||||
# else
|
# else
|
||||||
# define ASMJIT_API __attribute__((dllimport))
|
# define ASMJIT_API __attribute__((dllimport))
|
||||||
# endif // AsmJit_EXPORTS
|
# endif // ASMJIT_EXPORTS
|
||||||
# else
|
# else
|
||||||
# if defined(AsmJit_EXPORTS)
|
# if defined(ASMJIT_EXPORTS)
|
||||||
# define ASMJIT_API __declspec(dllexport)
|
# define ASMJIT_API __declspec(dllexport)
|
||||||
# else
|
# else
|
||||||
# define ASMJIT_API __declspec(dllimport)
|
# define ASMJIT_API __declspec(dllimport)
|
||||||
# endif // AsmJit_EXPORTS
|
# endif // ASMJIT_EXPORTS
|
||||||
# endif // __GNUC__
|
# endif // __GNUC__
|
||||||
# else
|
# else
|
||||||
# if defined(__GNUC__)
|
# if defined(__GNUC__)
|
||||||
|
@ -86,21 +88,13 @@
|
||||||
# endif
|
# endif
|
||||||
#endif // ASMJIT_API
|
#endif // ASMJIT_API
|
||||||
|
|
||||||
#if defined(ASMJIT_API)
|
#if !defined(ASMJIT_VAR)
|
||||||
# define ASMJIT_VAR extern ASMJIT_API
|
# if defined(ASMJIT_API)
|
||||||
#else
|
# define ASMJIT_VAR extern ASMJIT_API
|
||||||
# define ASMJIT_API
|
# else
|
||||||
# define ASMJIT_VAR
|
# define ASMJIT_VAR
|
||||||
#endif // ASMJIT_API
|
# endif // ASMJIT_API
|
||||||
|
#endif // !ASMJIT_VAR
|
||||||
// If not detected, fallback to nothing.
|
|
||||||
#if !defined(ASMJIT_HIDDEN)
|
|
||||||
# define ASMJIT_HIDDEN
|
|
||||||
#endif // ASMJIT_HIDDEN
|
|
||||||
|
|
||||||
#if !defined(ASMJIT_NOTHROW)
|
|
||||||
#define ASMJIT_NOTHROW throw()
|
|
||||||
#endif // ASMJIT_NOTHROW
|
|
||||||
|
|
||||||
// [AsmJit - Memory Management]
|
// [AsmJit - Memory Management]
|
||||||
#if !defined(ASMJIT_MALLOC)
|
#if !defined(ASMJIT_MALLOC)
|
||||||
|
@ -115,9 +109,9 @@
|
||||||
# define ASMJIT_FREE ::free
|
# define ASMJIT_FREE ::free
|
||||||
#endif // ASMJIT_FREE
|
#endif // ASMJIT_FREE
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
// [AsmJit - Calling Conventions]
|
// [AsmJit - Calling Conventions]
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
|
|
||||||
#if defined(ASMJIT_X86)
|
#if defined(ASMJIT_X86)
|
||||||
# if defined(__GNUC__)
|
# if defined(__GNUC__)
|
||||||
|
@ -147,94 +141,58 @@
|
||||||
#endif // ASMJIT_NOP
|
#endif // ASMJIT_NOP
|
||||||
|
|
||||||
// [AsmJit - C++ Compiler Support]
|
// [AsmJit - C++ Compiler Support]
|
||||||
#define ASMJIT_TYPE_TO_TYPE(type) type
|
#define ASMJIT_TYPE_TO_TYPE(_Type_) _Type_
|
||||||
#define ASMJIT_HAS_STANDARD_DEFINE_OPTIONS
|
#define ASMJIT_HAS_STANDARD_DEFINE_OPTIONS
|
||||||
#define ASMJIT_HAS_PARTIAL_TEMPLATE_SPECIALIZATION
|
#define ASMJIT_HAS_PARTIAL_TEMPLATE_SPECIALIZATION
|
||||||
|
|
||||||
// Support for VC6
|
// Support for VC6
|
||||||
#if defined(_MSC_VER) && (_MSC_VER < 1400)
|
#if defined(_MSC_VER) && (_MSC_VER < 1400)
|
||||||
#undef ASMJIT_TYPE_TO_TYPE
|
|
||||||
namespace AsmJit {
|
namespace AsmJit {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct _Type2Type { typedef T Type; };
|
struct _Type2Type { typedef T Type; };
|
||||||
}
|
}
|
||||||
#define ASMJIT_TYPE_TO_TYPE(T) _Type2Type<T>::Type
|
|
||||||
|
#undef ASMJIT_TYPE_TO_TYPE
|
||||||
|
#define ASMJIT_TYPE_TO_TYPE(_Type_) ::AsmJit::_Type2Type<_Type_>::Type
|
||||||
|
|
||||||
#undef ASMJIT_HAS_STANDARD_DEFINE_OPTIONS
|
#undef ASMJIT_HAS_STANDARD_DEFINE_OPTIONS
|
||||||
#undef ASMJIT_HAS_PARTIAL_TEMPLATE_SPECIALIZATION
|
#undef ASMJIT_HAS_PARTIAL_TEMPLATE_SPECIALIZATION
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
// [AsmJit - Types]
|
// [AsmJit - Types]
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
|
|
||||||
#if defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1600)
|
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||||
|
# include <sys/types.h>
|
||||||
// Use <stdint.h>
|
#endif // __MINGW32__ || __MINGW64__
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||||
|
# if (_MSC_VER < 1300)
|
||||||
|
typedef signed char int8_t;
|
||||||
|
typedef signed short int16_t;
|
||||||
|
typedef signed int int32_t;
|
||||||
|
typedef signed __int64 int64_t;
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
# else
|
||||||
|
typedef signed __int8 int8_t;
|
||||||
|
typedef signed __int16 int16_t;
|
||||||
|
typedef signed __int32 int32_t;
|
||||||
|
typedef signed __int64 int64_t;
|
||||||
|
typedef unsigned __int8 uint8_t;
|
||||||
|
typedef unsigned __int16 uint16_t;
|
||||||
|
typedef unsigned __int32 uint32_t;
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
# endif // _MSC_VER
|
||||||
#else
|
#else
|
||||||
|
# include <stdint.h>
|
||||||
// Use typedefs.
|
# include <limits.h>
|
||||||
#if defined(_MSC_VER)
|
#endif
|
||||||
#if (_MSC_VER < 1300)
|
|
||||||
|
|
||||||
#ifndef HAVE_INT8_T
|
|
||||||
typedef char int8_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_INT16_T
|
|
||||||
typedef short int16_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_INT32_T
|
|
||||||
typedef int int32_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_UINT8_T
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_UINT16_T
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_UINT32_T
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_INT64_T
|
|
||||||
typedef __int64 int64_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_UINT64_T
|
|
||||||
typedef unsigned __int64 uint64_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#ifndef HAVE_INT8_T
|
|
||||||
typedef __int8 int8_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_INT16_T
|
|
||||||
typedef __int16 int16_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_INT32_T
|
|
||||||
typedef __int32 int32_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_INT64_T
|
|
||||||
typedef __int64 int64_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_UINT8_T
|
|
||||||
typedef unsigned __int8 uint8_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_UINT16_T
|
|
||||||
typedef unsigned __int16 uint16_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_UINT32_T
|
|
||||||
typedef unsigned __int32 uint32_t;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_UINT64_T
|
|
||||||
typedef unsigned __int64 uint64_t;
|
|
||||||
#endif //HAVE_U_INT64_T
|
|
||||||
|
|
||||||
#endif // _MSC_VER
|
|
||||||
#endif // _MSC_VER
|
|
||||||
#endif // STDINT.H
|
|
||||||
|
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
typedef unsigned short ushort;
|
typedef unsigned short ushort;
|
||||||
|
@ -257,20 +215,21 @@ typedef uint64_t sysuint_t;
|
||||||
# define ASMJIT_UINT64_C(num) num##ULL
|
# define ASMJIT_UINT64_C(num) num##ULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
// [AsmJit - C++ Macros]
|
// [AsmJit - C++ Macros]
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
|
|
||||||
#define ASMJIT_ARRAY_SIZE(A) (sizeof(A) / sizeof(*A))
|
#define ASMJIT_ARRAY_SIZE(A) (sizeof(A) / sizeof(*A))
|
||||||
|
|
||||||
#define ASMJIT_DISABLE_COPY(__type__) \
|
#define ASMJIT_NO_COPY(__type__) \
|
||||||
private: \
|
private: \
|
||||||
inline __type__(const __type__& other); \
|
inline __type__(const __type__& other); \
|
||||||
inline __type__& operator=(const __type__& other);
|
inline __type__& operator=(const __type__& other); \
|
||||||
|
public:
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
// [AsmJit - Debug]
|
// [AsmJit - Debug]
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
|
|
||||||
// If ASMJIT_DEBUG and ASMJIT_NO_DEBUG is not defined then ASMJIT_DEBUG will be
|
// If ASMJIT_DEBUG and ASMJIT_NO_DEBUG is not defined then ASMJIT_DEBUG will be
|
||||||
// detected using the compiler specific macros. This enables to set the build
|
// detected using the compiler specific macros. This enables to set the build
|
||||||
|
@ -282,40 +241,49 @@ private: \
|
||||||
#endif // _DEBUG
|
#endif // _DEBUG
|
||||||
|
|
||||||
#endif // !ASMJIT_DEBUG && !ASMJIT_NO_DEBUG
|
#endif // !ASMJIT_DEBUG && !ASMJIT_NO_DEBUG
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// [AsmJit - Assert]
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace AsmJit {
|
// ============================================================================
|
||||||
ASMJIT_API void assertionFailure(const char* file, int line, const char* exp);
|
// [AsmJit - Initialize/DontInitialize]
|
||||||
} // AsmJit namespace
|
// ============================================================================
|
||||||
|
|
||||||
#if defined(ASMJIT_DEBUG)
|
// TODO: This should be moved to AsmJit namespace!
|
||||||
# if !defined(ASMJIT_ASSERT)
|
|
||||||
# define ASMJIT_ASSERT(exp) do { if (!(exp)) ::AsmJit::assertionFailure(__FILE__, __LINE__, #exp); } while(0)
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# if !defined(ASMJIT_ASSERT)
|
|
||||||
# define ASMJIT_ASSERT(exp) ASMJIT_NOP()
|
|
||||||
# endif
|
|
||||||
#endif // DEBUG
|
|
||||||
|
|
||||||
// GCC warnings fix: I can't understand why GCC has no interface to push/pop
|
// Skip documenting this.
|
||||||
// specific warnings.
|
#if !defined(ASMJIT_NODOC)
|
||||||
// #if defined(__GNUC__)
|
struct _Initialize {};
|
||||||
// # if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 402001
|
struct _DontInitialize {};
|
||||||
// # pragma GCC diagnostic ignored "-w"
|
#endif // !ASMJIT_NODOC
|
||||||
// # endif
|
|
||||||
// #endif // __GNUC__
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
|
// [AsmJit - Void]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// TODO: This should be moved to AsmJit namespace!
|
||||||
|
|
||||||
|
//! @brief Void type which can be used in @ref FunctionDeclaration templates.
|
||||||
|
struct Void {};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [asmjit_cast<>]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Cast used to cast pointer to function. It's like reinterpret_cast<>,
|
||||||
|
//! but uses internally C style cast to work with MinGW.
|
||||||
|
//!
|
||||||
|
//! If you are using single compiler and @c reinterpret_cast<> works for you,
|
||||||
|
//! there is no reason to use @c asmjit_cast<>. If you are writing
|
||||||
|
//! cross-platform software with various compiler support, consider using
|
||||||
|
//! @c asmjit_cast<> instead of @c reinterpret_cast<>.
|
||||||
|
template<typename T, typename Z>
|
||||||
|
static inline T asmjit_cast(Z* p) { return (T)p; }
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
// [AsmJit - OS Support]
|
// [AsmJit - OS Support]
|
||||||
// ----------------------------------------------------------------------------
|
// ============================================================================
|
||||||
|
|
||||||
#if defined(ASMJIT_WINDOWS)
|
#if defined(ASMJIT_WINDOWS)
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#endif // ASMJIT_WINDOWS
|
#endif // ASMJIT_WINDOWS
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#endif // _ASMJIT_BUILD_H
|
#endif // _ASMJIT_CORE_BUILD_H
|
|
@ -0,0 +1,274 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/assembler.h"
|
||||||
|
#include "../core/compiler.h"
|
||||||
|
#include "../core/compilercontext.h"
|
||||||
|
#include "../core/compilerfunc.h"
|
||||||
|
#include "../core/compileritem.h"
|
||||||
|
#include "../core/cpuinfo.h"
|
||||||
|
#include "../core/intutil.h"
|
||||||
|
#include "../core/logger.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
Compiler::Compiler(Context* context) :
|
||||||
|
_zoneMemory(16384 - sizeof(ZoneChunk) - 32),
|
||||||
|
_linkMemory(1024 - 32),
|
||||||
|
_context(context != NULL ? context : static_cast<Context*>(JitContext::getGlobal())),
|
||||||
|
_logger(NULL),
|
||||||
|
_error(0),
|
||||||
|
_properties(0),
|
||||||
|
_emitOptions(0),
|
||||||
|
_finished(false),
|
||||||
|
_first(NULL),
|
||||||
|
_last(NULL),
|
||||||
|
_current(NULL),
|
||||||
|
_func(NULL),
|
||||||
|
_cc(NULL),
|
||||||
|
_varNameId(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Compiler::~Compiler()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Logging]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Compiler::setLogger(Logger* logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Error Handling]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Compiler::setError(uint32_t error)
|
||||||
|
{
|
||||||
|
_error = error;
|
||||||
|
if (_error == kErrorOk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_logger)
|
||||||
|
_logger->logFormat("*** COMPILER ERROR: %s (%u).\n", getErrorString(error), (unsigned int)error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Properties]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
uint32_t Compiler::getProperty(uint32_t propertyId)
|
||||||
|
{
|
||||||
|
if (propertyId > 31)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (_properties & IntUtil::maskFromIndex(propertyId)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Compiler::setProperty(uint32_t propertyId, uint32_t value)
|
||||||
|
{
|
||||||
|
if (propertyId > 31)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
_properties |= IntUtil::maskFromIndex(propertyId);
|
||||||
|
else
|
||||||
|
_properties &= ~IntUtil::maskFromIndex(propertyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Clear / Reset]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Compiler::clear()
|
||||||
|
{
|
||||||
|
_purge();
|
||||||
|
|
||||||
|
if (_error != kErrorOk)
|
||||||
|
setError(kErrorOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Compiler::reset()
|
||||||
|
{
|
||||||
|
_purge();
|
||||||
|
|
||||||
|
_zoneMemory.reset();
|
||||||
|
_linkMemory.reset();
|
||||||
|
|
||||||
|
_targets.reset();
|
||||||
|
_vars.reset();
|
||||||
|
|
||||||
|
if (_error != kErrorOk)
|
||||||
|
setError(kErrorOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Compiler::_purge()
|
||||||
|
{
|
||||||
|
_zoneMemory.clear();
|
||||||
|
_linkMemory.clear();
|
||||||
|
|
||||||
|
_emitOptions = 0;
|
||||||
|
_finished = false;
|
||||||
|
|
||||||
|
_first = NULL;
|
||||||
|
_last = NULL;
|
||||||
|
_current = NULL;
|
||||||
|
_func = NULL;
|
||||||
|
|
||||||
|
_targets.clear();
|
||||||
|
_vars.clear();
|
||||||
|
|
||||||
|
_cc = NULL;
|
||||||
|
_varNameId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Item Management]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerItem* Compiler::setCurrentItem(CompilerItem* item)
|
||||||
|
{
|
||||||
|
CompilerItem* old = _current;
|
||||||
|
_current = item;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Compiler::addItem(CompilerItem* item)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(item != NULL);
|
||||||
|
ASMJIT_ASSERT(item->_prev == NULL);
|
||||||
|
ASMJIT_ASSERT(item->_next == NULL);
|
||||||
|
|
||||||
|
if (_current == NULL)
|
||||||
|
{
|
||||||
|
if (_first == NULL)
|
||||||
|
{
|
||||||
|
_first = item;
|
||||||
|
_last = item;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->_next = _first;
|
||||||
|
_first->_prev = item;
|
||||||
|
_first = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CompilerItem* prev = _current;
|
||||||
|
CompilerItem* next = _current->_next;
|
||||||
|
|
||||||
|
item->_prev = prev;
|
||||||
|
item->_next = next;
|
||||||
|
|
||||||
|
prev->_next = item;
|
||||||
|
if (next)
|
||||||
|
next->_prev = item;
|
||||||
|
else
|
||||||
|
_last = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
_current = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Compiler::addItemAfter(CompilerItem* item, CompilerItem* ref)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(item != NULL);
|
||||||
|
ASMJIT_ASSERT(item->_prev == NULL);
|
||||||
|
ASMJIT_ASSERT(item->_next == NULL);
|
||||||
|
ASMJIT_ASSERT(ref != NULL);
|
||||||
|
|
||||||
|
CompilerItem* prev = ref;
|
||||||
|
CompilerItem* next = ref->_next;
|
||||||
|
|
||||||
|
item->_prev = prev;
|
||||||
|
item->_next = next;
|
||||||
|
|
||||||
|
prev->_next = item;
|
||||||
|
if (next)
|
||||||
|
next->_prev = item;
|
||||||
|
else
|
||||||
|
_last = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Compiler::removeItem(CompilerItem* item)
|
||||||
|
{
|
||||||
|
CompilerItem* prev = item->_prev;
|
||||||
|
CompilerItem* next = item->_next;
|
||||||
|
|
||||||
|
if (_first == item) { _first = next; } else { prev->_next = next; }
|
||||||
|
if (_last == item) { _last = prev; } else { next->_prev = prev; }
|
||||||
|
|
||||||
|
item->_prev = NULL;
|
||||||
|
item->_next = NULL;
|
||||||
|
|
||||||
|
if (_current == item)
|
||||||
|
_current = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Comment]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Compiler::comment(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
char buf[128];
|
||||||
|
char* p = buf;
|
||||||
|
|
||||||
|
if (fmt)
|
||||||
|
{
|
||||||
|
*p++ = ';';
|
||||||
|
*p++ = ' ';
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
p += vsnprintf(p, 100, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
*p++ = '\n';
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
CompilerComment* item = Compiler_newItem<CompilerComment>(this, buf);
|
||||||
|
addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Embed]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Compiler::embed(const void* data, size_t len)
|
||||||
|
{
|
||||||
|
// Align length to 16 bytes.
|
||||||
|
size_t alignedSize = IntUtil::align<size_t>(len, sizeof(uintptr_t));
|
||||||
|
void* p = _zoneMemory.alloc(sizeof(CompilerEmbed) - sizeof(void*) + alignedSize);
|
||||||
|
|
||||||
|
if (p == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CompilerEmbed* item = new(p) CompilerEmbed(this, data, len);
|
||||||
|
addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
|
@ -0,0 +1,359 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_COMPILER_H
|
||||||
|
#define _ASMJIT_CORE_COMPILER_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/assembler.h"
|
||||||
|
#include "../core/context.h"
|
||||||
|
#include "../core/func.h"
|
||||||
|
#include "../core/operand.h"
|
||||||
|
#include "../core/podvector.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [Forward Declarations]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
struct Compiler;
|
||||||
|
struct CompilerAlign;
|
||||||
|
struct CompilerComment;
|
||||||
|
struct CompilerContext;
|
||||||
|
struct CompilerEmbed;
|
||||||
|
struct CompilerFuncCall;
|
||||||
|
struct CompilerFuncDecl;
|
||||||
|
struct CompilerFuncEnd;
|
||||||
|
struct CompilerInst;
|
||||||
|
struct CompilerItem;
|
||||||
|
struct CompilerMark;
|
||||||
|
struct CompilerState;
|
||||||
|
struct CompilerTarget;
|
||||||
|
struct CompilerVar;
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerState]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler state base.
|
||||||
|
struct CompilerState
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerVar]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler variable base.
|
||||||
|
struct CompilerVar
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get variable name.
|
||||||
|
inline const char* getName() const { return _name; }
|
||||||
|
//! @brief Get variable id.
|
||||||
|
inline uint32_t getId() const { return _id; }
|
||||||
|
|
||||||
|
//! @brief Get variable type.
|
||||||
|
inline uint32_t getType() const { return _type; }
|
||||||
|
//! @brief Get variable class.
|
||||||
|
inline uint32_t getClass() const { return _class; }
|
||||||
|
//! @brief Get variable priority.
|
||||||
|
inline uint32_t getPriority() const { return _priority; }
|
||||||
|
//! @brief Get variable size.
|
||||||
|
inline uint32_t getSize() const { return _size; }
|
||||||
|
|
||||||
|
//! @brief Get whether the variable is a function argument.
|
||||||
|
inline bool isArgument() const { return static_cast<bool>(_isRegArgument | _isMemArgument); }
|
||||||
|
//! @brief Get whether the variable is a function argument passed through register.
|
||||||
|
inline bool isRegArgument() const { return static_cast<bool>(_isRegArgument); }
|
||||||
|
//! @brief Get whether the variable is a function argument passed through memory.
|
||||||
|
inline bool isMemArgument() const { return static_cast<bool>(_isMemArgument); }
|
||||||
|
|
||||||
|
//! @brief Get variable content can be calculated by a simple instruction.
|
||||||
|
inline bool isCalculated() const { return static_cast<bool>(_isCalculated); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Variable name.
|
||||||
|
const char* _name;
|
||||||
|
//! @brief Variable id.
|
||||||
|
uint32_t _id;
|
||||||
|
|
||||||
|
//! @brief Variable type.
|
||||||
|
uint8_t _type;
|
||||||
|
//! @brief Variable class.
|
||||||
|
uint8_t _class;
|
||||||
|
//! @brief Variable priority.
|
||||||
|
uint8_t _priority;
|
||||||
|
|
||||||
|
//! @brief Whether the variable is a function argument passed through register.
|
||||||
|
uint8_t _isRegArgument : 1;
|
||||||
|
//! @brief Whether the variable is a function argument passed through memory.
|
||||||
|
uint8_t _isMemArgument : 1;
|
||||||
|
//! @brief Whether variable content can be calculated by a simple instruction.
|
||||||
|
//!
|
||||||
|
//! This is used mainly by MMX and SSE2 code. This flag indicates that
|
||||||
|
//! register allocator should never reserve memory for this variable, because
|
||||||
|
//! the content can be generated by a single instruction (for example PXOR).
|
||||||
|
uint8_t _isCalculated : 1;
|
||||||
|
//! @internal.
|
||||||
|
uint8_t _unused : 5;
|
||||||
|
|
||||||
|
//! @brief Variable size.
|
||||||
|
uint32_t _size;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler.
|
||||||
|
//!
|
||||||
|
//! @sa @ref Assembler.
|
||||||
|
struct Compiler
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref Compiler instance.
|
||||||
|
ASMJIT_API Compiler(Context* context);
|
||||||
|
//! @brief Destroy the @ref Compiler instance.
|
||||||
|
ASMJIT_API virtual ~Compiler();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Context]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get code generator.
|
||||||
|
inline Context* getContext() const
|
||||||
|
{ return _context; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Memory Management]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get zone memory manager.
|
||||||
|
inline ZoneMemory& getZoneMemory()
|
||||||
|
{ return _zoneMemory; }
|
||||||
|
|
||||||
|
//! @brief Get link memory manager.
|
||||||
|
inline ZoneMemory& getLinkMemory()
|
||||||
|
{ return _linkMemory; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Logging]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get logger.
|
||||||
|
inline Logger* getLogger() const
|
||||||
|
{ return _logger; }
|
||||||
|
|
||||||
|
//! @brief Set logger to @a logger.
|
||||||
|
ASMJIT_API virtual void setLogger(Logger* logger);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Error Handling]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get error code.
|
||||||
|
inline uint32_t getError() const
|
||||||
|
{ return _error; }
|
||||||
|
|
||||||
|
//! @brief Set error code.
|
||||||
|
//!
|
||||||
|
//! This method is virtual, because higher classes can use it to catch all
|
||||||
|
//! errors.
|
||||||
|
ASMJIT_API virtual void setError(uint32_t error);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Properties]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get compiler property.
|
||||||
|
ASMJIT_API virtual uint32_t getProperty(uint32_t propertyId);
|
||||||
|
//! @brief Set compiler property.
|
||||||
|
ASMJIT_API virtual void setProperty(uint32_t propertyId, uint32_t value);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Clear / Reset]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Clear everything, but not deallocate buffers.
|
||||||
|
//!
|
||||||
|
//! @note This method will destroy your code.
|
||||||
|
ASMJIT_API void clear();
|
||||||
|
|
||||||
|
//! @brief Free internal buffer, all emitters and NULL all pointers.
|
||||||
|
//!
|
||||||
|
//! @note This method will destroy your code.
|
||||||
|
ASMJIT_API void reset();
|
||||||
|
|
||||||
|
//! @brief Called by clear() and reset() to clear all data related to derived
|
||||||
|
//! class implementation.
|
||||||
|
ASMJIT_API virtual void _purge();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Item Management]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get first item.
|
||||||
|
inline CompilerItem* getFirstItem() const
|
||||||
|
{ return _first; }
|
||||||
|
|
||||||
|
//! @brief Get last item.
|
||||||
|
inline CompilerItem* getLastItem() const
|
||||||
|
{ return _last; }
|
||||||
|
|
||||||
|
//! @brief Get current item.
|
||||||
|
//!
|
||||||
|
//! @note If this method returns @c NULL it means that nothing has been
|
||||||
|
//! emitted yet.
|
||||||
|
inline CompilerItem* getCurrentItem() const
|
||||||
|
{ return _current; }
|
||||||
|
|
||||||
|
//! @brief Get current function.
|
||||||
|
inline CompilerFuncDecl* getFunc() const
|
||||||
|
{ return _func; }
|
||||||
|
|
||||||
|
//! @brief Set current item to @a item and return the previous current one.
|
||||||
|
ASMJIT_API CompilerItem* setCurrentItem(CompilerItem* item);
|
||||||
|
|
||||||
|
//! @brief Add item after current item to @a item and set current item to
|
||||||
|
//! @a item.
|
||||||
|
ASMJIT_API void addItem(CompilerItem* item);
|
||||||
|
|
||||||
|
//! @brief Add item after @a ref.
|
||||||
|
ASMJIT_API void addItemAfter(CompilerItem* item, CompilerItem* ref);
|
||||||
|
|
||||||
|
//! @brief Remove item @a item.
|
||||||
|
ASMJIT_API void removeItem(CompilerItem* item);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Comment]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Emit a single comment line.
|
||||||
|
//!
|
||||||
|
//! @note Comment is not directly sent to logger, but instead it's stored as
|
||||||
|
//! @ref CompilerComment item emitted when @c serialize() method is called.
|
||||||
|
ASMJIT_API void comment(const char* fmt, ...);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Embed]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Embed data.
|
||||||
|
ASMJIT_API void embed(const void* data, size_t len);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief ZoneMemory allocator, used to allocate compiler items.
|
||||||
|
ZoneMemory _zoneMemory;
|
||||||
|
//! @brief ZoneMemory allocator, used to alloc small data structures like
|
||||||
|
//! linked lists.
|
||||||
|
ZoneMemory _linkMemory;
|
||||||
|
|
||||||
|
//! @brief Context.
|
||||||
|
Context* _context;
|
||||||
|
//! @brief Logger.
|
||||||
|
Logger* _logger;
|
||||||
|
|
||||||
|
//! @brief Error code.
|
||||||
|
uint32_t _error;
|
||||||
|
//! @brief Properties.
|
||||||
|
uint32_t _properties;
|
||||||
|
//! @brief Contains options for next emitted instruction, clear after each emit.
|
||||||
|
uint32_t _emitOptions;
|
||||||
|
//! @brief Whether compiler was finished the job (register allocator, etc...).
|
||||||
|
uint32_t _finished;
|
||||||
|
|
||||||
|
//! @brief First item.
|
||||||
|
CompilerItem* _first;
|
||||||
|
//! @brief Last item.
|
||||||
|
CompilerItem* _last;
|
||||||
|
//! @brief Current item.
|
||||||
|
CompilerItem* _current;
|
||||||
|
//! @brief Current function.
|
||||||
|
CompilerFuncDecl* _func;
|
||||||
|
|
||||||
|
//! @brief Targets.
|
||||||
|
PodVector<CompilerTarget*> _targets;
|
||||||
|
//! @brief Variables.
|
||||||
|
PodVector<CompilerVar*> _vars;
|
||||||
|
|
||||||
|
//! @brief Compiler context instance, only available after prepare().
|
||||||
|
CompilerContext* _cc;
|
||||||
|
|
||||||
|
//! @brief Variable name id (used to generate unique names per function).
|
||||||
|
int _varNameId;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Helpers]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
template<typename T, typename Compiler>
|
||||||
|
inline T* Compiler_newItem(Compiler* self)
|
||||||
|
{
|
||||||
|
void* addr = self->getZoneMemory().alloc(sizeof(T));
|
||||||
|
return new(addr) T(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename Compiler, typename P1>
|
||||||
|
inline T* Compiler_newItem(Compiler* self, P1 p1)
|
||||||
|
{
|
||||||
|
void* addr = self->getZoneMemory().alloc(sizeof(T));
|
||||||
|
return new(addr) T(self, p1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename Compiler, typename P1, typename P2>
|
||||||
|
inline T* Compiler_newItem(Compiler* self, P1 p1, P2 p2)
|
||||||
|
{
|
||||||
|
void* addr = self->getZoneMemory().alloc(sizeof(T));
|
||||||
|
return new(addr) T(self, p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename Compiler, typename P1, typename P2, typename P3>
|
||||||
|
inline T* Compiler_newItem(Compiler* self, P1 p1, P2 p2, P3 p3)
|
||||||
|
{
|
||||||
|
void* addr = self->getZoneMemory().alloc(sizeof(T));
|
||||||
|
return new(addr) T(self, p1, p2, p3);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename Compiler, typename P1, typename P2, typename P3, typename P4>
|
||||||
|
inline T* Compiler_newItem(Compiler* self, P1 p1, P2 p2, P3 p3, P4 p4)
|
||||||
|
{
|
||||||
|
void* addr = self->getZoneMemory().alloc(sizeof(T));
|
||||||
|
return new(addr) T(self, p1, p2, p3, p4);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename Compiler, typename P1, typename P2, typename P3, typename P4, typename P5>
|
||||||
|
inline T* Compiler_newItem(Compiler* self, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
|
||||||
|
{
|
||||||
|
void* addr = self->getZoneMemory().alloc(sizeof(T));
|
||||||
|
return new(addr) T(self, p1, p2, p3, p4, p5);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_COMPILER_H
|
|
@ -0,0 +1,42 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/compilercontext.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerContext - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerContext::CompilerContext(Compiler* compiler) :
|
||||||
|
_zoneMemory(8192 - sizeof(ZoneChunk) - 32),
|
||||||
|
_compiler(compiler),
|
||||||
|
_func(NULL),
|
||||||
|
_start(NULL),
|
||||||
|
_stop(NULL),
|
||||||
|
_extraBlock(NULL),
|
||||||
|
_state(NULL),
|
||||||
|
_active(NULL),
|
||||||
|
_currentOffset(0),
|
||||||
|
_isUnreachable(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerContext::~CompilerContext()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,90 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_COMPILERCONTEXT_H
|
||||||
|
#define _ASMJIT_CORE_COMPILERCONTEXT_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/compiler.h"
|
||||||
|
#include "../core/compilerfunc.h"
|
||||||
|
#include "../core/compileritem.h"
|
||||||
|
#include "../core/zonememory.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerContext]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
struct CompilerContext
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(CompilerContext)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API CompilerContext(Compiler* compiler);
|
||||||
|
ASMJIT_API virtual ~CompilerContext();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessor]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline Compiler* getCompiler() const
|
||||||
|
{ return _compiler; }
|
||||||
|
|
||||||
|
inline CompilerFuncDecl* getFunc() const
|
||||||
|
{ return _func; }
|
||||||
|
|
||||||
|
inline CompilerItem* getExtraBlock() const
|
||||||
|
{ return _extraBlock; }
|
||||||
|
|
||||||
|
inline void setExtraBlock(CompilerItem* item)
|
||||||
|
{ _extraBlock = item; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief ZoneMemory manager.
|
||||||
|
ZoneMemory _zoneMemory;
|
||||||
|
|
||||||
|
//! @brief Compiler.
|
||||||
|
Compiler* _compiler;
|
||||||
|
//! @brief Function.
|
||||||
|
CompilerFuncDecl* _func;
|
||||||
|
|
||||||
|
//! @brief Start of the current active scope.
|
||||||
|
CompilerItem* _start;
|
||||||
|
//! @brief End of the current active scope.
|
||||||
|
CompilerItem* _stop;
|
||||||
|
//! @brief Item that is used to insert some code after the function body.
|
||||||
|
CompilerItem* _extraBlock;
|
||||||
|
|
||||||
|
//! @brief Current state (used by register allocator).
|
||||||
|
CompilerState* _state;
|
||||||
|
//! @brief Link to circular double-linked list containing all active variables
|
||||||
|
//! of the current state.
|
||||||
|
CompilerVar* _active;
|
||||||
|
|
||||||
|
//! @brief Current offset, used in prepare() stage. Each item should increment it.
|
||||||
|
uint32_t _currentOffset;
|
||||||
|
//! @brief Whether current code is unreachable.
|
||||||
|
uint32_t _isUnreachable;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_COMPILERCONTEXT_H
|
|
@ -0,0 +1,178 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/assembler.h"
|
||||||
|
#include "../core/compiler.h"
|
||||||
|
#include "../core/compilerfunc.h"
|
||||||
|
#include "../core/compileritem.h"
|
||||||
|
#include "../core/intutil.h"
|
||||||
|
#include "../core/logger.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerFuncDecl - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerFuncDecl::CompilerFuncDecl(Compiler* compiler) :
|
||||||
|
CompilerItem(compiler, kCompilerItemFuncDecl),
|
||||||
|
_entryTarget(NULL),
|
||||||
|
_exitTarget(NULL),
|
||||||
|
_end(NULL),
|
||||||
|
_decl(NULL),
|
||||||
|
_vars(NULL),
|
||||||
|
_funcHints(0),
|
||||||
|
_funcFlags(0),
|
||||||
|
_funcCallStackSize(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerFuncDecl::~CompilerFuncDecl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerFuncDecl - Hints]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void CompilerFuncDecl::setHint(uint32_t hint, uint32_t value)
|
||||||
|
{
|
||||||
|
if (hint > 31)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
_funcHints |= IntUtil::maskFromIndex(hint);
|
||||||
|
else
|
||||||
|
_funcHints &= ~IntUtil::maskFromIndex(hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t CompilerFuncDecl::getHint(uint32_t hint) const
|
||||||
|
{
|
||||||
|
if (hint > 31)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (_funcHints & IntUtil::maskFromIndex(hint)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerFuncEnd - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerFuncEnd::CompilerFuncEnd(Compiler* compiler, CompilerFuncDecl* func) :
|
||||||
|
CompilerItem(compiler, kCompilerItemFuncEnd),
|
||||||
|
_func(func)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerFuncEnd::~CompilerFuncEnd()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerFuncEnd - Interface]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerItem* CompilerFuncEnd::translate(CompilerContext& cc)
|
||||||
|
{
|
||||||
|
_isTranslated = true;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerFuncRet - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerFuncRet::CompilerFuncRet(Compiler* compiler, CompilerFuncDecl* func, const Operand* first, const Operand* second) :
|
||||||
|
CompilerItem(compiler, kCompilerItemFuncRet),
|
||||||
|
_func(func)
|
||||||
|
{
|
||||||
|
if (first != NULL)
|
||||||
|
_ret[0] = *first;
|
||||||
|
|
||||||
|
if (second != NULL)
|
||||||
|
_ret[1] = *second;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerFuncRet::~CompilerFuncRet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerFuncRet - Misc]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
bool CompilerFuncRet::mustEmitJump() const
|
||||||
|
{
|
||||||
|
// Iterate over next items until we found an item which emits a real instruction.
|
||||||
|
CompilerItem* item = this->getNext();
|
||||||
|
|
||||||
|
while (item)
|
||||||
|
{
|
||||||
|
switch (item->getType())
|
||||||
|
{
|
||||||
|
// Interesting item.
|
||||||
|
case kCompilerItemEmbed:
|
||||||
|
case kCompilerItemInst:
|
||||||
|
case kCompilerItemFuncCall:
|
||||||
|
case kCompilerItemFuncRet:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Non-interesting item.
|
||||||
|
case kCompilerItemComment:
|
||||||
|
case kCompilerItemMark:
|
||||||
|
case kCompilerItemAlign:
|
||||||
|
case kCompilerItemHint:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kCompilerItemTarget:
|
||||||
|
if (static_cast<CompilerTarget*>(item)->getLabel().getId() == getFunc()->getExitLabel().getId())
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Invalid items - these items shouldn't be here. We are inside the
|
||||||
|
// function, after prolog.
|
||||||
|
case kCompilerItemFuncDecl:
|
||||||
|
break;
|
||||||
|
|
||||||
|
// We can't go forward from here.
|
||||||
|
case kCompilerItemFuncEnd:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
item = item->getNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerFuncCall - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerFuncCall::CompilerFuncCall(Compiler* compiler, CompilerFuncDecl* caller, const Operand* target) :
|
||||||
|
CompilerItem(compiler, kCompilerItemFuncCall),
|
||||||
|
_caller(caller),
|
||||||
|
_decl(NULL),
|
||||||
|
_args(NULL)
|
||||||
|
{
|
||||||
|
if (target != NULL)
|
||||||
|
_target = *target;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerFuncCall::~CompilerFuncCall()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
|
@ -0,0 +1,357 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_COMPILERFUNC_H
|
||||||
|
#define _ASMJIT_CORE_COMPILERFUNC_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/compiler.h"
|
||||||
|
#include "../core/compileritem.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerFuncDecl]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler function declaration item.
|
||||||
|
//!
|
||||||
|
//! Functions are base blocks for generating assembler output. Each generated
|
||||||
|
//! assembler stream needs standard entry and leave sequences thats compatible
|
||||||
|
//! with the operating system conventions (ABI).
|
||||||
|
//!
|
||||||
|
//! Function class can be used to generate function prolog) and epilog sequences
|
||||||
|
//! that are compatible with the demanded calling convention and to allocate and
|
||||||
|
//! manage variables that can be allocated/spilled during compilation time.
|
||||||
|
//!
|
||||||
|
//! @note To create a function use @c Compiler::newFunc() method, do not
|
||||||
|
//! create any form of compiler function items using new operator.
|
||||||
|
//!
|
||||||
|
//! @sa @ref CompilerState, @ref CompilerVar.
|
||||||
|
struct CompilerFuncDecl : public CompilerItem
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @c CompilerFuncDecl instance.
|
||||||
|
//!
|
||||||
|
//! @note Always use @c AsmJit::Compiler::newFunc() to create @c Function
|
||||||
|
//! instance.
|
||||||
|
ASMJIT_API CompilerFuncDecl(Compiler* compiler);
|
||||||
|
//! @brief Destroy the @c CompilerFuncDecl instance.
|
||||||
|
ASMJIT_API virtual ~CompilerFuncDecl();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get function entry label.
|
||||||
|
//!
|
||||||
|
//! Entry label can be used to call this function from another code that's
|
||||||
|
//! being generated.
|
||||||
|
inline const Label& getEntryLabel() const
|
||||||
|
{ return _entryLabel; }
|
||||||
|
|
||||||
|
//! @brief Get function exit label.
|
||||||
|
//!
|
||||||
|
//! Use exit label to jump to function epilog.
|
||||||
|
inline const Label& getExitLabel() const
|
||||||
|
{ return _exitLabel; }
|
||||||
|
|
||||||
|
//! @brief Get function entry target.
|
||||||
|
inline CompilerTarget* getEntryTarget() const
|
||||||
|
{ return _entryTarget; }
|
||||||
|
|
||||||
|
//! @brief Get function exit target.
|
||||||
|
inline CompilerTarget* getExitTarget() const
|
||||||
|
{ return _exitTarget; }
|
||||||
|
|
||||||
|
//! @brief Get function end item.
|
||||||
|
inline CompilerFuncEnd* getEnd() const
|
||||||
|
{ return _end; }
|
||||||
|
|
||||||
|
//! @brief Get function declaration.
|
||||||
|
inline FuncDecl* getDecl() const
|
||||||
|
{ return _decl; }
|
||||||
|
|
||||||
|
//! @brief Get function arguments as variables.
|
||||||
|
inline CompilerVar** getVars() const
|
||||||
|
{ return _vars; }
|
||||||
|
|
||||||
|
//! @brief Get function argument at @a index.
|
||||||
|
inline CompilerVar* getVar(uint32_t index) const
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(index < _decl->getArgumentsCount());
|
||||||
|
return _vars[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Get function hints.
|
||||||
|
inline uint32_t getFuncHints() const
|
||||||
|
{ return _funcHints; }
|
||||||
|
|
||||||
|
//! @brief Get function flags.
|
||||||
|
inline uint32_t getFuncFlags() const
|
||||||
|
{ return _funcFlags; }
|
||||||
|
|
||||||
|
//! @brief Get whether the _funcFlags has @a flag
|
||||||
|
inline bool hasFuncFlag(uint32_t flag) const
|
||||||
|
{ return (_funcFlags & flag) != 0; }
|
||||||
|
|
||||||
|
//! @brief Set function @a flag.
|
||||||
|
inline void setFuncFlag(uint32_t flag)
|
||||||
|
{ _funcFlags |= flag; }
|
||||||
|
|
||||||
|
//! @brief Clear function @a flag.
|
||||||
|
inline void clearFuncFlag(uint32_t flag)
|
||||||
|
{ _funcFlags &= ~flag; }
|
||||||
|
|
||||||
|
//! @brief Get whether the function is also a caller.
|
||||||
|
inline bool isCaller() const
|
||||||
|
{ return hasFuncFlag(kFuncFlagIsCaller); }
|
||||||
|
|
||||||
|
//! @brief Get whether the function is finished.
|
||||||
|
inline bool isFinished() const
|
||||||
|
{ return hasFuncFlag(kFuncFlagIsFinished); }
|
||||||
|
|
||||||
|
//! @brief Get whether the function is naked.
|
||||||
|
inline bool isNaked() const
|
||||||
|
{ return hasFuncFlag(kFuncFlagIsNaked); }
|
||||||
|
|
||||||
|
//! @brief Get stack size needed to call other functions.
|
||||||
|
inline int32_t getFuncCallStackSize() const
|
||||||
|
{ return _funcCallStackSize; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Hints]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Set function hint.
|
||||||
|
ASMJIT_API virtual void setHint(uint32_t hint, uint32_t value);
|
||||||
|
//! @brief Get function hint.
|
||||||
|
ASMJIT_API virtual uint32_t getHint(uint32_t hint) const;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Prototype]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
virtual void setPrototype(
|
||||||
|
uint32_t convention,
|
||||||
|
uint32_t returnType,
|
||||||
|
const uint32_t* arguments,
|
||||||
|
uint32_t argumentsCount) = 0;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Function entry label.
|
||||||
|
Label _entryLabel;
|
||||||
|
//! @brief Function exit label.
|
||||||
|
Label _exitLabel;
|
||||||
|
|
||||||
|
//! @brief Function entry target.
|
||||||
|
CompilerTarget* _entryTarget;
|
||||||
|
//! @brief Function exit target.
|
||||||
|
CompilerTarget* _exitTarget;
|
||||||
|
|
||||||
|
//! @brief Function end item.
|
||||||
|
CompilerFuncEnd* _end;
|
||||||
|
|
||||||
|
//! @brief Function declaration.
|
||||||
|
FuncDecl* _decl;
|
||||||
|
//! @brief Function arguments as compiler variables.
|
||||||
|
CompilerVar** _vars;
|
||||||
|
|
||||||
|
//! @brief Function hints;
|
||||||
|
uint32_t _funcHints;
|
||||||
|
//! @brief Function flags.
|
||||||
|
uint32_t _funcFlags;
|
||||||
|
|
||||||
|
//! @brief Stack size needed to call other functions.
|
||||||
|
int32_t _funcCallStackSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerFuncEnd]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler function end item.
|
||||||
|
//!
|
||||||
|
//! This item does nothing; it's only used by @ref Compiler to mark specific
|
||||||
|
//! location in the code. The @c CompilerFuncEnd is similar to @c CompilerMark,
|
||||||
|
//! except that it overrides @c translate() to return @c NULL.
|
||||||
|
struct CompilerFuncEnd : public CompilerItem
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(CompilerFuncEnd)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref CompilerMark instance.
|
||||||
|
ASMJIT_API CompilerFuncEnd(Compiler* compiler, CompilerFuncDecl* func);
|
||||||
|
//! @brief Destroy the @ref CompilerMark instance.
|
||||||
|
ASMJIT_API virtual ~CompilerFuncEnd();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get related function.
|
||||||
|
inline CompilerFuncDecl* getFunc() const
|
||||||
|
{ return _func; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Interface]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Related function.
|
||||||
|
CompilerFuncDecl* _func;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerFuncRet]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler return from function item.
|
||||||
|
struct CompilerFuncRet : public CompilerItem
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(CompilerFuncRet)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref CompilerFuncRet instance.
|
||||||
|
ASMJIT_API CompilerFuncRet(Compiler* compiler, CompilerFuncDecl* func,
|
||||||
|
const Operand* first, const Operand* second);
|
||||||
|
//! @brief Destroy the @ref CompilerFuncRet instance.
|
||||||
|
ASMJIT_API virtual ~CompilerFuncRet();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @Brief Get the related function.
|
||||||
|
inline CompilerFuncDecl* getFunc() const
|
||||||
|
{ return _func; }
|
||||||
|
|
||||||
|
//! @brief Get the first return operand.
|
||||||
|
inline Operand& getFirst()
|
||||||
|
{ return _ret[0]; }
|
||||||
|
|
||||||
|
//! @overload
|
||||||
|
inline const Operand& getFirst() const
|
||||||
|
{ return _ret[0]; }
|
||||||
|
|
||||||
|
//! @brief Get the second return operand.
|
||||||
|
inline Operand& getSecond()
|
||||||
|
{ return _ret[1]; }
|
||||||
|
|
||||||
|
//! @overload
|
||||||
|
inline const Operand& getSecond() const
|
||||||
|
{ return _ret[1]; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Misc]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get whether jump to epilog has to be emitted.
|
||||||
|
ASMJIT_API bool mustEmitJump() const;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Related function.
|
||||||
|
CompilerFuncDecl* _func;
|
||||||
|
//! @brief Return operand(s).
|
||||||
|
Operand _ret[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerFuncCall]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler function call item.
|
||||||
|
struct CompilerFuncCall : public CompilerItem
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(CompilerFuncCall)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref CompilerFuncCall instance.
|
||||||
|
ASMJIT_API CompilerFuncCall(Compiler* compiler, CompilerFuncDecl* caller, const Operand* target);
|
||||||
|
//! @brief Destroy the @ref CompilerFuncCall instance.
|
||||||
|
ASMJIT_API virtual ~CompilerFuncCall();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get caller.
|
||||||
|
inline CompilerFuncDecl* getCaller() const
|
||||||
|
{ return _caller; }
|
||||||
|
|
||||||
|
//! @brief Get function declaration.
|
||||||
|
inline FuncDecl* getDecl() const
|
||||||
|
{ return _decl; }
|
||||||
|
|
||||||
|
//! @brief Get target operand.
|
||||||
|
inline Operand& getTarget()
|
||||||
|
{ return _target; }
|
||||||
|
|
||||||
|
//! @overload
|
||||||
|
inline const Operand& getTarget() const
|
||||||
|
{ return _target; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Prototype]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
virtual void setPrototype(uint32_t convention, uint32_t returnType, const uint32_t* arguments, uint32_t argumentsCount) = 0;
|
||||||
|
|
||||||
|
//! @brief Set function prototype.
|
||||||
|
inline void setPrototype(uint32_t convention, const FuncPrototype& func)
|
||||||
|
{ setPrototype(convention, func.getReturnType(), func.getArguments(), func.getArgumentsCount()); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Caller (the function which does the call).
|
||||||
|
CompilerFuncDecl* _caller;
|
||||||
|
//! @brief Function declaration.
|
||||||
|
FuncDecl* _decl;
|
||||||
|
|
||||||
|
//! @brief Operand (address of function, register, label, ...).
|
||||||
|
Operand _target;
|
||||||
|
//! @brief Return operands.
|
||||||
|
Operand _ret[2];
|
||||||
|
//! @brief Arguments operands.
|
||||||
|
Operand* _args;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_COMPILERFUNC_H
|
|
@ -0,0 +1,299 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/assembler.h"
|
||||||
|
#include "../core/compiler.h"
|
||||||
|
#include "../core/compilercontext.h"
|
||||||
|
#include "../core/compilerfunc.h"
|
||||||
|
#include "../core/compileritem.h"
|
||||||
|
#include "../core/intutil.h"
|
||||||
|
#include "../core/logger.h"
|
||||||
|
|
||||||
|
// [Dependencies - C]
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerItem - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerItem::CompilerItem(Compiler* compiler, uint32_t type) :
|
||||||
|
_compiler(compiler),
|
||||||
|
_prev(NULL),
|
||||||
|
_next(NULL),
|
||||||
|
_comment(NULL),
|
||||||
|
_type(static_cast<uint8_t>(type)),
|
||||||
|
_isTranslated(false),
|
||||||
|
_isUnreachable(false),
|
||||||
|
_reserved(0),
|
||||||
|
_offset(kInvalidValue)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerItem::~CompilerItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerItem - Interface]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void CompilerItem::prepare(CompilerContext& cc)
|
||||||
|
{
|
||||||
|
_offset = cc._currentOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerItem* CompilerItem::translate(CompilerContext& cc)
|
||||||
|
{
|
||||||
|
return translated();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompilerItem::emit(Assembler& a) {}
|
||||||
|
void CompilerItem::post(Assembler& a) {}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerItem - Misc]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
int CompilerItem::getMaxSize() const
|
||||||
|
{
|
||||||
|
// Default maximum size is -1 which means that it's not known.
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CompilerItem::_tryUnuseVar(CompilerVar* v)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerItem - Comment]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void CompilerItem::setComment(const char* str)
|
||||||
|
{
|
||||||
|
_comment = _compiler->getZoneMemory().sdup(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompilerItem::formatComment(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
// The capacity should be large enough.
|
||||||
|
char buf[128];
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
// I don't know if vsnprintf can produce non-null terminated string, in case
|
||||||
|
// it can, we terminate it here.
|
||||||
|
buf[ASMJIT_ARRAY_SIZE(buf) - 1] = '\0';
|
||||||
|
|
||||||
|
setComment(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerMark - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerMark::CompilerMark(Compiler* compiler) :
|
||||||
|
CompilerItem(compiler, kCompilerItemMark)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerMark::~CompilerMark()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerMark - Misc]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
int CompilerMark::getMaxSize() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerComment - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerComment::CompilerComment(Compiler* compiler, const char* str) :
|
||||||
|
CompilerItem(compiler, kCompilerItemComment)
|
||||||
|
{
|
||||||
|
if (str != NULL)
|
||||||
|
setComment(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerComment::~CompilerComment()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerComment - Interface]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void CompilerComment::emit(Assembler& a)
|
||||||
|
{
|
||||||
|
Logger* logger = a.getLogger();
|
||||||
|
if (logger == NULL || !logger->isUsed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
logger->logString(logger->getInstructionPrefix());
|
||||||
|
logger->logString(getComment());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerComment - Misc]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
int CompilerComment::getMaxSize() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerEmbed - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerEmbed::CompilerEmbed(Compiler* compiler, const void* data, size_t length) :
|
||||||
|
CompilerItem(compiler, kCompilerItemEmbed)
|
||||||
|
{
|
||||||
|
_length = length;
|
||||||
|
memcpy(_data, data, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerEmbed::~CompilerEmbed()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerEmbed - Interface]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void CompilerEmbed::emit(Assembler& a)
|
||||||
|
{
|
||||||
|
a.embed(_data, _length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerEmbed - Misc]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
int CompilerEmbed::getMaxSize() const
|
||||||
|
{
|
||||||
|
return (int)_length;;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerAlign - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerAlign::CompilerAlign(Compiler* compiler, uint32_t size) :
|
||||||
|
CompilerItem(compiler, kCompilerItemAlign), _size(size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerAlign::~CompilerAlign()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerAlign - Misc]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
int CompilerAlign::getMaxSize() const
|
||||||
|
{
|
||||||
|
if (_size == 0)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return static_cast<int>(_size - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerHint - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerHint::CompilerHint(Compiler* compiler, CompilerVar* var, uint32_t hintId, uint32_t hintValue) :
|
||||||
|
CompilerItem(compiler, kCompilerItemHint),
|
||||||
|
_var(var),
|
||||||
|
_hintId(hintId),
|
||||||
|
_hintValue(hintValue)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(var != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerHint::~CompilerHint()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerTarget - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerTarget::CompilerTarget(Compiler* compiler, const Label& label) :
|
||||||
|
CompilerItem(compiler, kCompilerItemTarget),
|
||||||
|
_label(label),
|
||||||
|
_from(NULL),
|
||||||
|
_state(NULL),
|
||||||
|
_jumpsCount(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerTarget::~CompilerTarget()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerTarget - Misc]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
int CompilerTarget::getMaxSize() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerInst - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerInst::CompilerInst(Compiler* compiler, uint32_t code, Operand* opData, uint32_t opCount) :
|
||||||
|
CompilerItem(compiler, kCompilerItemInst),
|
||||||
|
_code(code),
|
||||||
|
_emitOptions(static_cast<uint8_t>(compiler->_emitOptions)),
|
||||||
|
_instFlags(0),
|
||||||
|
_operandsCount(static_cast<uint8_t>(opCount)),
|
||||||
|
_variablesCount(0),
|
||||||
|
_operands(opData)
|
||||||
|
{
|
||||||
|
// Each created instruction takes emit options and clears it.
|
||||||
|
compiler->_emitOptions = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerInst::~CompilerInst()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerInst - GetJumpTarget]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
CompilerTarget* CompilerInst::getJumpTarget() const
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
|
@ -0,0 +1,546 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_COMPILERITEM_H
|
||||||
|
#define _ASMJIT_CORE_COMPILERITEM_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/compiler.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerItem]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler item.
|
||||||
|
//!
|
||||||
|
//! @ref CompilerItem represents items generated by compiler by calling its
|
||||||
|
//! methods to build functions, instruction stream, bind labels, etc... Each
|
||||||
|
//! item contains its type information and virtual methods which are called at
|
||||||
|
//! various compilation steps.
|
||||||
|
struct CompilerItem
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(CompilerItem)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create new @ref CompilerItem.
|
||||||
|
//!
|
||||||
|
//! @note Always use @ref Compiler to create an item!
|
||||||
|
ASMJIT_API CompilerItem(Compiler* compiler, uint32_t type);
|
||||||
|
|
||||||
|
//! @brief Destroy @ref CompilerItem.
|
||||||
|
//!
|
||||||
|
//! @note @ref Compiler keeps links into all items so it can destroy them
|
||||||
|
//! when code generation finished or in the case that @ref Compiler was
|
||||||
|
//! destroyed early (for example if an error happened). Never destroy items
|
||||||
|
//! manually!
|
||||||
|
ASMJIT_API virtual ~CompilerItem();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get associated compiler instance.
|
||||||
|
inline Compiler* getCompiler() const
|
||||||
|
{ return _compiler; }
|
||||||
|
|
||||||
|
//! @brief Get previous item in the compiler stream.
|
||||||
|
inline CompilerItem* getPrev() const
|
||||||
|
{ return _prev; }
|
||||||
|
|
||||||
|
//! @brief Get next item in the compiler stream.
|
||||||
|
inline CompilerItem* getNext() const
|
||||||
|
{ return _next; }
|
||||||
|
|
||||||
|
//! @brief Get comment string.
|
||||||
|
inline const char* getComment() const
|
||||||
|
{ return _comment; }
|
||||||
|
|
||||||
|
//! @brief Get type of item, see @ref kCompilerItem.
|
||||||
|
inline uint32_t getType() const
|
||||||
|
{ return _type; }
|
||||||
|
|
||||||
|
//! @brief Get whether the item was translated.
|
||||||
|
inline bool isTranslated() const
|
||||||
|
{ return _isTranslated; }
|
||||||
|
|
||||||
|
//! @brief Get whether the item is unreachable.
|
||||||
|
inline bool isUnreachable() const
|
||||||
|
{ return _isUnreachable; }
|
||||||
|
|
||||||
|
//! @brief Get the item offset in the compiler stream.
|
||||||
|
//!
|
||||||
|
//! The offset is not byte offset, each item increments offset by 1 and this
|
||||||
|
//! value is then used by register allocator. The offset is set by compiler
|
||||||
|
//! by the register allocator, don't use it in your code.
|
||||||
|
inline uint32_t getOffset() const
|
||||||
|
{ return _offset; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Interface]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Step 1. Extract item variables, update statistics, ...
|
||||||
|
ASMJIT_API virtual void prepare(CompilerContext& cc);
|
||||||
|
//! @brief Step 2. Translate instruction, alloc variables, ...
|
||||||
|
ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
|
||||||
|
//! @brief Step 3. Emit to @c Assembler.
|
||||||
|
ASMJIT_API virtual void emit(Assembler& a);
|
||||||
|
//! @brief Step 4. Last post step (verify, add data, etc).
|
||||||
|
ASMJIT_API virtual void post(Assembler& a);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Misc]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get maximum size of of this when serialized into @ref Assembler
|
||||||
|
//! item in bytes.
|
||||||
|
ASMJIT_API virtual int getMaxSize() const;
|
||||||
|
|
||||||
|
//! @brief Try to unuse the variable @a.
|
||||||
|
//!
|
||||||
|
//! Returns @c true only if the variable will be unused by the instruction,
|
||||||
|
//! otherwise @c false is returned.
|
||||||
|
ASMJIT_API virtual bool _tryUnuseVar(CompilerVar* v);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Comment]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Set comment string to @a str.
|
||||||
|
ASMJIT_API void setComment(const char* str);
|
||||||
|
|
||||||
|
//! @brief Format comment string using @a fmt string and variable argument list.
|
||||||
|
ASMJIT_API void formatComment(const char* fmt, ...);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Protected]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//! @brief Mark item as translated and return next.
|
||||||
|
inline CompilerItem* translated()
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(_isTranslated == false);
|
||||||
|
|
||||||
|
_isTranslated = true;
|
||||||
|
return _next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! @brief Compiler which owns this item.
|
||||||
|
Compiler* _compiler;
|
||||||
|
//! @brief Previous item.
|
||||||
|
CompilerItem* _prev;
|
||||||
|
//! @brief Next item.
|
||||||
|
CompilerItem* _next;
|
||||||
|
//! @brief Inline comment string, initially set to NULL.
|
||||||
|
const char* _comment;
|
||||||
|
|
||||||
|
//! @brief Type of the item, see @ref kCompilerItem.
|
||||||
|
uint32_t _type : 8;
|
||||||
|
//! @brief Whether the item was translated, see @c translate().
|
||||||
|
uint32_t _isTranslated : 1;
|
||||||
|
//! @brief Whether the item is unreachable.
|
||||||
|
uint32_t _isUnreachable : 1;
|
||||||
|
//! @brief Reserved for future use.
|
||||||
|
uint32_t _reserved : 22;
|
||||||
|
|
||||||
|
//! @brief Stream offset (not byte-offset).
|
||||||
|
uint32_t _offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerMark]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler mark item.
|
||||||
|
//!
|
||||||
|
//! This item does nothing and it's only used by @ref Compiler to mark some
|
||||||
|
//! specific location in the compiler stream.
|
||||||
|
struct CompilerMark : public CompilerItem
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(CompilerMark)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref CompilerMark instance.
|
||||||
|
ASMJIT_API CompilerMark(Compiler* compiler);
|
||||||
|
//! @brief Destroy the @ref CompilerMark instance.
|
||||||
|
ASMJIT_API virtual ~CompilerMark();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Misc]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual int getMaxSize() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerComment]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler comment item.
|
||||||
|
//!
|
||||||
|
//! Comments allows to comment your assembler stream for better debugging
|
||||||
|
//! and visualization. Comments are usually ignored in release builds unless
|
||||||
|
//! the logger is present.
|
||||||
|
struct CompilerComment : public CompilerItem
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(CompilerComment)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref CompilerComment instance.
|
||||||
|
ASMJIT_API CompilerComment(Compiler* compiler, const char* comment = NULL);
|
||||||
|
//! @brief Destroy the @ref CompilerComment instance.
|
||||||
|
ASMJIT_API virtual ~CompilerComment();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Interface]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void emit(Assembler& a);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Misc]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual int getMaxSize() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerEmbed]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler embed item.
|
||||||
|
//!
|
||||||
|
//! Embed item is used to embed data into final assembler stream. The data is
|
||||||
|
//! considered to be RAW, there is no analysis.
|
||||||
|
struct CompilerEmbed : public CompilerItem
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(CompilerEmbed)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref CompilerEmbed instance.
|
||||||
|
ASMJIT_API CompilerEmbed(Compiler* compiler, const void* data, size_t length);
|
||||||
|
//! @brief Destroy the @ref CompilerEmbed instance.
|
||||||
|
ASMJIT_API virtual ~CompilerEmbed();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get pointer to embedded data.
|
||||||
|
uint8_t* getData() const
|
||||||
|
{ return const_cast<uint8_t*>(_data); }
|
||||||
|
|
||||||
|
//! @brief Get length of embedded data.
|
||||||
|
size_t getLength() const
|
||||||
|
{ return _length; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Interface]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void emit(Assembler& a);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Misc]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual int getMaxSize() const;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Data length.
|
||||||
|
size_t _length;
|
||||||
|
//! @brief Data buffer (that will be embedded to the assembler stream).
|
||||||
|
uint8_t _data[sizeof(void*)];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerAlign]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler align item.
|
||||||
|
struct CompilerAlign : public CompilerItem
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(CompilerAlign)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref CompilerAlign instance.
|
||||||
|
ASMJIT_API CompilerAlign(Compiler* compiler, uint32_t size = 0);
|
||||||
|
//! @brief Destroy the @ref CompilerAlign instance.
|
||||||
|
ASMJIT_API virtual ~CompilerAlign();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get align size in bytes.
|
||||||
|
inline uint32_t getSize() const
|
||||||
|
{ return _size; }
|
||||||
|
|
||||||
|
//! @brief Set align size in bytes to @a size.
|
||||||
|
inline void setSize(uint32_t size)
|
||||||
|
{ _size = size; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Misc]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual int getMaxSize() const;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Align size.
|
||||||
|
uint32_t _size;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerHint]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler variable hint item.
|
||||||
|
struct CompilerHint : public CompilerItem
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(CompilerHint)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref CompilerHint instance.
|
||||||
|
ASMJIT_API CompilerHint(Compiler* compiler, CompilerVar* var, uint32_t hintId, uint32_t hintValue);
|
||||||
|
//! @brief Destroy the @ref CompilerHint instance.
|
||||||
|
ASMJIT_API virtual ~CompilerHint();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get variable.
|
||||||
|
inline CompilerVar* getVar() const
|
||||||
|
{ return _var; }
|
||||||
|
|
||||||
|
//! @brief Get hint it (see @ref kVarHint).
|
||||||
|
inline uint32_t getHintId() const
|
||||||
|
{ return _hintId; }
|
||||||
|
|
||||||
|
//! @brief Set hint it (see @ref kVarHint).
|
||||||
|
inline void setHintId(uint32_t hintId)
|
||||||
|
{ _hintId = hintId; }
|
||||||
|
|
||||||
|
//! @brief Get hint value.
|
||||||
|
inline uint32_t getHintValue() const
|
||||||
|
{ return _hintValue; }
|
||||||
|
|
||||||
|
//! @brief Set hint value.
|
||||||
|
inline void setHintValue(uint32_t hintValue)
|
||||||
|
{ _hintValue = hintValue; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Variable.
|
||||||
|
CompilerVar* _var;
|
||||||
|
//! @brief Variable hint id.
|
||||||
|
uint32_t _hintId;
|
||||||
|
//! @brief Variable hint value.
|
||||||
|
uint32_t _hintValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerTarget]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler target item.
|
||||||
|
struct CompilerTarget : public CompilerItem
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(CompilerTarget)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref CompilerTarget instance.
|
||||||
|
ASMJIT_API CompilerTarget(Compiler* compiler, const Label& target);
|
||||||
|
//! @brief Destroy the @ref CompilerTarget instance.
|
||||||
|
ASMJIT_API virtual ~CompilerTarget();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Return label bound to this target.
|
||||||
|
inline const Label& getLabel() const
|
||||||
|
{ return _label; }
|
||||||
|
|
||||||
|
//! @brief Get first jmp instruction.
|
||||||
|
inline CompilerInst* getFrom() const
|
||||||
|
{ return _from; }
|
||||||
|
|
||||||
|
//! @brief Get register allocator state for this target.
|
||||||
|
inline CompilerState* getState() const
|
||||||
|
{ return _state; }
|
||||||
|
|
||||||
|
//! @brief Get number of jumps to this target.
|
||||||
|
inline uint32_t getJumpsCount() const
|
||||||
|
{ return _jumpsCount; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Misc]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual int getMaxSize() const;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Label.
|
||||||
|
Label _label;
|
||||||
|
//! @brief First jump instruction that points to this target (label).
|
||||||
|
CompilerInst* _from;
|
||||||
|
//! @brief State at this location.
|
||||||
|
CompilerState* _state;
|
||||||
|
//! @brief Count of jumps here.
|
||||||
|
uint32_t _jumpsCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerInst]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler instruction item.
|
||||||
|
struct CompilerInst : public CompilerItem
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(CompilerInst)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref CompilerInst instance.
|
||||||
|
ASMJIT_API CompilerInst(Compiler* compiler, uint32_t code, Operand* opData, uint32_t opCount);
|
||||||
|
//! @brief Destroy the @ref CompilerInst instance.
|
||||||
|
ASMJIT_API virtual ~CompilerInst();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get instruction code, see @c kInstCode.
|
||||||
|
inline uint32_t getCode() const
|
||||||
|
{ return _code; }
|
||||||
|
|
||||||
|
//! @brief Set instruction code to @a code.
|
||||||
|
//!
|
||||||
|
//! 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.
|
||||||
|
inline void setCode(uint32_t code)
|
||||||
|
{ _code = code; }
|
||||||
|
|
||||||
|
//! @brief Get emit options (compiler specific).
|
||||||
|
inline uint32_t getEmitOptions() const
|
||||||
|
{ return _emitOptions; }
|
||||||
|
|
||||||
|
//! @brief Get instruction flags (compiler specific).
|
||||||
|
inline uint32_t getInstFlags() const
|
||||||
|
{ return _instFlags; }
|
||||||
|
|
||||||
|
//! @brief Get whether the instruction has flag @a flag.
|
||||||
|
inline bool hasInstFlag(uint8_t flag) const
|
||||||
|
{ return (_instFlags & flag) != 0; }
|
||||||
|
|
||||||
|
//! @brief Set instruction @a flag.
|
||||||
|
inline void setInstFlag(uint8_t flag)
|
||||||
|
{ _instFlags |= flag; }
|
||||||
|
|
||||||
|
//! @brief Clear instruction @a flag.
|
||||||
|
inline void clearInstFlag(uint8_t flag)
|
||||||
|
{ _instFlags &= ~flag; }
|
||||||
|
|
||||||
|
//! @brief Get count of operands in operands array.
|
||||||
|
inline uint32_t getOperandsCount() const
|
||||||
|
{ return _operandsCount; }
|
||||||
|
|
||||||
|
//! @brief Get count of variables in variables array.
|
||||||
|
inline uint32_t getVariablesCount() const
|
||||||
|
{ return _variablesCount; }
|
||||||
|
|
||||||
|
//! @brief Get operands array (3 operands total).
|
||||||
|
inline Operand* getOperands() { return _operands; }
|
||||||
|
//! @brief Get operands array (3 operands total).
|
||||||
|
inline const Operand* getOperands() const { return _operands; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [GetJumpTarget]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get possible jump target.
|
||||||
|
//!
|
||||||
|
//! If this instruction is conditional or normal jump then return value is
|
||||||
|
//! the label location (@ref CompilerTarget), otherwise the return value is
|
||||||
|
//! @c NULL.
|
||||||
|
ASMJIT_API virtual CompilerTarget* getJumpTarget() const;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Instruction code, see @c kInstCode.
|
||||||
|
uint32_t _code;
|
||||||
|
|
||||||
|
//! @brief Emit options.
|
||||||
|
uint8_t _emitOptions;
|
||||||
|
//! @brief Instruction flags.
|
||||||
|
uint8_t _instFlags;
|
||||||
|
//! @brief Operands count.
|
||||||
|
uint8_t _operandsCount;
|
||||||
|
//! @brief Variables count.
|
||||||
|
uint8_t _variablesCount;
|
||||||
|
|
||||||
|
//! @brief Operands.
|
||||||
|
Operand* _operands;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_COMPILERITEM_H
|
|
@ -4,99 +4,90 @@
|
||||||
// [License]
|
// [License]
|
||||||
// Zlib - See COPYING file in this package.
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
// [Dependencies]
|
#define ASMJIT_EXPORTS
|
||||||
#include "Assembler.h"
|
|
||||||
#include "CodeGenerator.h"
|
// [Dependencies - AsmJit]
|
||||||
#include "Defs.h"
|
#include "../core/assembler.h"
|
||||||
#include "MemoryManager.h"
|
#include "../core/context.h"
|
||||||
#include "MemoryMarker.h"
|
#include "../core/defs.h"
|
||||||
|
#include "../core/memorymanager.h"
|
||||||
|
#include "../core/memorymarker.h"
|
||||||
|
|
||||||
namespace AsmJit {
|
namespace AsmJit {
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [AsmJit::CodeGenerator - Construction / Destruction]
|
// [AsmJit::Context - Construction / Destruction]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
CodeGenerator::CodeGenerator()
|
Context::Context() {}
|
||||||
{
|
Context::~Context() {}
|
||||||
}
|
|
||||||
|
|
||||||
CodeGenerator::~CodeGenerator()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [AsmJit::CodeGenerator - GetGlobal]
|
// [AsmJit::JitContext - Construction / Destruction]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
JitCodeGenerator* CodeGenerator::getGlobal()
|
JitContext::JitContext() :
|
||||||
{
|
|
||||||
static JitCodeGenerator global;
|
|
||||||
return &global;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [AsmJit::JitCodeGenerator - Construction / Destruction]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
JitCodeGenerator::JitCodeGenerator() :
|
|
||||||
_memoryManager(NULL),
|
_memoryManager(NULL),
|
||||||
_memoryMarker(NULL),
|
_memoryMarker(NULL),
|
||||||
_allocType(MEMORY_ALLOC_FREEABLE)
|
_allocType(kMemAllocFreeable)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
JitCodeGenerator::~JitCodeGenerator()
|
JitContext::~JitContext()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [AsmJit::JitCodeGenerator - Generate]
|
// [AsmJit::JitContext - Generate]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
uint32_t JitCodeGenerator::generate(void** dest, Assembler* assembler)
|
uint32_t JitContext::generate(void** dest, Assembler* assembler)
|
||||||
{
|
{
|
||||||
// Disallow empty code generation.
|
// Disallow empty code generation.
|
||||||
sysuint_t codeSize = assembler->getCodeSize();
|
size_t codeSize = assembler->getCodeSize();
|
||||||
if (codeSize == 0)
|
if (codeSize == 0)
|
||||||
{
|
{
|
||||||
*dest = NULL;
|
*dest = NULL;
|
||||||
return AsmJit::ERROR_NO_FUNCTION;
|
return kErrorNoFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch to global memory manager if not provided.
|
// Switch to global memory manager if not provided.
|
||||||
MemoryManager* memmgr = getMemoryManager();
|
MemoryManager* memmgr = getMemoryManager();
|
||||||
|
|
||||||
if (memmgr == NULL)
|
if (memmgr == NULL)
|
||||||
{
|
|
||||||
memmgr = MemoryManager::getGlobal();
|
memmgr = MemoryManager::getGlobal();
|
||||||
}
|
|
||||||
|
|
||||||
void* p = memmgr->alloc(codeSize, getAllocType());
|
void* p = memmgr->alloc(codeSize, getAllocType());
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
*dest = NULL;
|
*dest = NULL;
|
||||||
return ERROR_NO_VIRTUAL_MEMORY;
|
return kErrorNoVirtualMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relocate the code.
|
// Relocate the code.
|
||||||
sysuint_t relocatedSize = assembler->relocCode(p);
|
size_t relocatedSize = assembler->relocCode(p);
|
||||||
|
|
||||||
// Return unused memory to MemoryManager.
|
// Return unused memory to MemoryManager.
|
||||||
if (relocatedSize < codeSize)
|
if (relocatedSize < codeSize)
|
||||||
{
|
|
||||||
memmgr->shrink(p, relocatedSize);
|
memmgr->shrink(p, relocatedSize);
|
||||||
}
|
|
||||||
|
|
||||||
// Mark memory if MemoryMarker provided.
|
// Mark memory if MemoryMarker provided.
|
||||||
if (_memoryMarker)
|
if (_memoryMarker)
|
||||||
{
|
|
||||||
_memoryMarker->mark(p, relocatedSize);
|
_memoryMarker->mark(p, relocatedSize);
|
||||||
}
|
|
||||||
|
|
||||||
// Return the code.
|
// Return the code.
|
||||||
*dest = p;
|
*dest = p;
|
||||||
return ERROR_NONE;
|
return kErrorOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::JitContext - GetGlobal]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
JitContext* JitContext::getGlobal()
|
||||||
|
{
|
||||||
|
static JitContext global;
|
||||||
|
return &global;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // AsmJit namespace
|
} // AsmJit namespace
|
|
@ -5,11 +5,11 @@
|
||||||
// Zlib - See COPYING file in this package.
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#ifndef _ASMJIT_CODEGENERATOR_H
|
#ifndef _ASMJIT_CORE_CONTEXT_H
|
||||||
#define _ASMJIT_CODEGENERATOR_H
|
#define _ASMJIT_CORE_CONTEXT_H
|
||||||
|
|
||||||
// [Dependencies]
|
// [Dependencies - AsmJit]
|
||||||
#include "Build.h"
|
#include "../core/build.h"
|
||||||
|
|
||||||
namespace AsmJit {
|
namespace AsmJit {
|
||||||
|
|
||||||
|
@ -18,26 +18,27 @@ namespace AsmJit {
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
struct Assembler;
|
struct Assembler;
|
||||||
struct JitCodeGenerator;
|
|
||||||
struct MemoryManager;
|
struct MemoryManager;
|
||||||
struct MemoryMarker;
|
struct MemoryMarker;
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [AsmJit::CodeGenerator]
|
// [AsmJit::Context]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief Code generator is core class for changing behavior of code generated
|
//! @brief Class for changing behavior of code generated by @ref Assembler and
|
||||||
//! by @c Assembler or @c Compiler.
|
//! @ref Compiler.
|
||||||
struct ASMJIT_API CodeGenerator
|
struct Context
|
||||||
{
|
{
|
||||||
|
ASMJIT_NO_COPY(Context)
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Construction / Destruction]
|
// [Construction / Destruction]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
//! @brief Create a @c CodeGenerator instance.
|
//! @brief Create a @c Context instance.
|
||||||
CodeGenerator();
|
ASMJIT_API Context();
|
||||||
//! @brief Destroy the @c CodeGenerator instance.
|
//! @brief Destroy the @c Context instance.
|
||||||
virtual ~CodeGenerator();
|
ASMJIT_API virtual ~Context();
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Interface]
|
// [Interface]
|
||||||
|
@ -55,33 +56,26 @@ struct ASMJIT_API CodeGenerator
|
||||||
//! it to allocate memory for JIT code, saving code to remote process or a
|
//! it to allocate memory for JIT code, saving code to remote process or a
|
||||||
//! shared library.
|
//! shared library.
|
||||||
//!
|
//!
|
||||||
//! @retrurn Error value, see @c ERROR_CODE.
|
//! @retrurn Error value, see @c kError.
|
||||||
virtual uint32_t generate(void** dest, Assembler* assembler) = 0;
|
virtual uint32_t generate(void** dest, Assembler* assembler) = 0;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// [Statics]
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static JitCodeGenerator* getGlobal();
|
|
||||||
|
|
||||||
private:
|
|
||||||
ASMJIT_DISABLE_COPY(CodeGenerator)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [AsmJit::JitCodeGenerator]
|
// [AsmJit::JitContext]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
struct JitCodeGenerator : public CodeGenerator
|
struct JitContext : public Context
|
||||||
{
|
{
|
||||||
|
ASMJIT_NO_COPY(JitContext)
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Construction / Destruction]
|
// [Construction / Destruction]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
//! @brief Create a @c JitCodeGenerator instance.
|
//! @brief Create a @c JitContext instance.
|
||||||
JitCodeGenerator();
|
ASMJIT_API JitContext();
|
||||||
//! @brief Destroy the @c JitCodeGenerator instance.
|
//! @brief Destroy the @c JitContext instance.
|
||||||
virtual ~JitCodeGenerator();
|
ASMJIT_API virtual ~JitContext();
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Memory Manager and Alloc Type]
|
// [Memory Manager and Alloc Type]
|
||||||
|
@ -93,35 +87,49 @@ struct JitCodeGenerator : public CodeGenerator
|
||||||
// members accessed by these accessors.
|
// members accessed by these accessors.
|
||||||
|
|
||||||
//! @brief Get the @c MemoryManager instance.
|
//! @brief Get the @c MemoryManager instance.
|
||||||
inline MemoryManager* getMemoryManager() const { return _memoryManager; }
|
inline MemoryManager* getMemoryManager() const
|
||||||
|
{ return _memoryManager; }
|
||||||
|
|
||||||
//! @brief Set the @c MemoryManager instance.
|
//! @brief Set the @c MemoryManager instance.
|
||||||
inline void setMemoryManager(MemoryManager* memoryManager) { _memoryManager = memoryManager; }
|
inline void setMemoryManager(MemoryManager* memoryManager)
|
||||||
|
{ _memoryManager = memoryManager; }
|
||||||
|
|
||||||
//! @brief Get the type of allocation.
|
//! @brief Get the type of allocation.
|
||||||
inline uint32_t getAllocType() const { return _allocType; }
|
inline uint32_t getAllocType() const
|
||||||
|
{ return _allocType; }
|
||||||
|
|
||||||
//! @brief Set the type of allocation.
|
//! @brief Set the type of allocation.
|
||||||
inline void setAllocType(uint32_t allocType) { _allocType = allocType; }
|
inline void setAllocType(uint32_t allocType)
|
||||||
|
{ _allocType = allocType; }
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Memory Marker]
|
// [Memory Marker]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
//! @brief Get the @c MemoryMarker instance.
|
//! @brief Get the @c MemoryMarker instance.
|
||||||
inline MemoryMarker* getMemoryMarker() const { return _memoryMarker; }
|
inline MemoryMarker* getMemoryMarker() const
|
||||||
|
{ return _memoryMarker; }
|
||||||
|
|
||||||
//! @brief Set the @c MemoryMarker instance.
|
//! @brief Set the @c MemoryMarker instance.
|
||||||
inline void setMemoryMarker(MemoryMarker* memoryMarker) { _memoryMarker = memoryMarker; }
|
inline void setMemoryMarker(MemoryMarker* memoryMarker)
|
||||||
|
{ _memoryMarker = memoryMarker; }
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Interface]
|
// [Interface]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
virtual uint32_t generate(void** dest, Assembler* assembler);
|
ASMJIT_API virtual uint32_t generate(void** dest, Assembler* assembler);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Statics]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API static JitContext* getGlobal();
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Members]
|
// [Members]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
protected:
|
|
||||||
//! @brief Memory manager.
|
//! @brief Memory manager.
|
||||||
MemoryManager* _memoryManager;
|
MemoryManager* _memoryManager;
|
||||||
//! @brief Memory marker.
|
//! @brief Memory marker.
|
||||||
|
@ -129,12 +137,9 @@ protected:
|
||||||
|
|
||||||
//! @brief Type of allocation.
|
//! @brief Type of allocation.
|
||||||
uint32_t _allocType;
|
uint32_t _allocType;
|
||||||
|
|
||||||
private:
|
|
||||||
ASMJIT_DISABLE_COPY(JitCodeGenerator)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // AsmJit namespace
|
} // AsmJit namespace
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#endif // _ASMJIT_CODEGENERATOR_H
|
#endif // _ASMJIT_CORE_CONTEXT_H
|
|
@ -0,0 +1,88 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/cpuinfo.h"
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
||||||
|
#include "../x86/x86cpuinfo.h"
|
||||||
|
#else
|
||||||
|
// ?
|
||||||
|
#endif // ASMJIT_X86 || ASMJIT_X64
|
||||||
|
|
||||||
|
// [Dependencies - Windows]
|
||||||
|
#if defined(ASMJIT_WINDOWS)
|
||||||
|
# include <windows.h>
|
||||||
|
#endif // ASMJIT_WINDOWS
|
||||||
|
|
||||||
|
// [Dependencies - Posix]
|
||||||
|
#if defined(ASMJIT_POSIX)
|
||||||
|
# include <errno.h>
|
||||||
|
# include <sys/statvfs.h>
|
||||||
|
# include <sys/utsname.h>
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif // ASMJIT_POSIX
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CpuInfo - DetectNumberOfProcessors]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
uint32_t CpuInfo::detectNumberOfProcessors()
|
||||||
|
{
|
||||||
|
#if defined(ASMJIT_WINDOWS)
|
||||||
|
SYSTEM_INFO info;
|
||||||
|
::GetSystemInfo(&info);
|
||||||
|
return info.dwNumberOfProcessors;
|
||||||
|
#elif defined(ASMJIT_POSIX) && defined(_SC_NPROCESSORS_ONLN)
|
||||||
|
// It seems that sysconf returns the number of "logical" processors on both
|
||||||
|
// mac and linux. So we get the number of "online logical" processors.
|
||||||
|
long res = ::sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
|
if (res == -1) return 1;
|
||||||
|
|
||||||
|
return static_cast<uint32_t>(res);
|
||||||
|
#else
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CpuInfo - GetGlobal]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
||||||
|
struct InitializedCpuInfo : public X86CpuInfo
|
||||||
|
{
|
||||||
|
inline InitializedCpuInfo() :
|
||||||
|
X86CpuInfo()
|
||||||
|
{
|
||||||
|
x86CpuDetect(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
#error "AsmJit::CpuInfo - Unsupported CPU or compiler."
|
||||||
|
#endif // ASMJIT_X86 || ASMJIT_X64
|
||||||
|
|
||||||
|
const CpuInfo* CpuInfo::getGlobal()
|
||||||
|
{
|
||||||
|
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
||||||
|
static InitializedCpuInfo cpuInfo;
|
||||||
|
#else
|
||||||
|
#error "AsmJit::CpuInfo - Unsupported CPU or compiler."
|
||||||
|
#endif // ASMJIT_X86 || ASMJIT_X64
|
||||||
|
return &cpuInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,113 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_CPUINFO_H
|
||||||
|
#define _ASMJIT_CORE_CPUINFO_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/build.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Core
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CpuInfo]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Informations about host cpu.
|
||||||
|
struct CpuInfo
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline CpuInfo(uint32_t size = sizeof(CpuInfo)) :
|
||||||
|
_size(size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get CPU vendor string.
|
||||||
|
inline const char* getVendorString() const { return _vendorString; }
|
||||||
|
//! @brief Get CPU brand string.
|
||||||
|
inline const char* getBrandString() const { return _brandString; }
|
||||||
|
|
||||||
|
//! @brief Get CPU vendor ID.
|
||||||
|
inline uint32_t getVendorId() const { return _vendorId; }
|
||||||
|
//! @brief Get CPU family ID.
|
||||||
|
inline uint32_t getFamily() const { return _family; }
|
||||||
|
//! @brief Get CPU model ID.
|
||||||
|
inline uint32_t getModel() const { return _model; }
|
||||||
|
//! @brief Get CPU stepping.
|
||||||
|
inline uint32_t getStepping() const { return _stepping; }
|
||||||
|
//! @brief Get CPU count.
|
||||||
|
inline uint32_t getNumberOfProcessors() const { return _numberOfProcessors; }
|
||||||
|
//! @brief Get CPU features.
|
||||||
|
inline uint32_t getFeatures() const { return _features; }
|
||||||
|
//! @brief Get CPU bugs.
|
||||||
|
inline uint32_t getBugs() const { return _bugs; }
|
||||||
|
|
||||||
|
//! @brief Get whether CPU has feature @a feature.
|
||||||
|
inline bool hasFeature(uint32_t feature) { return (_features & feature) != 0; }
|
||||||
|
//! @brief Get whether CPU has bug @a bug.
|
||||||
|
inline bool hasBug(uint32_t bug) { return (_bugs & bug) != 0; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Statics]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Detect number of processors.
|
||||||
|
ASMJIT_API static uint32_t detectNumberOfProcessors();
|
||||||
|
|
||||||
|
//! @brief Get global instance of @ref CpuInfo.
|
||||||
|
ASMJIT_API static const CpuInfo* getGlobal();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Size of CpuInfo structure (in bytes).
|
||||||
|
uint32_t _size;
|
||||||
|
|
||||||
|
//! @brief Cpu short vendor string.
|
||||||
|
char _vendorString[16];
|
||||||
|
//! @brief Cpu long vendor string (brand).
|
||||||
|
char _brandString[64];
|
||||||
|
|
||||||
|
//! @brief Cpu vendor id (see @c AsmJit::CpuInfo::VendorId enum).
|
||||||
|
uint32_t _vendorId;
|
||||||
|
//! @brief Cpu family ID.
|
||||||
|
uint32_t _family;
|
||||||
|
//! @brief Cpu model ID.
|
||||||
|
uint32_t _model;
|
||||||
|
//! @brief Cpu stepping.
|
||||||
|
uint32_t _stepping;
|
||||||
|
//! @brief Number of processors or cores.
|
||||||
|
uint32_t _numberOfProcessors;
|
||||||
|
//! @brief Cpu features bitfield, see @c AsmJit::CpuInfo::Feature enum).
|
||||||
|
uint32_t _features;
|
||||||
|
//! @brief Cpu bugs bitfield, see @c AsmJit::CpuInfo::Bug enum).
|
||||||
|
uint32_t _bugs;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_CPUINFO_H
|
|
@ -4,15 +4,21 @@
|
||||||
// [License]
|
// [License]
|
||||||
// Zlib - See COPYING file in this package.
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
// [Dependencies]
|
#define ASMJIT_EXPORTS
|
||||||
#include "Defs.h"
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/defs.h"
|
||||||
|
|
||||||
// [Api-Begin]
|
// [Api-Begin]
|
||||||
#include "ApiBegin.h"
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
namespace AsmJit {
|
namespace AsmJit {
|
||||||
|
|
||||||
const char* getErrorString(uint32_t error) ASMJIT_NOTHROW
|
// ============================================================================
|
||||||
|
// [AsmJit::getErrorString]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
const char* getErrorString(uint32_t error)
|
||||||
{
|
{
|
||||||
static const char* errorMessage[] = {
|
static const char* errorMessage[] = {
|
||||||
"No error",
|
"No error",
|
||||||
|
@ -38,7 +44,8 @@ const char* getErrorString(uint32_t error) ASMJIT_NOTHROW
|
||||||
};
|
};
|
||||||
|
|
||||||
// Saturate error code to be able to use errorMessage[].
|
// Saturate error code to be able to use errorMessage[].
|
||||||
if (error > _ERROR_COUNT) error = _ERROR_COUNT;
|
if (error > kErrorCount)
|
||||||
|
error = kErrorCount;
|
||||||
|
|
||||||
return errorMessage[error];
|
return errorMessage[error];
|
||||||
}
|
}
|
||||||
|
@ -46,4 +53,4 @@ const char* getErrorString(uint32_t error) ASMJIT_NOTHROW
|
||||||
} // AsmJit
|
} // AsmJit
|
||||||
|
|
||||||
// [Api-End]
|
// [Api-End]
|
||||||
#include "ApiEnd.h"
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,598 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_DEFS_H
|
||||||
|
#define _ASMJIT_CORE_DEFS_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/build.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Core
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Global]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
//! @brief Invalid operand identifier.
|
||||||
|
kInvalidValue = 0xFFFFFFFFU,
|
||||||
|
//! @brief Minimum reserved bytes in @ref Buffer.
|
||||||
|
kBufferGrow = 32U
|
||||||
|
};
|
||||||
|
|
||||||
|
static const size_t kInvalidSize = (size_t)-1;
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kStringBuilderOpType]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief String builder operation.
|
||||||
|
enum kStringBuilderOpType
|
||||||
|
{
|
||||||
|
//! @brief Replace the current content by a given content.
|
||||||
|
kStringBuilderOpSet = 0,
|
||||||
|
//! @brief Append a given content to the current content.
|
||||||
|
kStringBuilderOpAppend = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kStringBuilderNumType]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
enum kStringBuilderNumFlags
|
||||||
|
{
|
||||||
|
kStringBuilderNumShowSign = (1U << 0),
|
||||||
|
kStringBuilderNumShowSpace = (1U << 1),
|
||||||
|
kStringBuilderNumAlternate = (1U << 2),
|
||||||
|
kStringBuilderNumSigned = (1U << 31)
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kLoggerOption]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
enum kLoggerFlag
|
||||||
|
{
|
||||||
|
//! @brief Whether logger is enabled or disabled.
|
||||||
|
//!
|
||||||
|
//! Default @c true.
|
||||||
|
kLoggerIsEnabled = 0x00000001,
|
||||||
|
|
||||||
|
//! @brief Whether logger is enabled and can be used.
|
||||||
|
//!
|
||||||
|
//! This value can be set by inherited classes to inform @c Logger that
|
||||||
|
//! assigned stream (or something that can log output) is invalid. If
|
||||||
|
//! @c _used is false it means that there is no logging output and AsmJit
|
||||||
|
//! shouldn't use this logger (because all messages will be lost).
|
||||||
|
//!
|
||||||
|
//! This is designed only to optimize cases that logger exists, but its
|
||||||
|
//! configured not to output messages. The API inside Logging and AsmJit
|
||||||
|
//! should only check this value when needed. The API outside AsmJit should
|
||||||
|
//! check only whether logging is @c _enabled.
|
||||||
|
//!
|
||||||
|
//! Default @c true.
|
||||||
|
kLoggerIsUsed = 0x00000002,
|
||||||
|
|
||||||
|
//! @brief Whether to output instructions also in binary form.
|
||||||
|
kLoggerOutputBinary = 0x00000010,
|
||||||
|
//! @brief Whether to output immediates as hexadecimal numbers.
|
||||||
|
kLoggerOutputHexImmediate = 0x00000020,
|
||||||
|
//! @brief Whether to output displacements as hexadecimal numbers.
|
||||||
|
kLoggerOutputHexDisplacement = 0x00000040
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kCpu]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Cpu vendor IDs.
|
||||||
|
//!
|
||||||
|
//! Cpu vendor IDs are specific for AsmJit library. Vendor ID is not directly
|
||||||
|
//! read from cpuid result, instead it's based on CPU vendor string.
|
||||||
|
enum kCpu
|
||||||
|
{
|
||||||
|
//! @brief Unknown CPU vendor.
|
||||||
|
kCpuUnknown = 0,
|
||||||
|
|
||||||
|
//! @brief Intel CPU vendor.
|
||||||
|
kCpuIntel = 1,
|
||||||
|
//! @brief AMD CPU vendor.
|
||||||
|
kCpuAmd = 2,
|
||||||
|
//! @brief National Semiconductor CPU vendor (applies also to Cyrix processors).
|
||||||
|
kCpuNSM = 3,
|
||||||
|
//! @brief Transmeta CPU vendor.
|
||||||
|
kCpuTransmeta = 4,
|
||||||
|
//! @brief VIA CPU vendor.
|
||||||
|
kCpuVia = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kMemAllocType]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Types of allocation used by @c AsmJit::MemoryManager::alloc() method.
|
||||||
|
enum kMemAllocType
|
||||||
|
{
|
||||||
|
//! @brief Allocate memory that can be freed by @c AsmJit::MemoryManager::free()
|
||||||
|
//! method.
|
||||||
|
kMemAllocFreeable = 0,
|
||||||
|
//! @brief Allocate permanent memory that will be never freed.
|
||||||
|
kMemAllocPermanent = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kOperandType]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Operand types that can be encoded in @c Op operand.
|
||||||
|
enum kOperandType
|
||||||
|
{
|
||||||
|
//! @brief Operand is none, used only internally (not initialized Operand).
|
||||||
|
//!
|
||||||
|
//! This operand is not valid.
|
||||||
|
kOperandNone = 0x00,
|
||||||
|
//! @brief Operand is label.
|
||||||
|
kOperandLabel = 0x01,
|
||||||
|
//! @brief Operand is register.
|
||||||
|
kOperandReg = 0x02,
|
||||||
|
//! @brief Operand is variable.
|
||||||
|
kOperandVar = 0x04,
|
||||||
|
//! @brief Operand is memory.
|
||||||
|
kOperandMem = 0x08,
|
||||||
|
//! @brief Operand is immediate.
|
||||||
|
kOperandImm = 0x10
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kOperandMemType]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Type of memory operand.
|
||||||
|
enum kOperandMemType
|
||||||
|
{
|
||||||
|
//! @brief Operand is combination of register(s) and displacement (native).
|
||||||
|
kOperandMemNative = 0,
|
||||||
|
//! @brief Operand is label.
|
||||||
|
kOperandMemLabel = 1,
|
||||||
|
//! @brief Operand is absolute memory location (supported mainly in 32-bit mode)
|
||||||
|
kOperandMemAbsolute = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kOperandId]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Operand ID masks used to determine the operand type.
|
||||||
|
enum kOperandId
|
||||||
|
{
|
||||||
|
//! @brief Operand id type mask (part used for operand type).
|
||||||
|
kOperandIdTypeMask = 0xC0000000,
|
||||||
|
//! @brief Label operand mark id.
|
||||||
|
kOperandIdTypeLabel = 0x40000000,
|
||||||
|
//! @brief Variable operand mark id.
|
||||||
|
kOperandIdTypeVar = 0x80000000,
|
||||||
|
|
||||||
|
//! @brief Operand id value mask (part used for IDs).
|
||||||
|
kOperandIdValueMask = 0x3FFFFFFF
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kRegType / kRegIndex]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
//! @brief Mask for register type.
|
||||||
|
kRegTypeMask = 0xFF00,
|
||||||
|
|
||||||
|
//! @brief Mask for register code (index).
|
||||||
|
kRegIndexMask = 0xFF,
|
||||||
|
//! @brief Invalid register index.
|
||||||
|
kRegIndexInvalid = 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kCondHint]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Condition hint.
|
||||||
|
enum kCondHint
|
||||||
|
{
|
||||||
|
//! @brief No hint.
|
||||||
|
kCondHintNone = 0x00,
|
||||||
|
//! @brief Condition is likely to be taken.
|
||||||
|
kCondHintLikely = 0x01,
|
||||||
|
//! @brief Condition is unlikely to be taken.
|
||||||
|
kCondHintUnlikely = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kFuncAnonymous]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
//! @brief Maximum allowed arguments per function declaration / call.
|
||||||
|
kFuncArgsMax = 32,
|
||||||
|
//! @brief Invalid stack offset in function or function parameter.
|
||||||
|
kFuncStackInvalid = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kFuncConv]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
enum kFuncConv
|
||||||
|
{
|
||||||
|
//! @brief Calling convention is invalid (can't be used).
|
||||||
|
kFuncConvNone = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kFuncHint]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Function hints.
|
||||||
|
enum kFuncHint
|
||||||
|
{
|
||||||
|
//! @brief Make naked function (without using ebp/erp in prolog / epilog).
|
||||||
|
kFuncHintNaked = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kFuncFlags]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Function flags.
|
||||||
|
enum kFuncFlags
|
||||||
|
{
|
||||||
|
//! @brief Whether another function is called from this function.
|
||||||
|
//!
|
||||||
|
//! If another function is called from this function, it's needed to prepare
|
||||||
|
//! stack for it. If this member is true then it's likely that true will be
|
||||||
|
//! also @c _isEspAdjusted one.
|
||||||
|
kFuncFlagIsCaller = (1U << 0),
|
||||||
|
|
||||||
|
//! @brief Whether the function is finished using @c Compiler::endFunc().
|
||||||
|
kFuncFlagIsFinished = (1U << 1),
|
||||||
|
|
||||||
|
//! @brief Whether the function is using naked (minimal) prolog / epilog.
|
||||||
|
kFuncFlagIsNaked = (1U << 2)
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kFuncArgsDirection]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Function arguments direction.
|
||||||
|
enum kFuncArgsDirection
|
||||||
|
{
|
||||||
|
//! @brief Arguments are passed left to right.
|
||||||
|
//!
|
||||||
|
//! This arguments direction is unusual to C programming, it's used by pascal
|
||||||
|
//! compilers and in some calling conventions by Borland compiler).
|
||||||
|
kFuncArgsLTR = 0,
|
||||||
|
//! @brief Arguments are passed right ro left
|
||||||
|
//!
|
||||||
|
//! This is default argument direction in C programming.
|
||||||
|
kFuncArgsRTL = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kInstCode]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
enum kInstCode
|
||||||
|
{
|
||||||
|
//! @brief No instruction.
|
||||||
|
kInstNone = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kVarAllocFlags]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Variable alloc mode.
|
||||||
|
enum kVarAllocFlags
|
||||||
|
{
|
||||||
|
//! @brief Allocating variable to read only.
|
||||||
|
//!
|
||||||
|
//! Read only variables are used to optimize variable spilling. If variable
|
||||||
|
//! is some time ago deallocated and it's not marked as changed (so it was
|
||||||
|
//! all the life time read only) then spill is simply NOP (no mov instruction
|
||||||
|
//! is generated to move it to it's home memory location).
|
||||||
|
kVarAllocRead = 0x01,
|
||||||
|
//! @brief Allocating variable to write only (overwrite).
|
||||||
|
//!
|
||||||
|
//! Overwriting means that if variable is in memory, there is no generated
|
||||||
|
//! instruction to move variable from memory to register, because that
|
||||||
|
//! register will be overwritten by next instruction. This is used as a
|
||||||
|
//! simple optimization to improve generated code by @c Compiler.
|
||||||
|
kVarAllocWrite = 0x02,
|
||||||
|
//! @brief Allocating variable to read / write.
|
||||||
|
//!
|
||||||
|
//! Variable allocated for read / write is marked as changed. This means that
|
||||||
|
//! if variable must be later spilled into memory, mov (or similar)
|
||||||
|
//! instruction will be generated.
|
||||||
|
kVarAllocReadWrite = 0x03,
|
||||||
|
|
||||||
|
//! @brief Variable can be allocated in register.
|
||||||
|
kVarAllocRegister = 0x04,
|
||||||
|
//! @brief Variable can be allocated only to a special register.
|
||||||
|
kVarAllocSpecial = 0x08,
|
||||||
|
|
||||||
|
//! @brief Variable can be allocated in memory.
|
||||||
|
kVarAllocMem = 0x10,
|
||||||
|
|
||||||
|
//! @brief Unuse the variable after use.
|
||||||
|
kVarAllocUnuseAfterUse = 0x20
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kVarHint]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Variable hint (used by @ref Compiler).
|
||||||
|
//!
|
||||||
|
//! @sa @ref Compiler.
|
||||||
|
enum kVarHint
|
||||||
|
{
|
||||||
|
//! @brief Alloc variable.
|
||||||
|
kVarHintAlloc = 0,
|
||||||
|
//! @brief Spill variable.
|
||||||
|
kVarHintSpill = 1,
|
||||||
|
//! @brief Save variable if modified.
|
||||||
|
kVarHintSave = 2,
|
||||||
|
//! @brief Save variable if modified and mark it as unused.
|
||||||
|
kVarHintSaveAndUnuse = 3,
|
||||||
|
//! @brief Mark variable as unused.
|
||||||
|
kVarHintUnuse = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kVarPolicy]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Variable allocation method.
|
||||||
|
//!
|
||||||
|
//! Variable allocation method is used by compiler and it means if compiler
|
||||||
|
//! should first allocate preserved registers or not. Preserved registers are
|
||||||
|
//! registers that must be saved / restored by generated function.
|
||||||
|
//!
|
||||||
|
//! This option is for people who are calling C/C++ functions from JIT code so
|
||||||
|
//! Compiler can recude generating push/pop sequences before and after call,
|
||||||
|
//! respectively.
|
||||||
|
enum kVarPolicy
|
||||||
|
{
|
||||||
|
//! @brief Allocate preserved registers first.
|
||||||
|
kVarPolicyPreservedFirst = 0,
|
||||||
|
//! @brief Allocate preserved registers last (default).
|
||||||
|
kVarPolicyPreservedLast = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kVarState]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief State of variable.
|
||||||
|
//!
|
||||||
|
//! @note State of variable is used only during make process and it's not
|
||||||
|
//! visible to the developer.
|
||||||
|
enum kVarState
|
||||||
|
{
|
||||||
|
//! @brief Variable is currently not used.
|
||||||
|
kVarStateUnused = 0,
|
||||||
|
//! @brief Variable is in register.
|
||||||
|
//!
|
||||||
|
//! Variable is currently allocated in register.
|
||||||
|
kVarStateReg = 1,
|
||||||
|
//! @brief Variable is in memory location or spilled.
|
||||||
|
//!
|
||||||
|
//! Variable was spilled from register to memory or variable is used for
|
||||||
|
//! memory only storage.
|
||||||
|
kVarStateMem = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kVarType]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
enum kVarType
|
||||||
|
{
|
||||||
|
//! @brief Invalid variable type.
|
||||||
|
kVarTypeInvalid = 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kScale]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Scale which can be used for addressing (it the target instruction
|
||||||
|
//! supports it).
|
||||||
|
//!
|
||||||
|
//! See @c Op and addressing methods like @c byte_ptr(), @c word_ptr(),
|
||||||
|
//! @c dword_ptr(), etc...
|
||||||
|
enum kScale
|
||||||
|
{
|
||||||
|
//! @brief No scale.
|
||||||
|
kScaleNone = 0,
|
||||||
|
//! @brief Scale 2 times (same as shifting to left by 1).
|
||||||
|
kScale2Times = 1,
|
||||||
|
//! @brief Scale 4 times (same as shifting to left by 2).
|
||||||
|
kScale4Times = 2,
|
||||||
|
//! @brief Scale 8 times (same as shifting to left by 3).
|
||||||
|
kScale8Times = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kSize]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Size of registers and pointers.
|
||||||
|
enum kSize
|
||||||
|
{
|
||||||
|
//! @brief 1 byte size.
|
||||||
|
kSizeByte = 1,
|
||||||
|
//! @brief 2 bytes size.
|
||||||
|
kSizeWord = 2,
|
||||||
|
//! @brief 4 bytes size.
|
||||||
|
kSizeDWord = 4,
|
||||||
|
//! @brief 8 bytes size.
|
||||||
|
kSizeQWord = 8,
|
||||||
|
//! @brief 10 bytes size.
|
||||||
|
kSizeTWord = 10,
|
||||||
|
//! @brief 16 bytes size.
|
||||||
|
kSizeDQWord = 16
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kRelocMode]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
enum kRelocMode
|
||||||
|
{
|
||||||
|
kRelocAbsToAbs = 0,
|
||||||
|
kRelocRelToAbs = 1,
|
||||||
|
kRelocAbsToRel = 2,
|
||||||
|
kRelocTrampoline = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kCompilerItem]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Type of @ref CompilerItem.
|
||||||
|
//!
|
||||||
|
//! Each @c CompilerItem contains information about its type. Compiler can
|
||||||
|
//! optimize instruction stream by analyzing items and each type is hint
|
||||||
|
//! for it. The most used/serialized items are instructions
|
||||||
|
//! (@c kCompilerItemInst).
|
||||||
|
enum kCompilerItem
|
||||||
|
{
|
||||||
|
//! @brief Invalid item (can't be used).
|
||||||
|
kCompilerItemNone = 0,
|
||||||
|
//! @brief Item is mark, see @ref CompilerMark.
|
||||||
|
kCompilerItemMark,
|
||||||
|
//! @brief Item is comment, see @ref CompilerComment.
|
||||||
|
kCompilerItemComment,
|
||||||
|
//! @brief Item is embedded data, see @ref CompilerEmbed.
|
||||||
|
kCompilerItemEmbed,
|
||||||
|
//! @brief Item is .align directive, see @ref CompilerAlign.
|
||||||
|
kCompilerItemAlign,
|
||||||
|
//! @brief Item is variable hint (alloc, spill, use, unuse), see @ref CompilerHint.
|
||||||
|
kCompilerItemHint,
|
||||||
|
//! @brief Item is instruction, see @ref CompilerInst.
|
||||||
|
kCompilerItemInst,
|
||||||
|
//! @brief Item is target, see @ref CompilerTarget.
|
||||||
|
kCompilerItemTarget,
|
||||||
|
//! @brief Item is function call, see @ref CompilerFuncCall.
|
||||||
|
kCompilerItemFuncCall,
|
||||||
|
//! @brief Item is function declaration, see @ref CompilerFuncDecl.
|
||||||
|
kCompilerItemFuncDecl,
|
||||||
|
//! @brief Item is an end of the function, see @ref CompilerFuncEnd.
|
||||||
|
kCompilerItemFuncEnd,
|
||||||
|
//! @brief Item is function return, see @ref CompilerFuncRet.
|
||||||
|
kCompilerItemFuncRet
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::kError]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Error codes.
|
||||||
|
enum kError
|
||||||
|
{
|
||||||
|
//! @brief No error (success).
|
||||||
|
//!
|
||||||
|
//! This is default state and state you want.
|
||||||
|
kErrorOk = 0,
|
||||||
|
|
||||||
|
//! @brief Memory allocation error (@c ASMJIT_MALLOC returned @c NULL).
|
||||||
|
kErrorNoHeapMemory = 1,
|
||||||
|
//! @brief Virtual memory allocation error (@c VirtualMemory returned @c NULL).
|
||||||
|
kErrorNoVirtualMemory = 2,
|
||||||
|
|
||||||
|
//! @brief Unknown instruction. This happens only if instruction code is
|
||||||
|
//! out of bounds. Shouldn't happen.
|
||||||
|
kErrorUnknownInstruction = 3,
|
||||||
|
//! @brief Illegal instruction, usually generated by AsmJit::Assembler
|
||||||
|
//! class when emitting instruction opcode. If this error is generated the
|
||||||
|
//! target buffer is not affected by this invalid instruction.
|
||||||
|
//!
|
||||||
|
//! You can also get this error code if you are under x64 (64-bit x86) and
|
||||||
|
//! you tried to decode instruction using AH, BH, CH or DH register with REX
|
||||||
|
//! prefix. These registers can't be accessed if REX prefix is used and AsmJit
|
||||||
|
//! didn't check for this situation in intrinsics (@c Compiler takes care of
|
||||||
|
//! this and rearrange registers if needed).
|
||||||
|
//!
|
||||||
|
//! Examples that will raise @c kErrorIllegalInstruction error (a is
|
||||||
|
//! @c Assembler instance):
|
||||||
|
//!
|
||||||
|
//! @code
|
||||||
|
//! a.mov(dword_ptr(eax), al); // Invalid address size.
|
||||||
|
//! a.mov(byte_ptr(r10), ah); // Undecodable instruction (AH used with r10
|
||||||
|
//! // which can be encoded only using REX prefix)
|
||||||
|
//! @endcode
|
||||||
|
//!
|
||||||
|
//! @note In debug mode you get assertion failure instead of setting error
|
||||||
|
//! code.
|
||||||
|
kErrorIllegalInstruction = 4,
|
||||||
|
//! @brief Illegal addressing used (unencodable).
|
||||||
|
kErrorIllegalAddressing = 5,
|
||||||
|
//! @brief Short jump instruction used, but displacement is out of bounds.
|
||||||
|
kErrorIllegalShortJump = 6,
|
||||||
|
|
||||||
|
//! @brief No function defined.
|
||||||
|
kErrorNoFunction = 7,
|
||||||
|
//! @brief Function generation is not finished by using @c Compiler::endFunc()
|
||||||
|
//! or something bad happened during generation related to function. This can
|
||||||
|
//! be missing compiler item, etc...
|
||||||
|
kErrorIncompleteFunction = 8,
|
||||||
|
|
||||||
|
//! @brief Compiler can't allocate registers, because all of them are used.
|
||||||
|
//!
|
||||||
|
//! @note AsmJit is able to spill registers so this error really shouldn't
|
||||||
|
//! happen unless all registers have priority 0 (which means never spill).
|
||||||
|
kErrorNoRegisters = 9,
|
||||||
|
//! @brief Compiler can't allocate one register to multiple destinations.
|
||||||
|
//!
|
||||||
|
//! This error can only happen using special instructions like cmpxchg8b and
|
||||||
|
//! others where there are more destination operands (implicit).
|
||||||
|
kErrorOverlappedRegisters = 10,
|
||||||
|
|
||||||
|
//! @brief Tried to call function using incompatible argument.
|
||||||
|
kErrorIncompatibleArgumentType = 11,
|
||||||
|
//! @brief Incompatible return value.
|
||||||
|
kErrorIncompatibleReturnType = 12,
|
||||||
|
|
||||||
|
//! @brief Count of error codes by AsmJit. Can grow in future.
|
||||||
|
kErrorCount
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::API]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Translates error code (see @c kError) into text representation.
|
||||||
|
ASMJIT_API const char* getErrorString(uint32_t error);
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_DEFS_H
|
|
@ -0,0 +1,19 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/func.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
} // AsmJit
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,505 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_FUNC_H
|
||||||
|
#define _ASMJIT_CORE_FUNC_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/assert.h"
|
||||||
|
#include "../core/defs.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [Forward Declaration]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct TypeId;
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::TypeId]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
#if defined(ASMJIT_HAS_PARTIAL_TEMPLATE_SPECIALIZATION)
|
||||||
|
|
||||||
|
#define ASMJIT_DECLARE_TYPE_CORE(_PtrId_) \
|
||||||
|
template<typename T> \
|
||||||
|
struct TypeId \
|
||||||
|
{ \
|
||||||
|
enum \
|
||||||
|
{ \
|
||||||
|
Id = static_cast<int>(::AsmJit::kVarTypeInvalid) \
|
||||||
|
}; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template<typename T> \
|
||||||
|
struct TypeId<T*> { enum { Id = _PtrId_ }; }
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Code without partial template specialization is a bit complex. We need to
|
||||||
|
// determine whether the size of the return value of this function is equal
|
||||||
|
// to sizeof(char) or sizeof(void*). Any sizeof() can be used to distinguish
|
||||||
|
// between these two, but these are commonly used in other libraries as well.
|
||||||
|
template<typename T>
|
||||||
|
char TypeId_NoPtiHelper(T*(*)());
|
||||||
|
// And specialization.
|
||||||
|
void* TypeId_NoPtiHelper(...);
|
||||||
|
|
||||||
|
#define ASMJIT_DECLARE_TYPE_CORE(_PtrId_) \
|
||||||
|
template<typename T> \
|
||||||
|
struct TypeId \
|
||||||
|
{ \
|
||||||
|
enum \
|
||||||
|
{ \
|
||||||
|
Id = (sizeof( ::AsmJit::TypeId_NoPtiHelper((T(*)())0) ) == sizeof(char) \
|
||||||
|
? static_cast<int>(_PtrId_) \
|
||||||
|
: static_cast<int>(::AsmJit::kVarTypeInvalid)) \
|
||||||
|
}; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ASMJIT_HAS_PARTIAL_TEMPLATE_SPECIALIZATION
|
||||||
|
|
||||||
|
//! @brief Declare C/C++ type-id mapped to @c AsmJit::kX86VarType.
|
||||||
|
#define ASMJIT_DECLARE_TYPE_ID(_T_, _Id_) \
|
||||||
|
template<> \
|
||||||
|
struct TypeId<_T_> { enum { Id = _Id_ }; }
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::FuncArg]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Function argument translated from @ref FuncPrototype.
|
||||||
|
struct FuncArg
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline uint32_t getVarType() const
|
||||||
|
{ return _varType; }
|
||||||
|
|
||||||
|
inline uint32_t getRegIndex() const
|
||||||
|
{ return _regIndex; }
|
||||||
|
|
||||||
|
inline bool hasRegIndex() const
|
||||||
|
{ return _regIndex != kRegIndexInvalid; }
|
||||||
|
|
||||||
|
inline int32_t getStackOffset() const
|
||||||
|
{ return static_cast<int32_t>(_stackOffset); }
|
||||||
|
|
||||||
|
inline bool hasStackOffset() const
|
||||||
|
{ return _stackOffset != kFuncStackInvalid; }
|
||||||
|
|
||||||
|
//! @brief Get whether the argument is assigned, for private use only.
|
||||||
|
inline bool isAssigned() const
|
||||||
|
{ return (_regIndex != kRegIndexInvalid) | (_stackOffset != kFuncStackInvalid); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Reset]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Reset the function argument to "unassigned state".
|
||||||
|
inline void reset()
|
||||||
|
{ _packed = 0xFFFFFFFF; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
//! @brief Variable type, see @c kVarType.
|
||||||
|
uint8_t _varType;
|
||||||
|
//! @brief Register index is argument is passed through register.
|
||||||
|
uint8_t _regIndex;
|
||||||
|
//! @brief Stack offset if argument is passed through stack.
|
||||||
|
int16_t _stackOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief All members packed into single 32-bit integer.
|
||||||
|
uint32_t _packed;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::FuncPrototype]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Function prototype.
|
||||||
|
//!
|
||||||
|
//! Function prototype contains information about function return type, count
|
||||||
|
//! of arguments and their types. Function definition is low level structure
|
||||||
|
//! which doesn't contain platform or calling convention specific information.
|
||||||
|
struct FuncPrototype
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get function return value.
|
||||||
|
inline uint32_t getReturnType() const
|
||||||
|
{ return _returnType; }
|
||||||
|
|
||||||
|
//! @brief Get count of function arguments.
|
||||||
|
inline uint32_t getArgumentsCount() const
|
||||||
|
{ return _argumentsCount; }
|
||||||
|
|
||||||
|
//! @brief Get argument at index @a id.
|
||||||
|
inline uint32_t getArgument(uint32_t id) const
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(id < _argumentsCount);
|
||||||
|
return _arguments[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Get function arguments' IDs.
|
||||||
|
inline const uint32_t* getArguments() const
|
||||||
|
{ return _arguments; }
|
||||||
|
|
||||||
|
//! @brief Set function definition - return type and arguments.
|
||||||
|
inline void _setPrototype(uint32_t returnType, const uint32_t* arguments, uint32_t argumentsCount)
|
||||||
|
{
|
||||||
|
_returnType = returnType;
|
||||||
|
_arguments = arguments;
|
||||||
|
_argumentsCount = argumentsCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
uint32_t _returnType;
|
||||||
|
uint32_t _argumentsCount;
|
||||||
|
const uint32_t* _arguments;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::FuncDecl]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Function declaration.
|
||||||
|
struct FuncDecl
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get function return value or @ref kInvalidValue if it's void.
|
||||||
|
inline uint32_t getReturnType() const
|
||||||
|
{ return _returnType; }
|
||||||
|
|
||||||
|
//! @brief Get count of function arguments.
|
||||||
|
inline uint32_t getArgumentsCount() const
|
||||||
|
{ return _argumentsCount; }
|
||||||
|
|
||||||
|
//! @brief Get function arguments array.
|
||||||
|
inline FuncArg* getArguments()
|
||||||
|
{ return _arguments; }
|
||||||
|
|
||||||
|
//! @brief Get function arguments array (const).
|
||||||
|
inline const FuncArg* getArguments() const
|
||||||
|
{ return _arguments; }
|
||||||
|
|
||||||
|
//! @brief Get function argument at index @a index.
|
||||||
|
inline FuncArg& getArgument(size_t index)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(index < static_cast<size_t>(_argumentsCount));
|
||||||
|
return _arguments[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Get function argument at index @a index.
|
||||||
|
inline const FuncArg& getArgument(size_t index) const
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(index < static_cast<size_t>(_argumentsCount));
|
||||||
|
return _arguments[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Function return type.
|
||||||
|
uint8_t _returnType;
|
||||||
|
//! @brief Count of arguments (in @c _argumentsList).
|
||||||
|
uint8_t _argumentsCount;
|
||||||
|
//! @brief Reserved for future use (alignment).
|
||||||
|
uint8_t _reserved0[2];
|
||||||
|
|
||||||
|
//! @brief Function arguments array.
|
||||||
|
FuncArg _arguments[kFuncArgsMax];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::FuncBuilderX]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Custom function builder for up to 32 function arguments.
|
||||||
|
struct FuncBuilderX : public FuncPrototype
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline FuncBuilderX()
|
||||||
|
{ _setPrototype(kVarTypeInvalid, _argumentsData, 0); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void setReturnTypeT()
|
||||||
|
{ setReturnTypeRaw(TypeId<ASMJIT_TYPE_TO_TYPE(T)>::Id); }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void setArgumentT(uint32_t id)
|
||||||
|
{ setArgumentRaw(id, TypeId<ASMJIT_TYPE_TO_TYPE(T)>::Id); }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void addArgumentT()
|
||||||
|
{ addArgumentRaw(TypeId<ASMJIT_TYPE_TO_TYPE(T)>::Id); }
|
||||||
|
|
||||||
|
inline void setReturnTypeRaw(uint32_t returnType)
|
||||||
|
{ _returnType = returnType; }
|
||||||
|
|
||||||
|
inline void setArgumentRaw(uint32_t id, uint32_t type)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(id < _argumentsCount);
|
||||||
|
_argumentsData[id] = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void addArgumentRaw(uint32_t type)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(_argumentsCount < kFuncArgsMax);
|
||||||
|
_argumentsData[_argumentsCount++] = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
uint32_t _argumentsData[kFuncArgsMax];
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Class used to build function without arguments.
|
||||||
|
template<typename RET>
|
||||||
|
struct FuncBuilder0 : public FuncPrototype
|
||||||
|
{
|
||||||
|
inline FuncBuilder0()
|
||||||
|
{
|
||||||
|
_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, NULL, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Class used to build function with 1 argument.
|
||||||
|
template<typename RET, typename P0>
|
||||||
|
struct FuncBuilder1 : public FuncPrototype
|
||||||
|
{
|
||||||
|
inline FuncBuilder1()
|
||||||
|
{
|
||||||
|
static const uint32_t arguments[] =
|
||||||
|
{
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id
|
||||||
|
};
|
||||||
|
|
||||||
|
_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Class used to build function with 2 arguments.
|
||||||
|
template<typename RET, typename P0, typename P1>
|
||||||
|
struct FuncBuilder2 : public FuncPrototype
|
||||||
|
{
|
||||||
|
inline FuncBuilder2()
|
||||||
|
{
|
||||||
|
static const uint32_t arguments[] =
|
||||||
|
{
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id
|
||||||
|
};
|
||||||
|
|
||||||
|
_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Class used to build function with 3 arguments.
|
||||||
|
template<typename RET, typename P0, typename P1, typename P2>
|
||||||
|
struct FuncBuilder3 : public FuncPrototype
|
||||||
|
{
|
||||||
|
inline FuncBuilder3()
|
||||||
|
{
|
||||||
|
static const uint32_t arguments[] =
|
||||||
|
{
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id
|
||||||
|
};
|
||||||
|
|
||||||
|
_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Class used to build function with 4 arguments.
|
||||||
|
template<typename RET, typename P0, typename P1, typename P2, typename P3>
|
||||||
|
struct FuncBuilder4 : public FuncPrototype
|
||||||
|
{
|
||||||
|
inline FuncBuilder4()
|
||||||
|
{
|
||||||
|
static const uint32_t arguments[] =
|
||||||
|
{
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id
|
||||||
|
};
|
||||||
|
|
||||||
|
_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Class used to build function with 5 arguments.
|
||||||
|
template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4>
|
||||||
|
struct FuncBuilder5 : public FuncPrototype
|
||||||
|
{
|
||||||
|
inline FuncBuilder5()
|
||||||
|
{
|
||||||
|
static const uint32_t arguments[] =
|
||||||
|
{
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P4)>::Id
|
||||||
|
};
|
||||||
|
|
||||||
|
_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Class used to build function with 6 arguments.
|
||||||
|
template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
|
||||||
|
struct FuncBuilder6 : public FuncPrototype
|
||||||
|
{
|
||||||
|
inline FuncBuilder6()
|
||||||
|
{
|
||||||
|
static const uint32_t arguments[] =
|
||||||
|
{
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P4)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P5)>::Id
|
||||||
|
};
|
||||||
|
|
||||||
|
_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Class used to build function with 7 arguments.
|
||||||
|
template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
|
||||||
|
struct FuncBuilder7 : public FuncPrototype
|
||||||
|
{
|
||||||
|
inline FuncBuilder7()
|
||||||
|
{
|
||||||
|
static const uint32_t arguments[] =
|
||||||
|
{
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P4)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P5)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P6)>::Id
|
||||||
|
};
|
||||||
|
|
||||||
|
_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Class used to build function with 8 arguments.
|
||||||
|
template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
|
||||||
|
struct FuncBuilder8 : public FuncPrototype
|
||||||
|
{
|
||||||
|
inline FuncBuilder8()
|
||||||
|
{
|
||||||
|
static const uint32_t arguments[] =
|
||||||
|
{
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P4)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P5)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P6)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P7)>::Id
|
||||||
|
};
|
||||||
|
|
||||||
|
_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Class used to build function with 9 arguments.
|
||||||
|
template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
|
||||||
|
struct FuncBuilder9 : public FuncPrototype
|
||||||
|
{
|
||||||
|
inline FuncBuilder9()
|
||||||
|
{
|
||||||
|
static const uint32_t arguments[] =
|
||||||
|
{
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P4)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P5)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P6)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P7)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P8)>::Id
|
||||||
|
};
|
||||||
|
|
||||||
|
_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Class used to build function with 10 arguments.
|
||||||
|
template<typename RET, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
|
||||||
|
struct FuncBuilder10 : public FuncPrototype
|
||||||
|
{
|
||||||
|
inline FuncBuilder10()
|
||||||
|
{
|
||||||
|
static const uint32_t arguments[] =
|
||||||
|
{
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P0)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P1)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P2)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P3)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P4)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P5)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P6)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P7)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P8)>::Id,
|
||||||
|
TypeId<ASMJIT_TYPE_TO_TYPE(P9)>::Id
|
||||||
|
};
|
||||||
|
|
||||||
|
_setPrototype(TypeId<ASMJIT_TYPE_TO_TYPE(RET)>::Id, arguments, ASMJIT_ARRAY_SIZE(arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_FUNC_H
|
|
@ -0,0 +1,262 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_INTUTIL_H
|
||||||
|
#define _ASMJIT_CORE_INTUTIL_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/assert.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Core
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::I32FPUnion]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief used to cast from float to 32-bit integer and vica versa.
|
||||||
|
union I32FPUnion
|
||||||
|
{
|
||||||
|
//! @brief 32-bit signed integer value.
|
||||||
|
int32_t i;
|
||||||
|
//! @brief 32-bit SP-FP value.
|
||||||
|
float f;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::I64FPUnion]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief used to cast from double to 64-bit integer and vica versa.
|
||||||
|
union I64FPUnion
|
||||||
|
{
|
||||||
|
//! @brief 64-bit signed integer value.
|
||||||
|
int64_t i;
|
||||||
|
//! @brief 64-bit DP-FP value.
|
||||||
|
double f;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::IntUtil]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
namespace IntUtil
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Min/Max]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// NOTE: Because some environments declare min() and max() as macros, we
|
||||||
|
// decided to use different name so we never collide.
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline T _min(const T& a, const T& b) { return a < b ? a : b; }
|
||||||
|
template<typename T>
|
||||||
|
static inline T _max(const T& a, const T& b) { return a > b ? a : b; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Limits]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline T maxValue() { return ~T(0); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [IsInt / IsUInt]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Returns @c true if a given integer @a x is signed 8-bit integer
|
||||||
|
static inline bool isInt8(intptr_t x) { return x >= -128 && x <= 127; }
|
||||||
|
//! @brief Returns @c true if a given integer @a x is unsigned 8-bit integer
|
||||||
|
static inline bool isUInt8(intptr_t x) { return x >= 0 && x <= 255; }
|
||||||
|
|
||||||
|
//! @brief Returns @c true if a given integer @a x is signed 16-bit integer
|
||||||
|
static inline bool isInt16(intptr_t x) { return x >= -32768 && x <= 32767; }
|
||||||
|
//! @brief Returns @c true if a given integer @a x is unsigned 16-bit integer
|
||||||
|
static inline bool isUInt16(intptr_t x) { return x >= 0 && x <= 65535; }
|
||||||
|
|
||||||
|
//! @brief Returns @c true if a given integer @a x is signed 16-bit integer
|
||||||
|
static inline bool isInt32(intptr_t x)
|
||||||
|
{
|
||||||
|
#if defined(ASMJIT_X86)
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return x >= ASMJIT_INT64_C(-2147483648) && x <= ASMJIT_INT64_C(2147483647);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
//! @brief Returns @c true if a given integer @a x is unsigned 16-bit integer
|
||||||
|
static inline bool isUInt32(intptr_t x)
|
||||||
|
{
|
||||||
|
#if defined(ASMJIT_X86)
|
||||||
|
return x >= 0;
|
||||||
|
#else
|
||||||
|
return x >= 0 && x <= ASMJIT_INT64_C(4294967295);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Masking]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static inline uint32_t maskFromIndex(uint32_t x)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(x < 32);
|
||||||
|
return (1U << x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t maskUpToIndex(uint32_t x)
|
||||||
|
{
|
||||||
|
if (x >= 32)
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
else
|
||||||
|
return (1U << x) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Bits]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// From http://graphics.stanford.edu/~seander/bithacks.html .
|
||||||
|
static inline uint32_t bitCount(uint32_t x)
|
||||||
|
{
|
||||||
|
x = x - ((x >> 1) & 0x55555555U);
|
||||||
|
x = (x & 0x33333333U) + ((x >> 2) & 0x33333333U);
|
||||||
|
return (((x + (x >> 4)) & 0x0F0F0F0FU) * 0x01010101U) >> 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t findFirstBit(uint32_t mask)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < sizeof(uint32_t) * 8; i++, mask >>= 1)
|
||||||
|
{
|
||||||
|
if (mask & 0x1)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// kInvalidValue.
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Alignment]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline bool isAligned(T base, T alignment)
|
||||||
|
{
|
||||||
|
return (base % alignment) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Align @a base to @a alignment.
|
||||||
|
template<typename T>
|
||||||
|
static inline T align(T base, T alignment)
|
||||||
|
{
|
||||||
|
return (base + (alignment - 1)) & ~(alignment - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Get delta required to align @a base to @a alignment.
|
||||||
|
template<typename T>
|
||||||
|
static inline T delta(T base, T alignment)
|
||||||
|
{
|
||||||
|
return align(base, alignment) - base;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Round]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline T roundUp(T base, T alignment)
|
||||||
|
{
|
||||||
|
T over = base % alignment;
|
||||||
|
return base + (over > 0 ? alignment - over : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline T roundUpToPowerOf2(T base)
|
||||||
|
{
|
||||||
|
// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
|
||||||
|
// figure 3-3, page 48, where the function is called clp2.
|
||||||
|
base -= 1;
|
||||||
|
|
||||||
|
// I'm trying to make this portable and MSVC strikes me the warning C4293:
|
||||||
|
// "Shift count negative or too big, undefined behavior"
|
||||||
|
// Fixing...
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable: 4293)
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
base = base | (base >> 1);
|
||||||
|
base = base | (base >> 2);
|
||||||
|
base = base | (base >> 4);
|
||||||
|
|
||||||
|
if (sizeof(T) >= 2) base = base | (base >> 8);
|
||||||
|
if (sizeof(T) >= 4) base = base | (base >> 16);
|
||||||
|
if (sizeof(T) >= 8) base = base | (base >> 32);
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
return base + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Cast]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Binary cast from 32-bit integer to SP-FP value (@c float).
|
||||||
|
static inline float int32AsFloat(int32_t i)
|
||||||
|
{
|
||||||
|
I32FPUnion u;
|
||||||
|
u.i = i;
|
||||||
|
return u.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Binary cast SP-FP value (@c float) to 32-bit integer.
|
||||||
|
static inline int32_t floatAsInt32(float f)
|
||||||
|
{
|
||||||
|
I32FPUnion u;
|
||||||
|
u.f = f;
|
||||||
|
return u.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Binary cast from 64-bit integer to DP-FP value (@c double).
|
||||||
|
static inline double int64AsDouble(int64_t i)
|
||||||
|
{
|
||||||
|
I64FPUnion u;
|
||||||
|
u.i = i;
|
||||||
|
return u.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Binary cast from DP-FP value (@c double) to 64-bit integer.
|
||||||
|
static inline int64_t doubleAsInt64(double f)
|
||||||
|
{
|
||||||
|
I64FPUnion u;
|
||||||
|
u.f = f;
|
||||||
|
return u.i;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_INTUTIL_H
|
|
@ -0,0 +1,136 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_LOCK_H
|
||||||
|
#define _ASMJIT_CORE_LOCK_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/build.h"
|
||||||
|
|
||||||
|
// [Dependencies - Windows]
|
||||||
|
#if defined(ASMJIT_WINDOWS)
|
||||||
|
# include <windows.h>
|
||||||
|
#endif // ASMJIT_WINDOWS
|
||||||
|
|
||||||
|
// [Dependencies - Posix]
|
||||||
|
#if defined(ASMJIT_POSIX)
|
||||||
|
# include <pthread.h>
|
||||||
|
#endif // ASMJIT_POSIX
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Core
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Lock]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Lock - used in thread-safe code for locking.
|
||||||
|
struct Lock
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(Lock)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Windows]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(ASMJIT_WINDOWS)
|
||||||
|
typedef CRITICAL_SECTION Handle;
|
||||||
|
|
||||||
|
//! @brief Create a new @ref Lock instance.
|
||||||
|
inline Lock() { InitializeCriticalSection(&_handle); }
|
||||||
|
//! @brief Destroy the @ref Lock instance.
|
||||||
|
inline ~Lock() { DeleteCriticalSection(&_handle); }
|
||||||
|
|
||||||
|
//! @brief Lock.
|
||||||
|
inline void lock() { EnterCriticalSection(&_handle); }
|
||||||
|
//! @brief Unlock.
|
||||||
|
inline void unlock() { LeaveCriticalSection(&_handle); }
|
||||||
|
|
||||||
|
#endif // ASMJIT_WINDOWS
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Posix]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(ASMJIT_POSIX)
|
||||||
|
typedef pthread_mutex_t Handle;
|
||||||
|
|
||||||
|
//! @brief Create a new @ref Lock instance.
|
||||||
|
inline Lock() { pthread_mutex_init(&_handle, NULL); }
|
||||||
|
//! @brief Destroy the @ref Lock instance.
|
||||||
|
inline ~Lock() { pthread_mutex_destroy(&_handle); }
|
||||||
|
|
||||||
|
//! @brief Lock.
|
||||||
|
inline void lock() { pthread_mutex_lock(&_handle); }
|
||||||
|
//! @brief Unlock.
|
||||||
|
inline void unlock() { pthread_mutex_unlock(&_handle); }
|
||||||
|
#endif // ASMJIT_POSIX
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get handle.
|
||||||
|
inline Handle& getHandle() { return _handle; }
|
||||||
|
//! @overload
|
||||||
|
inline const Handle& getHandle() const { return _handle; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Handle.
|
||||||
|
Handle _handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::AutoLock]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Scope auto locker.
|
||||||
|
struct AutoLock
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(AutoLock)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Locks @a target.
|
||||||
|
inline AutoLock(Lock& target) : _target(target)
|
||||||
|
{
|
||||||
|
_target.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Unlocks target.
|
||||||
|
inline ~AutoLock()
|
||||||
|
{
|
||||||
|
_target.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Pointer to target (lock).
|
||||||
|
Lock& _target;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_LOCK_H
|
|
@ -0,0 +1,196 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/logger.h"
|
||||||
|
|
||||||
|
// [Dependencies - C]
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Logger - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
Logger::Logger() :
|
||||||
|
_flags(kLoggerIsEnabled | kLoggerIsUsed)
|
||||||
|
{
|
||||||
|
memset(_instructionPrefix, 0, ASMJIT_ARRAY_SIZE(_instructionPrefix));
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::~Logger()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Logger - Logging]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Logger::logFormat(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
len = vsnprintf(buf, 1023, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
logString(buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Logger - Enabled]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Logger::setEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
if (enabled)
|
||||||
|
_flags |= kLoggerIsEnabled | kLoggerIsUsed;
|
||||||
|
else
|
||||||
|
_flags &= ~(kLoggerIsEnabled | kLoggerIsUsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Logger - LogBinary]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Logger::setLogBinary(bool value)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
_flags |= kLoggerOutputBinary;
|
||||||
|
else
|
||||||
|
_flags &= ~kLoggerOutputBinary;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Logger - HexImmediate]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Logger::setHexImmediate(bool value)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
_flags |= kLoggerOutputHexImmediate;
|
||||||
|
else
|
||||||
|
_flags &= ~kLoggerOutputHexImmediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Logger - HexDisplacement]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Logger::setHexDisplacement(bool value)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
_flags |= kLoggerOutputHexDisplacement;
|
||||||
|
else
|
||||||
|
_flags &= ~kLoggerOutputHexDisplacement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Logger - InstructionPrefix]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Logger::setInstructionPrefix(const char* prefix)
|
||||||
|
{
|
||||||
|
memset(_instructionPrefix, 0, ASMJIT_ARRAY_SIZE(_instructionPrefix));
|
||||||
|
|
||||||
|
if (!prefix)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t length = strnlen(prefix, ASMJIT_ARRAY_SIZE(_instructionPrefix) - 1);
|
||||||
|
memcpy(_instructionPrefix, prefix, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::FileLogger - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
FileLogger::FileLogger(FILE* stream)
|
||||||
|
: _stream(NULL)
|
||||||
|
{
|
||||||
|
setStream(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileLogger::~FileLogger()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::FileLogger - Accessors]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Set file stream.
|
||||||
|
void FileLogger::setStream(FILE* stream)
|
||||||
|
{
|
||||||
|
_stream = stream;
|
||||||
|
|
||||||
|
if (isEnabled() && _stream != NULL)
|
||||||
|
_flags |= kLoggerIsUsed;
|
||||||
|
else
|
||||||
|
_flags &= ~kLoggerIsUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::FileLogger - Logging]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void FileLogger::logString(const char* buf, size_t len)
|
||||||
|
{
|
||||||
|
if (!isUsed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (len == kInvalidSize)
|
||||||
|
len = strlen(buf);
|
||||||
|
|
||||||
|
fwrite(buf, 1, len, _stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::FileLogger - Enabled]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void FileLogger::setEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
if (enabled)
|
||||||
|
_flags |= kLoggerIsEnabled | (_stream != NULL ? kLoggerIsUsed : 0);
|
||||||
|
else
|
||||||
|
_flags &= ~(kLoggerIsEnabled | kLoggerIsUsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::StringLogger - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
StringLogger::StringLogger()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
StringLogger::~StringLogger()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::StringLogger - Logging]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void StringLogger::logString(const char* buf, size_t len)
|
||||||
|
{
|
||||||
|
if (!isUsed())
|
||||||
|
return;
|
||||||
|
_stringBuilder.appendString(buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,244 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_LOGGER_H
|
||||||
|
#define _ASMJIT_CORE_LOGGER_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/build.h"
|
||||||
|
#include "../core/defs.h"
|
||||||
|
#include "../core/stringbuilder.h"
|
||||||
|
|
||||||
|
// [Dependencies - C]
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Logging
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Logger]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Abstract logging class.
|
||||||
|
//!
|
||||||
|
//! This class can be inherited and reimplemented to fit into your logging
|
||||||
|
//! subsystem. When reimplementing use @c AsmJit::Logger::log() method to
|
||||||
|
//! log into your stream.
|
||||||
|
//!
|
||||||
|
//! This class also contain @c _enabled member that can be used to enable
|
||||||
|
//! or disable logging.
|
||||||
|
struct Logger
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(Logger)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create logger.
|
||||||
|
ASMJIT_API Logger();
|
||||||
|
//! @brief Destroy logger.
|
||||||
|
ASMJIT_API virtual ~Logger();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Logging]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Abstract method to log output.
|
||||||
|
//!
|
||||||
|
//! Default implementation that is in @c AsmJit::Logger is to do nothing.
|
||||||
|
//! It's virtual to fit to your logging system.
|
||||||
|
virtual void logString(const char* buf, size_t len = kInvalidSize) = 0;
|
||||||
|
|
||||||
|
//! @brief Log formatter message (like sprintf) sending output to @c logString() method.
|
||||||
|
ASMJIT_API virtual void logFormat(const char* fmt, ...);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Flags]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get logger flags (used internally by Assembler/Compiler).
|
||||||
|
inline uint32_t getFlags() const { return _flags; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Enabled]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Return @c true if logging is enabled.
|
||||||
|
inline bool isEnabled() const { return (_flags & kLoggerIsEnabled) != 0; }
|
||||||
|
|
||||||
|
//! @brief Set logging to enabled or disabled.
|
||||||
|
ASMJIT_API virtual void setEnabled(bool enabled);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Used]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get whether the logger should be used.
|
||||||
|
inline bool isUsed() const { return (_flags & kLoggerIsUsed) != 0; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [LogBinary]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get whether logging of binary output is enabled.
|
||||||
|
inline bool getLogBinary() const { return (_flags & kLoggerOutputBinary) != 0; }
|
||||||
|
//! @brief Enable or disable binary output logging.
|
||||||
|
ASMJIT_API void setLogBinary(bool value);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [HexImmediate]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline bool getHexImmediate() const { return (_flags & kLoggerOutputHexImmediate) != 0; }
|
||||||
|
ASMJIT_API void setHexImmediate(bool value);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [HexDisplacement]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline bool getHexDisplacement() const { return (_flags & kLoggerOutputHexDisplacement) != 0; }
|
||||||
|
ASMJIT_API void setHexDisplacement(bool value);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [InstructionPrefix]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get instruction prefix.
|
||||||
|
inline const char* getInstructionPrefix() const { return _instructionPrefix; }
|
||||||
|
//! @brief Set instruction prefix.
|
||||||
|
ASMJIT_API void setInstructionPrefix(const char* prefix);
|
||||||
|
//! @brief Reset instruction prefix.
|
||||||
|
inline void resetInstructionPrefix() { setInstructionPrefix(NULL); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Flags, see @ref kLoggerFlag.
|
||||||
|
uint32_t _flags;
|
||||||
|
|
||||||
|
//! @brief Instrictions and macro-instructions prefix.
|
||||||
|
char _instructionPrefix[12];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::FileLogger]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Logger that can log to standard C @c FILE* stream.
|
||||||
|
struct FileLogger : public Logger
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(FileLogger)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @c FileLogger.
|
||||||
|
//! @param stream FILE stream where logging will be sent (can be @c NULL
|
||||||
|
//! to disable logging).
|
||||||
|
ASMJIT_API FileLogger(FILE* stream = NULL);
|
||||||
|
|
||||||
|
//! @brief Destroy the @ref FileLogger.
|
||||||
|
ASMJIT_API virtual ~FileLogger();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get @c FILE* stream.
|
||||||
|
//!
|
||||||
|
//! @note Return value can be @c NULL.
|
||||||
|
inline FILE* getStream() const { return _stream; }
|
||||||
|
|
||||||
|
//! @brief Set @c FILE* stream.
|
||||||
|
//!
|
||||||
|
//! @param stream @c FILE stream where to log output (can be @c NULL to
|
||||||
|
//! disable logging).
|
||||||
|
ASMJIT_API void setStream(FILE* stream);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Logging]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void logString(const char* buf, size_t len = kInvalidSize);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Enabled]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void setEnabled(bool enabled);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief C file stream.
|
||||||
|
FILE* _stream;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::StringLogger]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief String logger.
|
||||||
|
struct StringLogger : public Logger
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(StringLogger)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create new @ref StringLogger.
|
||||||
|
ASMJIT_API StringLogger();
|
||||||
|
|
||||||
|
//! @brief Destroy the @ref StringLogger.
|
||||||
|
ASMJIT_API virtual ~StringLogger();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get <code>char*</code> pointer which represents the serialized
|
||||||
|
//! string.
|
||||||
|
//!
|
||||||
|
//! The pointer is owned by @ref StringLogger, it can't be modified or freed.
|
||||||
|
inline const char* getString() const { return _stringBuilder.getData(); }
|
||||||
|
|
||||||
|
//! @brief Clear the serialized string.
|
||||||
|
inline void clearString() { _stringBuilder.clear(); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Logging]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void logString(const char* buf, size_t len = kInvalidSize);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Output.
|
||||||
|
StringBuilder _stringBuilder;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_LOGGER_H
|
|
@ -4,18 +4,16 @@
|
||||||
// [License]
|
// [License]
|
||||||
// Zlib - See COPYING file in this package.
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
// [Dependencies]
|
#define ASMJIT_EXPORTS
|
||||||
#include "Build.h"
|
|
||||||
#include "MemoryManager.h"
|
|
||||||
#include "Platform.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
// [Dependencies - AsmJit]
|
||||||
#include <string.h>
|
#include "../core/assert.h"
|
||||||
|
#include "../core/lock.h"
|
||||||
#include <new>
|
#include "../core/memorymanager.h"
|
||||||
|
#include "../core/virtualmemory.h"
|
||||||
|
|
||||||
// [Api-Begin]
|
// [Api-Begin]
|
||||||
#include "ApiBegin.h"
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
// This file contains implementation of virtual memory management for AsmJit
|
// This file contains implementation of virtual memory management for AsmJit
|
||||||
// library. The initial concept is to keep this implementation simple but
|
// library. The initial concept is to keep this implementation simple but
|
||||||
|
@ -55,70 +53,70 @@ namespace AsmJit {
|
||||||
// [Bits Manipulation]
|
// [Bits Manipulation]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
#define BITS_PER_ENTITY (sizeof(sysuint_t) * 8)
|
#define BITS_PER_ENTITY (sizeof(size_t) * 8)
|
||||||
|
|
||||||
static void _SetBit(sysuint_t* buf, sysuint_t index) ASMJIT_NOTHROW
|
static void _SetBit(size_t* buf, size_t index)
|
||||||
{
|
{
|
||||||
sysuint_t i = index / BITS_PER_ENTITY; // sysuint_t[]
|
size_t i = index / BITS_PER_ENTITY; // size_t[]
|
||||||
sysuint_t j = index % BITS_PER_ENTITY; // sysuint_t[][] bit index
|
size_t j = index % BITS_PER_ENTITY; // size_t[][] bit index
|
||||||
|
|
||||||
buf += i;
|
buf += i;
|
||||||
*buf |= (sysuint_t)1 << j;
|
*buf |= (size_t)1 << j;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _ClearBit(sysuint_t* buf, sysuint_t index) ASMJIT_NOTHROW
|
static void _ClearBit(size_t* buf, size_t index)
|
||||||
{
|
{
|
||||||
sysuint_t i = index / BITS_PER_ENTITY; // sysuint_t[]
|
size_t i = index / BITS_PER_ENTITY; // size_t[]
|
||||||
sysuint_t j = index % BITS_PER_ENTITY; // sysuint_t[][] bit index
|
size_t j = index % BITS_PER_ENTITY; // size_t[][] bit index
|
||||||
|
|
||||||
buf += i;
|
buf += i;
|
||||||
*buf &= ~((sysuint_t)1 << j);
|
*buf &= ~((size_t)1 << j);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _SetBits(sysuint_t* buf, sysuint_t index, sysuint_t len) ASMJIT_NOTHROW
|
static void _SetBits(size_t* buf, size_t index, size_t len)
|
||||||
{
|
{
|
||||||
if (len == 0) return;
|
if (len == 0) return;
|
||||||
|
|
||||||
sysuint_t i = index / BITS_PER_ENTITY; // sysuint_t[]
|
size_t i = index / BITS_PER_ENTITY; // size_t[]
|
||||||
sysuint_t j = index % BITS_PER_ENTITY; // sysuint_t[][] bit index
|
size_t j = index % BITS_PER_ENTITY; // size_t[][] bit index
|
||||||
|
|
||||||
// How many bytes process in the first group.
|
// How many bytes process in the first group.
|
||||||
sysuint_t c = BITS_PER_ENTITY - j;
|
size_t c = BITS_PER_ENTITY - j;
|
||||||
if (c > len) c = len;
|
if (c > len) c = len;
|
||||||
|
|
||||||
// Offset.
|
// Offset.
|
||||||
buf += i;
|
buf += i;
|
||||||
|
|
||||||
*buf++ |= (((sysuint_t)-1) >> (BITS_PER_ENTITY - c)) << j;
|
*buf++ |= ((~(size_t)0) >> (BITS_PER_ENTITY - c)) << j;
|
||||||
len -= c;
|
len -= c;
|
||||||
|
|
||||||
while (len >= BITS_PER_ENTITY)
|
while (len >= BITS_PER_ENTITY)
|
||||||
{
|
{
|
||||||
*buf++ = (sysuint_t)-1;
|
*buf++ = ~(size_t)0;
|
||||||
len -= BITS_PER_ENTITY;
|
len -= BITS_PER_ENTITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
*buf |= (((sysuint_t)-1) >> (BITS_PER_ENTITY - len));
|
*buf |= ((~(size_t)0) >> (BITS_PER_ENTITY - len));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _ClearBits(sysuint_t* buf, sysuint_t index, sysuint_t len) ASMJIT_NOTHROW
|
static void _ClearBits(size_t* buf, size_t index, size_t len)
|
||||||
{
|
{
|
||||||
if (len == 0) return;
|
if (len == 0) return;
|
||||||
|
|
||||||
sysuint_t i = index / BITS_PER_ENTITY; // sysuint_t[]
|
size_t i = index / BITS_PER_ENTITY; // size_t[]
|
||||||
sysuint_t j = index % BITS_PER_ENTITY; // sysuint_t[][] bit index
|
size_t j = index % BITS_PER_ENTITY; // size_t[][] bit index
|
||||||
|
|
||||||
// How many bytes process in the first group.
|
// How many bytes process in the first group.
|
||||||
sysuint_t c = BITS_PER_ENTITY - j;
|
size_t c = BITS_PER_ENTITY - j;
|
||||||
if (c > len) c = len;
|
if (c > len) c = len;
|
||||||
|
|
||||||
// Offset.
|
// Offset.
|
||||||
buf += i;
|
buf += i;
|
||||||
|
|
||||||
*buf++ &= ~((((sysuint_t)-1) >> (BITS_PER_ENTITY - c)) << j);
|
*buf++ &= ~(((~(size_t)0) >> (BITS_PER_ENTITY - c)) << j);
|
||||||
len -= c;
|
len -= c;
|
||||||
|
|
||||||
while (len >= BITS_PER_ENTITY)
|
while (len >= BITS_PER_ENTITY)
|
||||||
|
@ -129,7 +127,7 @@ static void _ClearBits(sysuint_t* buf, sysuint_t index, sysuint_t len) ASMJIT_NO
|
||||||
|
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
*buf &= ((sysuint_t)-1) << len;
|
*buf &= (~(size_t)0) << len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +139,7 @@ static void _ClearBits(sysuint_t* buf, sysuint_t index, sysuint_t len) ASMJIT_NO
|
||||||
#define M_MOD(x, y) ((x) % (y))
|
#define M_MOD(x, y) ((x) % (y))
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct ASMJIT_HIDDEN RbNode
|
struct RbNode
|
||||||
{
|
{
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Node red-black tree tree, key is mem pointer].
|
// [Node red-black tree tree, key is mem pointer].
|
||||||
|
@ -170,36 +168,36 @@ inline bool isRed(RbNode<T>* node)
|
||||||
return node != NULL && node->red;
|
return node != NULL && node->red;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ASMJIT_HIDDEN MemNode : public RbNode<MemNode>
|
struct MemNode : public RbNode<MemNode>
|
||||||
{
|
{
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Node double-linked list]
|
// [Node double-linked list]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
MemNode* prev; // Prev node in list.
|
MemNode* prev; // Prev node in list.
|
||||||
MemNode* next; // Next node in list.
|
MemNode* next; // Next node in list.
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Chunk Data]
|
// [Chunk Data]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
sysuint_t size; // How many bytes contain this node.
|
size_t size; // How many bytes contain this node.
|
||||||
sysuint_t blocks; // How many blocks are here.
|
size_t blocks; // How many blocks are here.
|
||||||
sysuint_t density; // Minimum count of allocated bytes in this node (also alignment).
|
size_t density; // Minimum count of allocated bytes in this node (also alignment).
|
||||||
sysuint_t used; // How many bytes are used in this node.
|
size_t used; // How many bytes are used in this node.
|
||||||
sysuint_t largestBlock; // Contains largest block that can be allocated.
|
size_t largestBlock; // Contains largest block that can be allocated.
|
||||||
|
|
||||||
sysuint_t* baUsed; // Contains bits about used blocks.
|
size_t* baUsed; // Contains bits about used blocks.
|
||||||
// (0 = unused, 1 = used).
|
// (0 = unused, 1 = used).
|
||||||
sysuint_t* baCont; // Contains bits about continuous blocks.
|
size_t* baCont; // Contains bits about continuous blocks.
|
||||||
// (0 = stop, 1 = continue).
|
// (0 = stop, 1 = continue).
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Methods]
|
// [Methods]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
// Get available space.
|
// Get available space.
|
||||||
inline sysuint_t getAvailable() const ASMJIT_NOTHROW { return size - used; }
|
inline size_t getAvailable() const { return size - used; }
|
||||||
|
|
||||||
inline void fillData(MemNode* other)
|
inline void fillData(MemNode* other)
|
||||||
{
|
{
|
||||||
|
@ -220,49 +218,49 @@ struct ASMJIT_HIDDEN MemNode : public RbNode<MemNode>
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief Permanent node.
|
//! @brief Permanent node.
|
||||||
struct ASMJIT_HIDDEN PermanentNode
|
struct PermanentNode
|
||||||
{
|
{
|
||||||
uint8_t* mem; // Base pointer (virtual memory address).
|
uint8_t* mem; // Base pointer (virtual memory address).
|
||||||
sysuint_t size; // Count of bytes allocated.
|
size_t size; // Count of bytes allocated.
|
||||||
sysuint_t used; // Count of bytes used.
|
size_t used; // Count of bytes used.
|
||||||
PermanentNode* prev; // Pointer to prev chunk or NULL.
|
PermanentNode* prev; // Pointer to prev chunk or NULL.
|
||||||
|
|
||||||
// Get available space.
|
// Get available space.
|
||||||
inline sysuint_t getAvailable() const ASMJIT_NOTHROW { return size - used; }
|
inline size_t getAvailable() const { return size - used; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [AsmJit::MemoryManagerPrivate]
|
// [AsmJit::MemoryManagerPrivate]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
struct ASMJIT_HIDDEN MemoryManagerPrivate
|
struct MemoryManagerPrivate
|
||||||
{
|
{
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Construction / Destruction]
|
// [Construction / Destruction]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
#if !defined(ASMJIT_WINDOWS)
|
#if !defined(ASMJIT_WINDOWS)
|
||||||
MemoryManagerPrivate() ASMJIT_NOTHROW;
|
MemoryManagerPrivate();
|
||||||
#else
|
#else
|
||||||
MemoryManagerPrivate(HANDLE hProcess) ASMJIT_NOTHROW;
|
MemoryManagerPrivate(HANDLE hProcess);
|
||||||
#endif // ASMJIT_WINDOWS
|
#endif // ASMJIT_WINDOWS
|
||||||
~MemoryManagerPrivate() ASMJIT_NOTHROW;
|
~MemoryManagerPrivate();
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Allocation]
|
// [Allocation]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
MemNode* createNode(sysuint_t size, sysuint_t density) ASMJIT_NOTHROW;
|
MemNode* createNode(size_t size, size_t density);
|
||||||
|
|
||||||
void* allocPermanent(sysuint_t vsize) ASMJIT_NOTHROW;
|
void* allocPermanent(size_t vsize);
|
||||||
void* allocFreeable(sysuint_t vsize) ASMJIT_NOTHROW;
|
void* allocFreeable(size_t vsize);
|
||||||
|
|
||||||
bool free(void* address) ASMJIT_NOTHROW;
|
bool free(void* address);
|
||||||
bool shrink(void* address, sysuint_t used) ASMJIT_NOTHROW;
|
bool shrink(void* address, size_t used);
|
||||||
void freeAll(bool keepVirtualMemory) ASMJIT_NOTHROW;
|
void freeAll(bool keepVirtualMemory);
|
||||||
|
|
||||||
// Helpers to avoid ifdefs in the code.
|
// Helpers to avoid ifdefs in the code.
|
||||||
inline uint8_t* allocVirtualMemory(sysuint_t size, sysuint_t* vsize) ASMJIT_NOTHROW
|
inline uint8_t* allocVirtualMemory(size_t size, size_t* vsize)
|
||||||
{
|
{
|
||||||
#if !defined(ASMJIT_WINDOWS)
|
#if !defined(ASMJIT_WINDOWS)
|
||||||
return (uint8_t*)VirtualMemory::alloc(size, vsize, true);
|
return (uint8_t*)VirtualMemory::alloc(size, vsize, true);
|
||||||
|
@ -271,7 +269,7 @@ struct ASMJIT_HIDDEN MemoryManagerPrivate
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void freeVirtualMemory(void* vmem, sysuint_t vsize) ASMJIT_NOTHROW
|
inline void freeVirtualMemory(void* vmem, size_t vsize)
|
||||||
{
|
{
|
||||||
#if !defined(ASMJIT_WINDOWS)
|
#if !defined(ASMJIT_WINDOWS)
|
||||||
VirtualMemory::free(vmem, vsize);
|
VirtualMemory::free(vmem, vsize);
|
||||||
|
@ -284,11 +282,11 @@ struct ASMJIT_HIDDEN MemoryManagerPrivate
|
||||||
// [NodeList RB-Tree]
|
// [NodeList RB-Tree]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
bool checkTree() ASMJIT_NOTHROW;
|
bool checkTree();
|
||||||
|
|
||||||
void insertNode(MemNode* node) ASMJIT_NOTHROW;
|
void insertNode(MemNode* node);
|
||||||
MemNode* removeNode(MemNode* node) ASMJIT_NOTHROW;
|
MemNode* removeNode(MemNode* node);
|
||||||
MemNode* findPtr(uint8_t* mem) ASMJIT_NOTHROW;
|
MemNode* findPtr(uint8_t* mem);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Members]
|
// [Members]
|
||||||
|
@ -299,10 +297,10 @@ struct ASMJIT_HIDDEN MemoryManagerPrivate
|
||||||
#endif // ASMJIT_WINDOWS
|
#endif // ASMJIT_WINDOWS
|
||||||
Lock _lock; // Lock for thread safety.
|
Lock _lock; // Lock for thread safety.
|
||||||
|
|
||||||
sysuint_t _newChunkSize; // Default node size.
|
size_t _newChunkSize; // Default node size.
|
||||||
sysuint_t _newChunkDensity; // Default node density.
|
size_t _newChunkDensity; // Default node density.
|
||||||
sysuint_t _allocated; // How many bytes are allocated.
|
size_t _allocated; // How many bytes are allocated.
|
||||||
sysuint_t _used; // How many bytes are used.
|
size_t _used; // How many bytes are used.
|
||||||
|
|
||||||
// Memory nodes list.
|
// Memory nodes list.
|
||||||
MemNode* _first;
|
MemNode* _first;
|
||||||
|
@ -324,9 +322,9 @@ struct ASMJIT_HIDDEN MemoryManagerPrivate
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
#if !defined(ASMJIT_WINDOWS)
|
#if !defined(ASMJIT_WINDOWS)
|
||||||
MemoryManagerPrivate::MemoryManagerPrivate() ASMJIT_NOTHROW :
|
MemoryManagerPrivate::MemoryManagerPrivate() :
|
||||||
#else
|
#else
|
||||||
MemoryManagerPrivate::MemoryManagerPrivate(HANDLE hProcess) ASMJIT_NOTHROW :
|
MemoryManagerPrivate::MemoryManagerPrivate(HANDLE hProcess) :
|
||||||
_hProcess(hProcess),
|
_hProcess(hProcess),
|
||||||
#endif
|
#endif
|
||||||
_newChunkSize(65536),
|
_newChunkSize(65536),
|
||||||
|
@ -342,7 +340,7 @@ MemoryManagerPrivate::MemoryManagerPrivate(HANDLE hProcess) ASMJIT_NOTHROW :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryManagerPrivate::~MemoryManagerPrivate() ASMJIT_NOTHROW
|
MemoryManagerPrivate::~MemoryManagerPrivate()
|
||||||
{
|
{
|
||||||
// Freeable memory cleanup - Also frees the virtual memory if configured to.
|
// Freeable memory cleanup - Also frees the virtual memory if configured to.
|
||||||
freeAll(_keepVirtualMemory);
|
freeAll(_keepVirtualMemory);
|
||||||
|
@ -364,16 +362,16 @@ MemoryManagerPrivate::~MemoryManagerPrivate() ASMJIT_NOTHROW
|
||||||
// Allocates virtual memory node and MemNode structure.
|
// Allocates virtual memory node and MemNode structure.
|
||||||
//
|
//
|
||||||
// Returns MemNode* on success, otherwise NULL.
|
// Returns MemNode* on success, otherwise NULL.
|
||||||
MemNode* MemoryManagerPrivate::createNode(sysuint_t size, sysuint_t density) ASMJIT_NOTHROW
|
MemNode* MemoryManagerPrivate::createNode(size_t size, size_t density)
|
||||||
{
|
{
|
||||||
sysuint_t vsize;
|
size_t vsize;
|
||||||
uint8_t* vmem = allocVirtualMemory(size, &vsize);
|
uint8_t* vmem = allocVirtualMemory(size, &vsize);
|
||||||
|
|
||||||
// Out of memory.
|
// Out of memory.
|
||||||
if (vmem == NULL) return NULL;
|
if (vmem == NULL) return NULL;
|
||||||
|
|
||||||
sysuint_t blocks = (vsize / density);
|
size_t blocks = (vsize / density);
|
||||||
sysuint_t bsize = (((blocks + 7) >> 3) + sizeof(sysuint_t) - 1) & ~(sysuint_t)(sizeof(sysuint_t)-1);
|
size_t bsize = (((blocks + 7) >> 3) + sizeof(size_t) - 1) & ~(size_t)(sizeof(size_t) - 1);
|
||||||
|
|
||||||
MemNode* node = reinterpret_cast<MemNode*>(ASMJIT_MALLOC(sizeof(MemNode)));
|
MemNode* node = reinterpret_cast<MemNode*>(ASMJIT_MALLOC(sizeof(MemNode)));
|
||||||
uint8_t* data = reinterpret_cast<uint8_t*>(ASMJIT_MALLOC(bsize * 2));
|
uint8_t* data = reinterpret_cast<uint8_t*>(ASMJIT_MALLOC(bsize * 2));
|
||||||
|
@ -404,21 +402,22 @@ MemNode* MemoryManagerPrivate::createNode(sysuint_t size, sysuint_t density) ASM
|
||||||
node->largestBlock = vsize;
|
node->largestBlock = vsize;
|
||||||
|
|
||||||
memset(data, 0, bsize * 2);
|
memset(data, 0, bsize * 2);
|
||||||
node->baUsed = reinterpret_cast<sysuint_t*>(data);
|
node->baUsed = reinterpret_cast<size_t*>(data);
|
||||||
node->baCont = reinterpret_cast<sysuint_t*>(data + bsize);
|
node->baCont = reinterpret_cast<size_t*>(data + bsize);
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* MemoryManagerPrivate::allocPermanent(sysuint_t vsize) ASMJIT_NOTHROW
|
void* MemoryManagerPrivate::allocPermanent(size_t vsize)
|
||||||
{
|
{
|
||||||
static const sysuint_t permanentAlignment = 32;
|
static const size_t permanentAlignment = 32;
|
||||||
static const sysuint_t permanentNodeSize = 32768;
|
static const size_t permanentNodeSize = 32768;
|
||||||
|
|
||||||
sysuint_t over = vsize % permanentAlignment;
|
size_t over = vsize % permanentAlignment;
|
||||||
if (over) over = permanentAlignment - over;
|
if (over)
|
||||||
sysuint_t alignedSize = vsize + over;
|
over = permanentAlignment - over;
|
||||||
|
|
||||||
|
size_t alignedSize = vsize + over;
|
||||||
AutoLock locked(_lock);
|
AutoLock locked(_lock);
|
||||||
|
|
||||||
PermanentNode* node = _permanent;
|
PermanentNode* node = _permanent;
|
||||||
|
@ -427,9 +426,9 @@ void* MemoryManagerPrivate::allocPermanent(sysuint_t vsize) ASMJIT_NOTHROW
|
||||||
while (node && alignedSize > node->getAvailable()) node = node->prev;
|
while (node && alignedSize > node->getAvailable()) node = node->prev;
|
||||||
|
|
||||||
// Or allocate new node.
|
// Or allocate new node.
|
||||||
if (!node)
|
if (node == NULL)
|
||||||
{
|
{
|
||||||
sysuint_t nodeSize = permanentNodeSize;
|
size_t nodeSize = permanentNodeSize;
|
||||||
if (vsize > nodeSize) nodeSize = vsize;
|
if (vsize > nodeSize) nodeSize = vsize;
|
||||||
|
|
||||||
node = (PermanentNode*)ASMJIT_MALLOC(sizeof(PermanentNode));
|
node = (PermanentNode*)ASMJIT_MALLOC(sizeof(PermanentNode));
|
||||||
|
@ -460,14 +459,14 @@ void* MemoryManagerPrivate::allocPermanent(sysuint_t vsize) ASMJIT_NOTHROW
|
||||||
return (void*)result;
|
return (void*)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* MemoryManagerPrivate::allocFreeable(sysuint_t vsize) ASMJIT_NOTHROW
|
void* MemoryManagerPrivate::allocFreeable(size_t vsize)
|
||||||
{
|
{
|
||||||
sysuint_t i; // Current index.
|
size_t i; // Current index.
|
||||||
sysuint_t need; // How many we need to be freed.
|
size_t need; // How many we need to be freed.
|
||||||
sysuint_t minVSize;
|
size_t minVSize;
|
||||||
|
|
||||||
// Align to 32 bytes (our default alignment).
|
// Align to 32 bytes (our default alignment).
|
||||||
vsize = (vsize + 31) & ~(sysuint_t)31;
|
vsize = (vsize + 31) & ~(size_t)31;
|
||||||
if (vsize == 0) return NULL;
|
if (vsize == 0) return NULL;
|
||||||
|
|
||||||
AutoLock locked(_lock);
|
AutoLock locked(_lock);
|
||||||
|
@ -488,13 +487,13 @@ void* MemoryManagerPrivate::allocFreeable(sysuint_t vsize) ASMJIT_NOTHROW
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sysuint_t* up = node->baUsed; // Current ubits address.
|
size_t* up = node->baUsed; // Current ubits address.
|
||||||
sysuint_t ubits; // Current ubits[0] value.
|
size_t ubits; // Current ubits[0] value.
|
||||||
sysuint_t bit; // Current bit mask.
|
size_t bit; // Current bit mask.
|
||||||
sysuint_t blocks = node->blocks; // Count of blocks in node.
|
size_t blocks = node->blocks; // Count of blocks in node.
|
||||||
sysuint_t cont = 0; // How many bits are currently freed in find loop.
|
size_t cont = 0; // How many bits are currently freed in find loop.
|
||||||
sysuint_t maxCont = 0; // Largest continuous block (bits count).
|
size_t maxCont = 0; // Largest continuous block (bits count).
|
||||||
sysuint_t j;
|
size_t j;
|
||||||
|
|
||||||
need = M_DIV((vsize + node->density - 1), node->density);
|
need = M_DIV((vsize + node->density - 1), node->density);
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -505,7 +504,7 @@ void* MemoryManagerPrivate::allocFreeable(sysuint_t vsize) ASMJIT_NOTHROW
|
||||||
ubits = *up++;
|
ubits = *up++;
|
||||||
|
|
||||||
// Fast skip used blocks.
|
// Fast skip used blocks.
|
||||||
if (ubits == (sysuint_t)-1)
|
if (ubits == ~(size_t)0)
|
||||||
{
|
{
|
||||||
if (cont > maxCont) maxCont = cont;
|
if (cont > maxCont) maxCont = cont;
|
||||||
cont = 0;
|
cont = 0;
|
||||||
|
@ -514,7 +513,7 @@ void* MemoryManagerPrivate::allocFreeable(sysuint_t vsize) ASMJIT_NOTHROW
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sysuint_t max = BITS_PER_ENTITY;
|
size_t max = BITS_PER_ENTITY;
|
||||||
if (i + max > blocks) max = blocks - i;
|
if (i + max > blocks) max = blocks - i;
|
||||||
|
|
||||||
for (j = 0, bit = 1; j < max; bit <<= 1)
|
for (j = 0, bit = 1; j < max; bit <<= 1)
|
||||||
|
@ -522,7 +521,7 @@ void* MemoryManagerPrivate::allocFreeable(sysuint_t vsize) ASMJIT_NOTHROW
|
||||||
j++;
|
j++;
|
||||||
if ((ubits & bit) == 0)
|
if ((ubits & bit) == 0)
|
||||||
{
|
{
|
||||||
if (++cont == need) { i += j; i -= cont; goto found; }
|
if (++cont == need) { i += j; i -= cont; goto _Found; }
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,7 +542,7 @@ void* MemoryManagerPrivate::allocFreeable(sysuint_t vsize) ASMJIT_NOTHROW
|
||||||
// If we are here, we failed to find existing memory block and we must
|
// If we are here, we failed to find existing memory block and we must
|
||||||
// allocate new.
|
// allocate new.
|
||||||
{
|
{
|
||||||
sysuint_t chunkSize = _newChunkSize;
|
size_t chunkSize = _newChunkSize;
|
||||||
if (chunkSize < vsize) chunkSize = vsize;
|
if (chunkSize < vsize) chunkSize = vsize;
|
||||||
|
|
||||||
node = createNode(chunkSize, _newChunkDensity);
|
node = createNode(chunkSize, _newChunkDensity);
|
||||||
|
@ -561,14 +560,14 @@ void* MemoryManagerPrivate::allocFreeable(sysuint_t vsize) ASMJIT_NOTHROW
|
||||||
_allocated += node->size;
|
_allocated += node->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
found:
|
_Found:
|
||||||
// Update bits.
|
// Update bits.
|
||||||
_SetBits(node->baUsed, i, need);
|
_SetBits(node->baUsed, i, need);
|
||||||
_SetBits(node->baCont, i, need - 1);
|
_SetBits(node->baCont, i, need - 1);
|
||||||
|
|
||||||
// Update statistics.
|
// Update statistics.
|
||||||
{
|
{
|
||||||
sysuint_t u = need * node->density;
|
size_t u = need * node->density;
|
||||||
node->used += u;
|
node->used += u;
|
||||||
node->largestBlock = 0;
|
node->largestBlock = 0;
|
||||||
_used += u;
|
_used += u;
|
||||||
|
@ -580,7 +579,7 @@ found:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemoryManagerPrivate::free(void* address) ASMJIT_NOTHROW
|
bool MemoryManagerPrivate::free(void* address)
|
||||||
{
|
{
|
||||||
if (address == NULL) return true;
|
if (address == NULL) return true;
|
||||||
|
|
||||||
|
@ -590,17 +589,17 @@ bool MemoryManagerPrivate::free(void* address) ASMJIT_NOTHROW
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
sysuint_t offset = (sysuint_t)((uint8_t*)address - (uint8_t*)node->mem);
|
size_t offset = (size_t)((uint8_t*)address - (uint8_t*)node->mem);
|
||||||
sysuint_t bitpos = M_DIV(offset, node->density);
|
size_t bitpos = M_DIV(offset, node->density);
|
||||||
sysuint_t i = (bitpos / BITS_PER_ENTITY);
|
size_t i = (bitpos / BITS_PER_ENTITY);
|
||||||
|
|
||||||
sysuint_t* up = node->baUsed + i; // Current ubits address.
|
size_t* up = node->baUsed + i; // Current ubits address.
|
||||||
sysuint_t* cp = node->baCont + i; // Current cbits address.
|
size_t* cp = node->baCont + i; // Current cbits address.
|
||||||
sysuint_t ubits = *up; // Current ubits[0] value.
|
size_t ubits = *up; // Current ubits[0] value.
|
||||||
sysuint_t cbits = *cp; // Current cbits[0] value.
|
size_t cbits = *cp; // Current cbits[0] value.
|
||||||
sysuint_t bit = (sysuint_t)1 << (bitpos % BITS_PER_ENTITY);
|
size_t bit = (size_t)1 << (bitpos % BITS_PER_ENTITY);
|
||||||
|
|
||||||
sysuint_t cont = 0;
|
size_t cont = 0;
|
||||||
bool stop;
|
bool stop;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
|
@ -665,7 +664,7 @@ bool MemoryManagerPrivate::free(void* address) ASMJIT_NOTHROW
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemoryManagerPrivate::shrink(void* address, sysuint_t used) ASMJIT_NOTHROW
|
bool MemoryManagerPrivate::shrink(void* address, size_t used)
|
||||||
{
|
{
|
||||||
if (address == NULL) return false;
|
if (address == NULL) return false;
|
||||||
if (used == 0) return free(address);
|
if (used == 0) return free(address);
|
||||||
|
@ -676,18 +675,18 @@ bool MemoryManagerPrivate::shrink(void* address, sysuint_t used) ASMJIT_NOTHROW
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
sysuint_t offset = (sysuint_t)((uint8_t*)address - (uint8_t*)node->mem);
|
size_t offset = (size_t)((uint8_t*)address - (uint8_t*)node->mem);
|
||||||
sysuint_t bitpos = M_DIV(offset, node->density);
|
size_t bitpos = M_DIV(offset, node->density);
|
||||||
sysuint_t i = (bitpos / BITS_PER_ENTITY);
|
size_t i = (bitpos / BITS_PER_ENTITY);
|
||||||
|
|
||||||
sysuint_t* up = node->baUsed + i; // Current ubits address.
|
size_t* up = node->baUsed + i; // Current ubits address.
|
||||||
sysuint_t* cp = node->baCont + i; // Current cbits address.
|
size_t* cp = node->baCont + i; // Current cbits address.
|
||||||
sysuint_t ubits = *up; // Current ubits[0] value.
|
size_t ubits = *up; // Current ubits[0] value.
|
||||||
sysuint_t cbits = *cp; // Current cbits[0] value.
|
size_t cbits = *cp; // Current cbits[0] value.
|
||||||
sysuint_t bit = (sysuint_t)1 << (bitpos % BITS_PER_ENTITY);
|
size_t bit = (size_t)1 << (bitpos % BITS_PER_ENTITY);
|
||||||
|
|
||||||
sysuint_t cont = 0;
|
size_t cont = 0;
|
||||||
sysuint_t usedBlocks = (used + node->density - 1) / node->density;
|
size_t usedBlocks = (used + node->density - 1) / node->density;
|
||||||
|
|
||||||
bool stop;
|
bool stop;
|
||||||
|
|
||||||
|
@ -709,14 +708,14 @@ bool MemoryManagerPrivate::shrink(void* address, sysuint_t used) ASMJIT_NOTHROW
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the tail blocks.
|
// Free the tail blocks.
|
||||||
cont = (sysuint_t)-1;
|
cont = ~(size_t)0;
|
||||||
goto enterFreeLoop;
|
goto _EnterFreeLoop;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
stop = (cbits & bit) == 0;
|
stop = (cbits & bit) == 0;
|
||||||
ubits &= ~bit;
|
ubits &= ~bit;
|
||||||
enterFreeLoop:
|
_EnterFreeLoop:
|
||||||
cbits &= ~bit;
|
cbits &= ~bit;
|
||||||
|
|
||||||
bit <<= 1;
|
bit <<= 1;
|
||||||
|
@ -743,7 +742,7 @@ enterFreeLoop:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManagerPrivate::freeAll(bool keepVirtualMemory) ASMJIT_NOTHROW
|
void MemoryManagerPrivate::freeAll(bool keepVirtualMemory)
|
||||||
{
|
{
|
||||||
MemNode* node = _first;
|
MemNode* node = _first;
|
||||||
|
|
||||||
|
@ -751,7 +750,9 @@ void MemoryManagerPrivate::freeAll(bool keepVirtualMemory) ASMJIT_NOTHROW
|
||||||
{
|
{
|
||||||
MemNode* next = node->next;
|
MemNode* next = node->next;
|
||||||
|
|
||||||
if (!keepVirtualMemory) freeVirtualMemory(node->mem, node->size);
|
if (!keepVirtualMemory)
|
||||||
|
freeVirtualMemory(node->mem, node->size);
|
||||||
|
|
||||||
ASMJIT_FREE(node->baUsed);
|
ASMJIT_FREE(node->baUsed);
|
||||||
ASMJIT_FREE(node);
|
ASMJIT_FREE(node);
|
||||||
|
|
||||||
|
@ -817,12 +818,12 @@ static inline MemNode* rbRotateDouble(MemNode* root, int dir)
|
||||||
return rbRotateSingle(root, dir);
|
return rbRotateSingle(root, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemoryManagerPrivate::checkTree() ASMJIT_NOTHROW
|
bool MemoryManagerPrivate::checkTree()
|
||||||
{
|
{
|
||||||
return rbAssert(_root) > 0;
|
return rbAssert(_root) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManagerPrivate::insertNode(MemNode* node) ASMJIT_NOTHROW
|
void MemoryManagerPrivate::insertNode(MemNode* node)
|
||||||
{
|
{
|
||||||
if (_root == NULL)
|
if (_root == NULL)
|
||||||
{
|
{
|
||||||
|
@ -905,7 +906,7 @@ void MemoryManagerPrivate::insertNode(MemNode* node) ASMJIT_NOTHROW
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemNode* MemoryManagerPrivate::removeNode(MemNode* node) ASMJIT_NOTHROW
|
MemNode* MemoryManagerPrivate::removeNode(MemNode* node)
|
||||||
{
|
{
|
||||||
// False tree root.
|
// False tree root.
|
||||||
RbNode<MemNode> head = {0};
|
RbNode<MemNode> head = {0};
|
||||||
|
@ -996,7 +997,7 @@ MemNode* MemoryManagerPrivate::removeNode(MemNode* node) ASMJIT_NOTHROW
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemNode* MemoryManagerPrivate::findPtr(uint8_t* mem) ASMJIT_NOTHROW
|
MemNode* MemoryManagerPrivate::findPtr(uint8_t* mem)
|
||||||
{
|
{
|
||||||
MemNode* cur = _root;
|
MemNode* cur = _root;
|
||||||
while (cur)
|
while (cur)
|
||||||
|
@ -1031,15 +1032,15 @@ MemNode* MemoryManagerPrivate::findPtr(uint8_t* mem) ASMJIT_NOTHROW
|
||||||
// [AsmJit::MemoryManager]
|
// [AsmJit::MemoryManager]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
MemoryManager::MemoryManager() ASMJIT_NOTHROW
|
MemoryManager::MemoryManager()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryManager::~MemoryManager() ASMJIT_NOTHROW
|
MemoryManager::~MemoryManager()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryManager* MemoryManager::getGlobal() ASMJIT_NOTHROW
|
MemoryManager* MemoryManager::getGlobal()
|
||||||
{
|
{
|
||||||
static VirtualMemoryManager memmgr;
|
static VirtualMemoryManager memmgr;
|
||||||
return &memmgr;
|
return &memmgr;
|
||||||
|
@ -1050,54 +1051,54 @@ MemoryManager* MemoryManager::getGlobal() ASMJIT_NOTHROW
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
#if !defined(ASMJIT_WINDOWS)
|
#if !defined(ASMJIT_WINDOWS)
|
||||||
VirtualMemoryManager::VirtualMemoryManager() ASMJIT_NOTHROW
|
VirtualMemoryManager::VirtualMemoryManager()
|
||||||
{
|
{
|
||||||
MemoryManagerPrivate* d = new(std::nothrow) MemoryManagerPrivate();
|
MemoryManagerPrivate* d = new(std::nothrow) MemoryManagerPrivate();
|
||||||
_d = (void*)d;
|
_d = (void*)d;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
VirtualMemoryManager::VirtualMemoryManager() ASMJIT_NOTHROW
|
VirtualMemoryManager::VirtualMemoryManager()
|
||||||
{
|
{
|
||||||
MemoryManagerPrivate* d = new(std::nothrow) MemoryManagerPrivate(GetCurrentProcess());
|
MemoryManagerPrivate* d = new(std::nothrow) MemoryManagerPrivate(GetCurrentProcess());
|
||||||
_d = (void*)d;
|
_d = (void*)d;
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualMemoryManager::VirtualMemoryManager(HANDLE hProcess) ASMJIT_NOTHROW
|
VirtualMemoryManager::VirtualMemoryManager(HANDLE hProcess)
|
||||||
{
|
{
|
||||||
MemoryManagerPrivate* d = new(std::nothrow) MemoryManagerPrivate(hProcess);
|
MemoryManagerPrivate* d = new(std::nothrow) MemoryManagerPrivate(hProcess);
|
||||||
_d = (void*)d;
|
_d = (void*)d;
|
||||||
}
|
}
|
||||||
#endif // ASMJIT_WINDOWS
|
#endif // ASMJIT_WINDOWS
|
||||||
|
|
||||||
VirtualMemoryManager::~VirtualMemoryManager() ASMJIT_NOTHROW
|
VirtualMemoryManager::~VirtualMemoryManager()
|
||||||
{
|
{
|
||||||
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* VirtualMemoryManager::alloc(sysuint_t size, uint32_t type) ASMJIT_NOTHROW
|
void* VirtualMemoryManager::alloc(size_t size, uint32_t type)
|
||||||
{
|
{
|
||||||
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
||||||
|
|
||||||
if (type == MEMORY_ALLOC_PERMANENT)
|
if (type == kMemAllocPermanent)
|
||||||
return d->allocPermanent(size);
|
return d->allocPermanent(size);
|
||||||
else
|
else
|
||||||
return d->allocFreeable(size);
|
return d->allocFreeable(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualMemoryManager::free(void* address) ASMJIT_NOTHROW
|
bool VirtualMemoryManager::free(void* address)
|
||||||
{
|
{
|
||||||
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
||||||
return d->free(address);
|
return d->free(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualMemoryManager::shrink(void* address, sysuint_t used) ASMJIT_NOTHROW
|
bool VirtualMemoryManager::shrink(void* address, size_t used)
|
||||||
{
|
{
|
||||||
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
||||||
return d->shrink(address, used);
|
return d->shrink(address, used);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualMemoryManager::freeAll() ASMJIT_NOTHROW
|
void VirtualMemoryManager::freeAll()
|
||||||
{
|
{
|
||||||
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
||||||
|
|
||||||
|
@ -1105,25 +1106,25 @@ void VirtualMemoryManager::freeAll() ASMJIT_NOTHROW
|
||||||
return d->freeAll(false);
|
return d->freeAll(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
sysuint_t VirtualMemoryManager::getUsedBytes() ASMJIT_NOTHROW
|
size_t VirtualMemoryManager::getUsedBytes()
|
||||||
{
|
{
|
||||||
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
||||||
return d->_used;
|
return d->_used;
|
||||||
}
|
}
|
||||||
|
|
||||||
sysuint_t VirtualMemoryManager::getAllocatedBytes() ASMJIT_NOTHROW
|
size_t VirtualMemoryManager::getAllocatedBytes()
|
||||||
{
|
{
|
||||||
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
||||||
return d->_allocated;
|
return d->_allocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualMemoryManager::getKeepVirtualMemory() const ASMJIT_NOTHROW
|
bool VirtualMemoryManager::getKeepVirtualMemory() const
|
||||||
{
|
{
|
||||||
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
||||||
return d->_keepVirtualMemory;
|
return d->_keepVirtualMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualMemoryManager::setKeepVirtualMemory(bool keepVirtualMemory) ASMJIT_NOTHROW
|
void VirtualMemoryManager::setKeepVirtualMemory(bool keepVirtualMemory)
|
||||||
{
|
{
|
||||||
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
||||||
d->_keepVirtualMemory = keepVirtualMemory;
|
d->_keepVirtualMemory = keepVirtualMemory;
|
||||||
|
@ -1135,7 +1136,7 @@ void VirtualMemoryManager::setKeepVirtualMemory(bool keepVirtualMemory) ASMJIT_N
|
||||||
|
|
||||||
#if defined(ASMJIT_MEMORY_MANAGER_DUMP)
|
#if defined(ASMJIT_MEMORY_MANAGER_DUMP)
|
||||||
|
|
||||||
struct ASMJIT_HIDDEN GraphVizContext
|
struct GraphVizContext
|
||||||
{
|
{
|
||||||
GraphVizContext();
|
GraphVizContext();
|
||||||
~GraphVizContext();
|
~GraphVizContext();
|
||||||
|
@ -1194,7 +1195,9 @@ void VirtualMemoryManager::dump(const char* fileName)
|
||||||
{
|
{
|
||||||
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
MemoryManagerPrivate* d = reinterpret_cast<MemoryManagerPrivate*>(_d);
|
||||||
GraphVizContext ctx;
|
GraphVizContext ctx;
|
||||||
if (!ctx.openFile(fileName)) return;
|
|
||||||
|
if (!ctx.openFile(fileName))
|
||||||
|
return;
|
||||||
|
|
||||||
fprintf(ctx.file, "digraph {\n");
|
fprintf(ctx.file, "digraph {\n");
|
||||||
if (d->_root) ctx.dumpNode(d->_root);
|
if (d->_root) ctx.dumpNode(d->_root);
|
||||||
|
@ -1205,4 +1208,4 @@ void VirtualMemoryManager::dump(const char* fileName)
|
||||||
} // AsmJit namespace
|
} // AsmJit namespace
|
||||||
|
|
||||||
// [Api-End]
|
// [Api-End]
|
||||||
#include "ApiEnd.h"
|
#include "../core/apiend.h"
|
|
@ -5,15 +5,15 @@
|
||||||
// Zlib - See COPYING file in this package.
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#ifndef _ASMJIT_MEMORYMANAGER_H
|
#ifndef _ASMJIT_CORE_MEMORYMANAGER_H
|
||||||
#define _ASMJIT_MEMORYMANAGER_H
|
#define _ASMJIT_CORE_MEMORYMANAGER_H
|
||||||
|
|
||||||
// [Dependencies]
|
// [Dependencies - AsmJit]
|
||||||
#include "Build.h"
|
#include "../core/build.h"
|
||||||
#include "Defs.h"
|
#include "../core/defs.h"
|
||||||
|
|
||||||
// [Api-Begin]
|
// [Api-Begin]
|
||||||
#include "ApiBegin.h"
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
// [Debug]
|
// [Debug]
|
||||||
// #define ASMJIT_MEMORY_MANAGER_DUMP
|
// #define ASMJIT_MEMORY_MANAGER_DUMP
|
||||||
|
@ -32,17 +32,17 @@ namespace AsmJit {
|
||||||
//! This class is pure virtual. You can get default virtual memory manager using
|
//! This class is pure virtual. You can get default virtual memory manager using
|
||||||
//! @c getGlobal() method. If you want to create more memory managers with same
|
//! @c getGlobal() method. If you want to create more memory managers with same
|
||||||
//! functionality as global memory manager use @c VirtualMemoryManager class.
|
//! functionality as global memory manager use @c VirtualMemoryManager class.
|
||||||
struct ASMJIT_API MemoryManager
|
struct MemoryManager
|
||||||
{
|
{
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Construction / Destruction]
|
// [Construction / Destruction]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
//! @brief Create memory manager instance.
|
//! @brief Create memory manager instance.
|
||||||
MemoryManager() ASMJIT_NOTHROW;
|
ASMJIT_API MemoryManager();
|
||||||
//! @brief Destroy memory manager instance, this means also to free all memory
|
//! @brief Destroy memory manager instance, this means also to free all memory
|
||||||
//! blocks.
|
//! blocks.
|
||||||
virtual ~MemoryManager() ASMJIT_NOTHROW;
|
ASMJIT_API virtual ~MemoryManager();
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Interface]
|
// [Interface]
|
||||||
|
@ -53,62 +53,70 @@ struct ASMJIT_API MemoryManager
|
||||||
//! Note that if you are implementing your own virtual memory manager then you
|
//! Note that if you are implementing your own virtual memory manager then you
|
||||||
//! can quitly ignore type of allocation. This is mainly for AsmJit to memory
|
//! can quitly ignore type of allocation. This is mainly for AsmJit to memory
|
||||||
//! manager that allocated memory will be never freed.
|
//! manager that allocated memory will be never freed.
|
||||||
virtual void* alloc(sysuint_t size, uint32_t type = MEMORY_ALLOC_FREEABLE) ASMJIT_NOTHROW = 0;
|
virtual void* alloc(size_t size, uint32_t type = kMemAllocFreeable) = 0;
|
||||||
//! @brief Free previously allocated memory at a given @a address.
|
//! @brief Free previously allocated memory at a given @a address.
|
||||||
virtual bool free(void* address) ASMJIT_NOTHROW = 0;
|
virtual bool free(void* address) = 0;
|
||||||
//! @brief Free some tail memory.
|
//! @brief Free some tail memory.
|
||||||
virtual bool shrink(void* address, sysuint_t used) ASMJIT_NOTHROW = 0;
|
virtual bool shrink(void* address, size_t used) = 0;
|
||||||
//! @brief Free all allocated memory.
|
//! @brief Free all allocated memory.
|
||||||
virtual void freeAll() ASMJIT_NOTHROW = 0;
|
virtual void freeAll() = 0;
|
||||||
|
|
||||||
//! @brief Get how many bytes are currently used.
|
//! @brief Get how many bytes are currently used.
|
||||||
virtual sysuint_t getUsedBytes() ASMJIT_NOTHROW = 0;
|
virtual size_t getUsedBytes() = 0;
|
||||||
//! @brief Get how many bytes are currently allocated.
|
//! @brief Get how many bytes are currently allocated.
|
||||||
virtual sysuint_t getAllocatedBytes() ASMJIT_NOTHROW = 0;
|
virtual size_t getAllocatedBytes() = 0;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Statics]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
//! @brief Get global memory manager instance.
|
//! @brief Get global memory manager instance.
|
||||||
//!
|
//!
|
||||||
//! Global instance is instance of @c VirtualMemoryManager class. Global memory
|
//! Global instance is instance of @c VirtualMemoryManager class. Global memory
|
||||||
//! manager is used by default by @ref Assembler::make() and @ref Compiler::make()
|
//! manager is used by default by @ref Assembler::make() and @ref Compiler::make()
|
||||||
//! methods.
|
//! methods.
|
||||||
static MemoryManager* getGlobal() ASMJIT_NOTHROW;
|
ASMJIT_API static MemoryManager* getGlobal();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::VirtualMemoryManager]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief Reference implementation of memory manager that uses
|
//! @brief Reference implementation of memory manager that uses
|
||||||
//! @ref AsmJit::VirtualMemory class to allocate chunks of virtual memory
|
//! @ref AsmJit::VirtualMemory class to allocate chunks of virtual memory
|
||||||
//! and bit arrays to manage it.
|
//! and bit arrays to manage it.
|
||||||
struct ASMJIT_API VirtualMemoryManager : public MemoryManager
|
struct VirtualMemoryManager : public MemoryManager
|
||||||
{
|
{
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Construction / Destruction]
|
// [Construction / Destruction]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
//! @brief Create a @c VirtualMemoryManager instance.
|
//! @brief Create a @c VirtualMemoryManager instance.
|
||||||
VirtualMemoryManager() ASMJIT_NOTHROW;
|
ASMJIT_API VirtualMemoryManager();
|
||||||
|
|
||||||
#if defined(ASMJIT_WINDOWS)
|
#if defined(ASMJIT_WINDOWS)
|
||||||
//! @brief Create a @c VirtualMemoryManager instance for process @a hProcess.
|
//! @brief Create a @c VirtualMemoryManager instance for process @a hProcess.
|
||||||
//!
|
//!
|
||||||
//! This is specialized version of constructor available only for windows and
|
//! This is specialized version of constructor available only for windows and
|
||||||
//! usable to alloc/free memory of different process.
|
//! usable to alloc/free memory of different process.
|
||||||
VirtualMemoryManager(HANDLE hProcess) ASMJIT_NOTHROW;
|
ASMJIT_API VirtualMemoryManager(HANDLE hProcess);
|
||||||
#endif // ASMJIT_WINDOWS
|
#endif // ASMJIT_WINDOWS
|
||||||
|
|
||||||
//! @brief Destroy the @c VirtualMemoryManager instance, this means also to
|
//! @brief Destroy the @c VirtualMemoryManager instance, this means also to
|
||||||
//! free all blocks.
|
//! free all blocks.
|
||||||
virtual ~VirtualMemoryManager() ASMJIT_NOTHROW;
|
ASMJIT_API virtual ~VirtualMemoryManager();
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Interface]
|
// [Interface]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
virtual void* alloc(sysuint_t size, uint32_t type = MEMORY_ALLOC_FREEABLE) ASMJIT_NOTHROW;
|
ASMJIT_API virtual void* alloc(size_t size, uint32_t type = kMemAllocFreeable);
|
||||||
virtual bool free(void* address) ASMJIT_NOTHROW;
|
ASMJIT_API virtual bool free(void* address);
|
||||||
virtual bool shrink(void* address, sysuint_t used) ASMJIT_NOTHROW;
|
ASMJIT_API virtual bool shrink(void* address, size_t used);
|
||||||
virtual void freeAll() ASMJIT_NOTHROW;
|
ASMJIT_API virtual void freeAll();
|
||||||
|
|
||||||
virtual sysuint_t getUsedBytes() ASMJIT_NOTHROW;
|
ASMJIT_API virtual size_t getUsedBytes();
|
||||||
virtual sysuint_t getAllocatedBytes() ASMJIT_NOTHROW;
|
ASMJIT_API virtual size_t getAllocatedBytes();
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Virtual Memory Manager Specific]
|
// [Virtual Memory Manager Specific]
|
||||||
|
@ -118,7 +126,7 @@ struct ASMJIT_API VirtualMemoryManager : public MemoryManager
|
||||||
//! destroyed.
|
//! destroyed.
|
||||||
//!
|
//!
|
||||||
//! @sa @c setKeepVirtualMemory().
|
//! @sa @c setKeepVirtualMemory().
|
||||||
bool getKeepVirtualMemory() const ASMJIT_NOTHROW;
|
ASMJIT_API bool getKeepVirtualMemory() const;
|
||||||
|
|
||||||
//! @brief Set whether to keep allocated memory after memory manager is
|
//! @brief Set whether to keep allocated memory after memory manager is
|
||||||
//! destroyed.
|
//! destroyed.
|
||||||
|
@ -129,10 +137,10 @@ struct ASMJIT_API VirtualMemoryManager : public MemoryManager
|
||||||
//! VirtualMemoryManager destructor. After destruction all internal
|
//! VirtualMemoryManager destructor. After destruction all internal
|
||||||
//! structures are freed, only the process virtual memory remains.
|
//! structures are freed, only the process virtual memory remains.
|
||||||
//!
|
//!
|
||||||
//! @note Memory allocated with MEMORY_ALLOC_PERMANENT is always kept.
|
//! @note Memory allocated with kMemAllocPermanent is always kept.
|
||||||
//!
|
//!
|
||||||
//! @sa @c getKeepVirtualMemory().
|
//! @sa @c getKeepVirtualMemory().
|
||||||
void setKeepVirtualMemory(bool keepVirtualMemory) ASMJIT_NOTHROW;
|
ASMJIT_API void setKeepVirtualMemory(bool keepVirtualMemory);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Debug]
|
// [Debug]
|
||||||
|
@ -142,14 +150,13 @@ struct ASMJIT_API VirtualMemoryManager : public MemoryManager
|
||||||
//! @brief Dump memory manager tree into file.
|
//! @brief Dump memory manager tree into file.
|
||||||
//!
|
//!
|
||||||
//! Generated output is using DOT language (from graphviz package).
|
//! Generated output is using DOT language (from graphviz package).
|
||||||
void dump(const char* fileName);
|
ASMJIT_API void dump(const char* fileName);
|
||||||
#endif // ASMJIT_MEMORY_MANAGER_DUMP
|
#endif // ASMJIT_MEMORY_MANAGER_DUMP
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Members]
|
// [Members]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
protected:
|
|
||||||
//! @brief Pointer to private data hidden from the public API.
|
//! @brief Pointer to private data hidden from the public API.
|
||||||
void* _d;
|
void* _d;
|
||||||
};
|
};
|
||||||
|
@ -159,7 +166,7 @@ protected:
|
||||||
} // AsmJit namespace
|
} // AsmJit namespace
|
||||||
|
|
||||||
// [Api-End]
|
// [Api-End]
|
||||||
#include "ApiEnd.h"
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#endif // _ASMJIT_MEMORYMANAGER_H
|
#endif // _ASMJIT_CORE_MEMORYMANAGER_H
|
|
@ -4,12 +4,14 @@
|
||||||
// [License]
|
// [License]
|
||||||
// Zlib - See COPYING file in this package.
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
// [Dependencies]
|
#define ASMJIT_EXPORTS
|
||||||
#include "Build.h"
|
|
||||||
#include "MemoryMarker.h"
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/build.h"
|
||||||
|
#include "../core/memorymarker.h"
|
||||||
|
|
||||||
// [Api-Begin]
|
// [Api-Begin]
|
||||||
#include "ApiBegin.h"
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
namespace AsmJit {
|
namespace AsmJit {
|
||||||
|
|
||||||
|
@ -17,10 +19,10 @@ namespace AsmJit {
|
||||||
// [AsmJit::MemoryMarker]
|
// [AsmJit::MemoryMarker]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
MemoryMarker::MemoryMarker() ASMJIT_NOTHROW {}
|
MemoryMarker::MemoryMarker() {}
|
||||||
MemoryMarker::~MemoryMarker() ASMJIT_NOTHROW {}
|
MemoryMarker::~MemoryMarker() {}
|
||||||
|
|
||||||
} // AsmJit namespace
|
} // AsmJit namespace
|
||||||
|
|
||||||
// [Api-End]
|
// [Api-End]
|
||||||
#include "ApiEnd.h"
|
#include "../core/apiend.h"
|
|
@ -5,15 +5,15 @@
|
||||||
// Zlib - See COPYING file in this package.
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#ifndef _ASMJIT_MEMORYMARKER_H
|
#ifndef _ASMJIT_CORE_MEMORYMARKER_H
|
||||||
#define _ASMJIT_MEMORYMARKER_H
|
#define _ASMJIT_CORE_MEMORYMARKER_H
|
||||||
|
|
||||||
// [Dependencies]
|
// [Dependencies - AsmJit]
|
||||||
#include "Build.h"
|
#include "../core/build.h"
|
||||||
#include "Defs.h"
|
#include "../core/defs.h"
|
||||||
|
|
||||||
// [Api-Begin]
|
// [Api-Begin]
|
||||||
#include "ApiBegin.h"
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
namespace AsmJit {
|
namespace AsmJit {
|
||||||
|
|
||||||
|
@ -25,23 +25,22 @@ namespace AsmJit {
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief Virtual memory marker interface.
|
//! @brief Virtual memory marker interface.
|
||||||
struct ASMJIT_API MemoryMarker
|
struct MemoryMarker
|
||||||
{
|
{
|
||||||
|
ASMJIT_NO_COPY(MemoryMarker)
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Construction / Destruction]
|
// [Construction / Destruction]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
MemoryMarker() ASMJIT_NOTHROW;
|
ASMJIT_API MemoryMarker();
|
||||||
virtual ~MemoryMarker() ASMJIT_NOTHROW;
|
ASMJIT_API virtual ~MemoryMarker();
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Interface]
|
// [Interface]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
virtual void mark(const void* ptr, sysuint_t size) ASMJIT_NOTHROW = 0;
|
virtual void mark(const void* ptr, size_t size) = 0;
|
||||||
|
|
||||||
private:
|
|
||||||
ASMJIT_DISABLE_COPY(MemoryMarker)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//! @}
|
//! @}
|
||||||
|
@ -49,7 +48,7 @@ private:
|
||||||
} // AsmJit namespace
|
} // AsmJit namespace
|
||||||
|
|
||||||
// [Api-End]
|
// [Api-End]
|
||||||
#include "ApiEnd.h"
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#endif // _ASMJIT_MEMORYMARKER_H
|
#endif // _ASMJIT_CORE_MEMORYMARKER_H
|
|
@ -4,33 +4,39 @@
|
||||||
// [License]
|
// [License]
|
||||||
// Zlib - See COPYING file in this package.
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
// [Guard]
|
#define ASMJIT_EXPORTS
|
||||||
#ifndef _ASMJIT_ASSEMBLER_H
|
|
||||||
#define _ASMJIT_ASSEMBLER_H
|
|
||||||
|
|
||||||
// [Dependencies]
|
// [Dependencies - AsmJit]
|
||||||
#include "Build.h"
|
#include "../core/operand.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
namespace AsmJit {
|
namespace AsmJit {
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [Forward Declarations]
|
// [AsmJit::Operand]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
struct Logger;
|
const Operand noOperand;
|
||||||
struct MemoryManager;
|
|
||||||
struct EInstruction;
|
// ============================================================================
|
||||||
|
// [AsmJit::Imm]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Create signed immediate value operand.
|
||||||
|
Imm imm(sysint_t i)
|
||||||
|
{
|
||||||
|
return Imm(i, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Create unsigned immediate value operand.
|
||||||
|
Imm uimm(sysuint_t i)
|
||||||
|
{
|
||||||
|
return Imm((sysint_t)i, true);
|
||||||
|
}
|
||||||
|
|
||||||
} // AsmJit namespace
|
} // AsmJit namespace
|
||||||
|
|
||||||
// ============================================================================
|
// [Api-End]
|
||||||
// [Platform Specific]
|
#include "../core/apiend.h"
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
// [X86 / X64]
|
|
||||||
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
|
||||||
#include "AssemblerX86X64.h"
|
|
||||||
#endif // ASMJIT_X86 || ASMJIT_X64
|
|
||||||
|
|
||||||
// [Guard]
|
|
||||||
#endif // _ASMJIT_ASSEMBLER_H
|
|
|
@ -0,0 +1,585 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_OPERAND_H
|
||||||
|
#define _ASMJIT_CORE_OPERAND_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/defs.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Core
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::_OperandData]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief Base operand data.
|
||||||
|
struct _OpBase
|
||||||
|
{
|
||||||
|
//! @brief Type of operand, see @c kOperandType.
|
||||||
|
uint8_t op;
|
||||||
|
//! @brief Size of operand (register, address, immediate, or variable).
|
||||||
|
uint8_t size;
|
||||||
|
//! @brief Not used.
|
||||||
|
uint8_t reserved[2];
|
||||||
|
|
||||||
|
//! @brief Operand ID (private variable for @c Assembler and @c Compiler classes).
|
||||||
|
//!
|
||||||
|
//! @note Uninitialized operand has always zero id.
|
||||||
|
uint32_t id;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief Label operand data.
|
||||||
|
struct _OpLabel
|
||||||
|
{
|
||||||
|
//! @brief Type of operand, see @c kOperandType (in this case @c kOperandLabel).
|
||||||
|
uint8_t op;
|
||||||
|
//! @brief Size of label, currently not used.
|
||||||
|
uint8_t size;
|
||||||
|
//! @brief Not used.
|
||||||
|
uint8_t reserved[2];
|
||||||
|
|
||||||
|
//! @brief Operand ID.
|
||||||
|
uint32_t id;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief Register operand data.
|
||||||
|
struct _OpReg
|
||||||
|
{
|
||||||
|
//! @brief Type of operand, see @c kOperandType (in this case @c kOperandReg).
|
||||||
|
uint8_t op;
|
||||||
|
//! @brief Size of register.
|
||||||
|
uint8_t size;
|
||||||
|
//! @brief Not used.
|
||||||
|
uint8_t reserved[2];
|
||||||
|
|
||||||
|
//! @brief Operand id.
|
||||||
|
uint32_t id;
|
||||||
|
//! @brief Register/Variable code, see @c REG.
|
||||||
|
uint32_t code;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief Variable operand data.
|
||||||
|
struct _OpVar
|
||||||
|
{
|
||||||
|
//! @brief Type of operand, see @c kOperandType (in this case @c kOperandVar).
|
||||||
|
uint8_t op;
|
||||||
|
//! @brief Size of variable (0 if don't known).
|
||||||
|
uint8_t size;
|
||||||
|
//! @brief Not used.
|
||||||
|
uint8_t reserved[2];
|
||||||
|
|
||||||
|
//! @brief Operand ID.
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
//! @brief Type (and later also code) of register, see @c kX86RegType, @c kX86RegCode.
|
||||||
|
//!
|
||||||
|
//! @note Register code and variable code are two different things. In most
|
||||||
|
//! cases regCode is very related to varType, but general purpose registers
|
||||||
|
//! are divided to 64-bit, 32-bit, 16-bit and 8-bit entities so the regCode
|
||||||
|
//! can be used to access these, varType remains unchanged from the
|
||||||
|
//! initialization state. Variable type describes mainly variable type and
|
||||||
|
//! home memory size.
|
||||||
|
uint32_t regCode;
|
||||||
|
|
||||||
|
//! @brief Type of variable. See @c kX86VarType enum.
|
||||||
|
uint32_t varType;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief Memory operand data.
|
||||||
|
struct _OpMem
|
||||||
|
{
|
||||||
|
//! @brief Type of operand, see @c kOperandType (in this case @c kOperandMem).
|
||||||
|
uint8_t op;
|
||||||
|
//! @brief Size of pointer.
|
||||||
|
uint8_t size;
|
||||||
|
|
||||||
|
//! @brief Memory operand type, see @c kOperandMemType.
|
||||||
|
uint8_t type;
|
||||||
|
//! @brief Segment override prefix, see @c kX86Seg.
|
||||||
|
uint8_t segment : 4;
|
||||||
|
//! @brief Emit MOV/LEA instruction using 16-bit/32-bit form of base/index
|
||||||
|
//! registers.
|
||||||
|
uint8_t sizePrefix : 1;
|
||||||
|
//! @brief Index register shift/scale (0 to 3 inclusive, see @c kScale).
|
||||||
|
uint8_t shift : 3;
|
||||||
|
|
||||||
|
//! @brief Operand ID.
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
//! @brief Base register index, variable or label id.
|
||||||
|
uint32_t base;
|
||||||
|
//! @brief Index register index or variable id.
|
||||||
|
uint32_t index;
|
||||||
|
|
||||||
|
//! @brief Target (for 32-bit, absolute address).
|
||||||
|
void* target;
|
||||||
|
//! @brief Displacement.
|
||||||
|
sysint_t displacement;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief Immediate operand data.
|
||||||
|
struct _OpImm
|
||||||
|
{
|
||||||
|
//! @brief Type of operand, see @c kOperandType (in this case @c kOperandImm)..
|
||||||
|
uint8_t op;
|
||||||
|
//! @brief Size of immediate (or 0 to autodetect).
|
||||||
|
uint8_t size;
|
||||||
|
//! @brief @c true if immediate is unsigned.
|
||||||
|
uint8_t isUnsigned;
|
||||||
|
//! @brief Not used.
|
||||||
|
uint8_t reserved;
|
||||||
|
|
||||||
|
//! @brief Operand ID.
|
||||||
|
uint32_t id;
|
||||||
|
//! @brief Immediate value.
|
||||||
|
sysint_t value;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief Binary operand data.
|
||||||
|
struct _OpBin
|
||||||
|
{
|
||||||
|
//! @brief First four 32-bit integers.
|
||||||
|
uint32_t u32[4];
|
||||||
|
//! @brief Second two 32-bit or 64-bit integers.
|
||||||
|
uintptr_t uptr[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Operand]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Operand can contain register, memory location, immediate, or label.
|
||||||
|
struct Operand
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create an uninitialized operand.
|
||||||
|
inline Operand()
|
||||||
|
{
|
||||||
|
memset(this, 0, sizeof(Operand));
|
||||||
|
_base.id = kInvalidValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Create a reference to @a other operand.
|
||||||
|
inline Operand(const Operand& other)
|
||||||
|
{
|
||||||
|
_init(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NODOC)
|
||||||
|
inline Operand(const _DontInitialize&) {}
|
||||||
|
#endif // ASMJIT_NODOC
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Init & Copy]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief Initialize operand to @a other (used by constructors).
|
||||||
|
inline void _init(const Operand& other)
|
||||||
|
{ memcpy(this, &other, sizeof(Operand)); }
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief Initialize operand to @a other (used by assign operators).
|
||||||
|
inline void _copy(const Operand& other)
|
||||||
|
{ memcpy(this, &other, sizeof(Operand)); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Data]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline T& getData() { return reinterpret_cast<T&>(_base); }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline const T& getData() const { return reinterpret_cast<const T&>(_base); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Type]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get type of the operand, see @c kOperandType.
|
||||||
|
inline uint32_t getType() const
|
||||||
|
{ return _base.op; }
|
||||||
|
|
||||||
|
//! @brief Get whether the operand is none (@c kOperandNone).
|
||||||
|
inline bool isNone() const
|
||||||
|
{ return (_base.op == kOperandNone); }
|
||||||
|
|
||||||
|
//! @brief Get whether the operand is any (general purpose, mmx or sse) register (@c kOperandReg).
|
||||||
|
inline bool isReg() const
|
||||||
|
{ return (_base.op == kOperandReg); }
|
||||||
|
|
||||||
|
//! @brief Get whether the operand is memory address (@c kOperandMem).
|
||||||
|
inline bool isMem() const
|
||||||
|
{ return (_base.op == kOperandMem); }
|
||||||
|
|
||||||
|
//! @brief Get whether the operand is immediate (@c kOperandImm).
|
||||||
|
inline bool isImm() const
|
||||||
|
{ return (_base.op == kOperandImm); }
|
||||||
|
|
||||||
|
//! @brief Get whether the operand is label (@c kOperandLabel).
|
||||||
|
inline bool isLabel() const
|
||||||
|
{ return (_base.op == kOperandLabel); }
|
||||||
|
|
||||||
|
//! @brief Get whether the operand is variable (@c kOperandVar).
|
||||||
|
inline bool isVar() const
|
||||||
|
{ return (_base.op == kOperandVar); }
|
||||||
|
|
||||||
|
//! @brief Get whether the operand is variable or memory.
|
||||||
|
inline bool isVarMem() const
|
||||||
|
{ return ((_base.op & (kOperandVar | kOperandMem)) != 0); }
|
||||||
|
|
||||||
|
//! @brief Get whether the operand is register and type of register is @a regType.
|
||||||
|
inline bool isRegType(uint32_t regType) const
|
||||||
|
{ return (_base.op == kOperandReg) & ((_reg.code & kRegTypeMask) == regType); }
|
||||||
|
|
||||||
|
//! @brief Get whether the operand is register and code of register is @a regCode.
|
||||||
|
inline bool isRegCode(uint32_t regCode) const
|
||||||
|
{ return (_base.op == kOperandReg) & (_reg.code == regCode); }
|
||||||
|
|
||||||
|
//! @brief Get whether the operand is register and index of register is @a regIndex.
|
||||||
|
inline bool isRegIndex(uint32_t regIndex) const
|
||||||
|
{ return (_base.op == kOperandReg) & ((_reg.code & kRegIndexMask) == (regIndex & kRegIndexMask)); }
|
||||||
|
|
||||||
|
//! @brief Get whether the operand is any register or memory.
|
||||||
|
inline bool isRegMem() const
|
||||||
|
{ return ((_base.op & (kOperandReg | kOperandMem)) != 0); }
|
||||||
|
|
||||||
|
//! @brief Get whether the operand is register of @a regType type or memory.
|
||||||
|
inline bool isRegTypeMem(uint32_t regType) const
|
||||||
|
{ return ((_base.op == kOperandReg) & ((_reg.code & kRegTypeMask) == regType)) | (_base.op == kOperandMem); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Size]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get size of the operand in bytes.
|
||||||
|
inline uint32_t getSize() const
|
||||||
|
{ return _base.size; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Id]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Return operand Id (Operand Id's are used internally by
|
||||||
|
//! @c Assembler and @c Compiler classes).
|
||||||
|
//!
|
||||||
|
//! @note There is no way how to change or remove operand id. If you don't
|
||||||
|
//! need the operand just assign different operand to this one.
|
||||||
|
inline uint32_t getId() const
|
||||||
|
{ return _base.id; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
//! @brief Base operand data.
|
||||||
|
_OpBase _base;
|
||||||
|
//! @brief Label operand data.
|
||||||
|
_OpLabel _lbl;
|
||||||
|
//! @brief Register operand data.
|
||||||
|
_OpReg _reg;
|
||||||
|
//! @brief Variable operand data.
|
||||||
|
_OpVar _var;
|
||||||
|
//! @brief Memory operand data.
|
||||||
|
_OpMem _mem;
|
||||||
|
//! @brief Immediate operand data.
|
||||||
|
_OpImm _imm;
|
||||||
|
//! @brief Binary data.
|
||||||
|
_OpBin _bin;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ASMJIT_VAR const Operand noOperand;
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Reg]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Base class for all register operands.
|
||||||
|
struct Reg : public Operand
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new base register.
|
||||||
|
inline Reg(uint32_t code, uint32_t size) : Operand(_DontInitialize())
|
||||||
|
{
|
||||||
|
_reg.op = kOperandReg;
|
||||||
|
_reg.size = (uint8_t)size;
|
||||||
|
_reg.id = kInvalidValue;
|
||||||
|
_reg.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Create a new reference to @a other.
|
||||||
|
inline Reg(const Reg& other) : Operand(other) {}
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NODOC)
|
||||||
|
inline Reg(const _DontInitialize& dontInitialize) : Operand(dontInitialize) {}
|
||||||
|
#endif // ASMJIT_NODOC
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Reg Specific]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get register code, see @c REG.
|
||||||
|
inline uint32_t getRegCode() const
|
||||||
|
{ return (uint32_t)(_reg.code); }
|
||||||
|
|
||||||
|
//! @brief Get register type, see @c REG.
|
||||||
|
inline uint32_t getRegType() const
|
||||||
|
{ return (uint32_t)(_reg.code & kRegTypeMask); }
|
||||||
|
|
||||||
|
//! @brief Get register index (value from 0 to 7/15).
|
||||||
|
inline uint32_t getRegIndex() const
|
||||||
|
{ return (uint32_t)(_reg.code & kRegIndexMask); }
|
||||||
|
|
||||||
|
//! @brief Get whether register code is equal to @a code.
|
||||||
|
inline bool isRegCode(uint32_t code) const
|
||||||
|
{ return _reg.code == code; }
|
||||||
|
|
||||||
|
//! @brief Get whether register code is equal to @a type.
|
||||||
|
inline bool isRegType(uint32_t type) const
|
||||||
|
{ return (uint32_t)(_reg.code & kRegTypeMask) == type; }
|
||||||
|
|
||||||
|
//! @brief Get whether register index is equal to @a index.
|
||||||
|
inline bool isRegIndex(uint32_t index) const
|
||||||
|
{ return (uint32_t)(_reg.code & kRegIndexMask) == index; }
|
||||||
|
|
||||||
|
//! @brief Set register code to @a code.
|
||||||
|
inline Reg& setCode(uint32_t code)
|
||||||
|
{
|
||||||
|
_reg.code = code;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set register size to @a size.
|
||||||
|
inline Reg& setSize(uint32_t size)
|
||||||
|
{
|
||||||
|
_reg.size = static_cast<uint8_t>(size);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Operator Overload]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline Reg& operator=(const Reg& other)
|
||||||
|
{ _copy(other); return *this; }
|
||||||
|
|
||||||
|
inline bool operator==(const Reg& other) const
|
||||||
|
{ return getRegCode() == other.getRegCode(); }
|
||||||
|
|
||||||
|
inline bool operator!=(const Reg& other) const
|
||||||
|
{ return getRegCode() != other.getRegCode(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Imm]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Immediate operand.
|
||||||
|
//!
|
||||||
|
//! Immediate operand is part of instruction (it's inlined after it).
|
||||||
|
//!
|
||||||
|
//! To create immediate operand, use @c imm() and @c uimm() constructors
|
||||||
|
//! or constructors provided by @c Immediate class itself.
|
||||||
|
struct Imm : public Operand
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new immediate value (initial value is 0).
|
||||||
|
Imm() : Operand(_DontInitialize())
|
||||||
|
{
|
||||||
|
_imm.op = kOperandImm;
|
||||||
|
_imm.size = 0;
|
||||||
|
_imm.isUnsigned = false;
|
||||||
|
_imm.reserved = 0;
|
||||||
|
|
||||||
|
_imm.id = kInvalidValue;
|
||||||
|
_imm.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Create a new signed immediate value, assigning the value to @a i.
|
||||||
|
Imm(sysint_t i) : Operand(_DontInitialize())
|
||||||
|
{
|
||||||
|
_imm.op = kOperandImm;
|
||||||
|
_imm.size = 0;
|
||||||
|
_imm.isUnsigned = false;
|
||||||
|
_imm.reserved = 0;
|
||||||
|
|
||||||
|
_imm.id = kInvalidValue;
|
||||||
|
_imm.value = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Create a new signed or unsigned immediate value, assigning the value to @a i.
|
||||||
|
Imm(sysint_t i, bool isUnsigned) : Operand(_DontInitialize())
|
||||||
|
{
|
||||||
|
_imm.op = kOperandImm;
|
||||||
|
_imm.size = 0;
|
||||||
|
_imm.isUnsigned = isUnsigned;
|
||||||
|
_imm.reserved = 0;
|
||||||
|
|
||||||
|
_imm.id = kInvalidValue;
|
||||||
|
_imm.value = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Create a new immediate value from @a other.
|
||||||
|
inline Imm(const Imm& other) : Operand(other)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Immediate Specific]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get whether an immediate is unsigned value.
|
||||||
|
inline bool isUnsigned() const
|
||||||
|
{ return _imm.isUnsigned != 0; }
|
||||||
|
|
||||||
|
//! @brief Get signed immediate value.
|
||||||
|
inline sysint_t getValue() const
|
||||||
|
{ return _imm.value; }
|
||||||
|
|
||||||
|
//! @brief Get unsigned immediate value.
|
||||||
|
inline sysuint_t getUValue() const
|
||||||
|
{ return static_cast<sysuint_t>(_imm.value); }
|
||||||
|
|
||||||
|
//! @brief Set immediate value as signed type to @a val.
|
||||||
|
inline Imm& setValue(sysint_t val, bool isUnsigned = false)
|
||||||
|
{
|
||||||
|
_imm.value = val;
|
||||||
|
_imm.isUnsigned = isUnsigned;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Set immediate value as unsigned type to @a val.
|
||||||
|
inline Imm& setUValue(sysuint_t val)
|
||||||
|
{
|
||||||
|
_imm.value = (sysint_t)val;
|
||||||
|
_imm.isUnsigned = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Operator Overload]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Assign a signed value @a val to the immediate operand.
|
||||||
|
inline Imm& operator=(sysint_t val)
|
||||||
|
{ setValue(val); return *this; }
|
||||||
|
|
||||||
|
//! @brief Assign @a other to the immediate operand.
|
||||||
|
inline Imm& operator=(const Imm& other)
|
||||||
|
{ _copy(other); return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Create signed immediate value operand.
|
||||||
|
ASMJIT_API Imm imm(sysint_t i);
|
||||||
|
|
||||||
|
//! @brief Create unsigned immediate value operand.
|
||||||
|
ASMJIT_API Imm uimm(sysuint_t i);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Label]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Label (jump target or data location).
|
||||||
|
//!
|
||||||
|
//! Label represents locations typically used as jump targets, but may be also
|
||||||
|
//! used as position where are stored constants or static variables. If you
|
||||||
|
//! want to use @c Label you need first to associate it with @c Assembler or
|
||||||
|
//! @c Compiler instance. To create new label use @c Assembler::newLabel() or
|
||||||
|
//! @c Compiler::newLabel().
|
||||||
|
//!
|
||||||
|
//! Example of using labels:
|
||||||
|
//!
|
||||||
|
//! @code
|
||||||
|
//! // Create Assembler or Compiler instance.
|
||||||
|
//! X86Assembler a;
|
||||||
|
//!
|
||||||
|
//! // Create Label instance.
|
||||||
|
//! Label L_1(a);
|
||||||
|
//!
|
||||||
|
//! // ... your code ...
|
||||||
|
//!
|
||||||
|
//! // Using label, see @c AsmJit::Assembler or @c AsmJit::Compiler.
|
||||||
|
//! a.jump(L_1);
|
||||||
|
//!
|
||||||
|
//! // ... your code ...
|
||||||
|
//!
|
||||||
|
//! // Bind label to current position, see @c AsmJit::Assembler::bind() or
|
||||||
|
//! // @c AsmJit::Compiler::bind().
|
||||||
|
//! a.bind(L_1);
|
||||||
|
//! @endcode
|
||||||
|
struct Label : public Operand
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create new, unassociated label.
|
||||||
|
inline Label() : Operand(_DontInitialize())
|
||||||
|
{
|
||||||
|
_lbl.op = kOperandLabel;
|
||||||
|
_lbl.size = 0;
|
||||||
|
_lbl.id = kInvalidValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Create reference to another label.
|
||||||
|
inline Label(const Label& other) : Operand(other) {}
|
||||||
|
|
||||||
|
//! @brief Destroy the label.
|
||||||
|
inline ~Label() {}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Operator Overload]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NODOC)
|
||||||
|
inline Label& operator=(const Label& other)
|
||||||
|
{ _copy(other); return *this; }
|
||||||
|
|
||||||
|
inline bool operator==(const Label& other) const { return _base.id == other._base.id; }
|
||||||
|
inline bool operator!=(const Label& other) const { return _base.id != other._base.id; }
|
||||||
|
#endif // ASMJIT_NODOC
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_OPERAND_H
|
|
@ -0,0 +1,224 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_PODVECTOR_H
|
||||||
|
#define _ASMJIT_CORE_PODVECTOR_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/assert.h"
|
||||||
|
#include "../core/defs.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Core
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::PodVector<T>]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Template used to store and manage array of POD data.
|
||||||
|
//!
|
||||||
|
//! This template has these adventages over other vector<> templates:
|
||||||
|
//! - Non-copyable (designed to be non-copyable, we want it)
|
||||||
|
//! - No copy-on-write (some implementations of stl can use it)
|
||||||
|
//! - Optimized for working only with POD types
|
||||||
|
//! - Uses ASMJIT_... memory management macros
|
||||||
|
template <typename T>
|
||||||
|
struct PodVector
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(PodVector<T>)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create new instance of PodVector template. Data will not
|
||||||
|
//! be allocated (will be NULL).
|
||||||
|
inline PodVector() :
|
||||||
|
_data(NULL),
|
||||||
|
_length(0),
|
||||||
|
_capacity(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Destroy PodVector and free all data.
|
||||||
|
inline ~PodVector()
|
||||||
|
{
|
||||||
|
if (_data != NULL)
|
||||||
|
ASMJIT_FREE(_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Data]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get data.
|
||||||
|
inline T* getData() { return _data; }
|
||||||
|
//! @overload
|
||||||
|
inline const T* getData() const { return _data; }
|
||||||
|
|
||||||
|
//! @brief Get length.
|
||||||
|
inline size_t getLength() const { return _length; }
|
||||||
|
//! @brief Get capacity.
|
||||||
|
inline size_t getCapacity() const { return _capacity; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Manipulation]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Clear vector data, but not free internal buffer.
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Clear vector data and free internal buffer.
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
if (_data != NULL)
|
||||||
|
{
|
||||||
|
ASMJIT_FREE(_data);
|
||||||
|
_data = 0;
|
||||||
|
_length = 0;
|
||||||
|
_capacity = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Prepend @a item to vector.
|
||||||
|
bool prepend(const T& item)
|
||||||
|
{
|
||||||
|
if (_length == _capacity && !_grow()) return false;
|
||||||
|
|
||||||
|
memmove(_data + 1, _data, sizeof(T) * _length);
|
||||||
|
memcpy(_data, &item, sizeof(T));
|
||||||
|
|
||||||
|
_length++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Insert an @a item at the @a index.
|
||||||
|
bool insert(size_t index, const T& item)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(index <= _length);
|
||||||
|
if (_length == _capacity && !_grow()) return false;
|
||||||
|
|
||||||
|
T* dst = _data + index;
|
||||||
|
memmove(dst + 1, dst, _length - index);
|
||||||
|
memcpy(dst, &item, sizeof(T));
|
||||||
|
|
||||||
|
_length++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Append @a item to vector.
|
||||||
|
bool append(const T& item)
|
||||||
|
{
|
||||||
|
if (_length == _capacity && !_grow()) return false;
|
||||||
|
|
||||||
|
memcpy(_data + _length, &item, sizeof(T));
|
||||||
|
|
||||||
|
_length++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Get index of @a val or kInvalidSize if not found.
|
||||||
|
size_t indexOf(const T& val) const
|
||||||
|
{
|
||||||
|
size_t i = 0, len = _length;
|
||||||
|
for (i = 0; i < len; i++) { if (_data[i] == val) return i; }
|
||||||
|
return kInvalidSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Remove element at index @a i.
|
||||||
|
void removeAt(size_t i)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(i < _length);
|
||||||
|
|
||||||
|
T* dst = _data + i;
|
||||||
|
_length--;
|
||||||
|
memmove(dst, dst + 1, _length - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Swap this pod-vector with @a other.
|
||||||
|
void swap(PodVector<T>& other)
|
||||||
|
{
|
||||||
|
T* _tmp_data = _data;
|
||||||
|
size_t _tmp_length = _length;
|
||||||
|
size_t _tmp_capacity = _capacity;
|
||||||
|
|
||||||
|
_data = other._data;
|
||||||
|
_length = other._length;
|
||||||
|
_capacity = other._capacity;
|
||||||
|
|
||||||
|
other._data = _tmp_data;
|
||||||
|
other._length = _tmp_length;
|
||||||
|
other._capacity = _tmp_capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Get item at position @a i.
|
||||||
|
inline T& operator[](size_t i)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(i < _length);
|
||||||
|
return _data[i];
|
||||||
|
}
|
||||||
|
//! @brief Get item at position @a i.
|
||||||
|
inline const T& operator[](size_t i) const
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(i < _length);
|
||||||
|
return _data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Append the item and return address so it can be initialized.
|
||||||
|
T* newItem()
|
||||||
|
{
|
||||||
|
if (_length == _capacity && !_grow()) return NULL;
|
||||||
|
return _data + (_length++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Private]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Called to grow internal array.
|
||||||
|
bool _grow()
|
||||||
|
{
|
||||||
|
return _realloc(_capacity < 16 ? 16 : _capacity * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Realloc internal array to fit @a to items.
|
||||||
|
bool _realloc(size_t to)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(to >= _length);
|
||||||
|
|
||||||
|
T* p = reinterpret_cast<T*>(_data ? ASMJIT_REALLOC(_data, to * sizeof(T)) : ASMJIT_MALLOC(to * sizeof(T)));
|
||||||
|
|
||||||
|
if (p == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_data = p;
|
||||||
|
_capacity = to;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Items data.
|
||||||
|
T* _data;
|
||||||
|
//! @brief Length of buffer (count of items in array).
|
||||||
|
size_t _length;
|
||||||
|
//! @brief Capacity of buffer (maximum items that can fit to current array).
|
||||||
|
size_t _capacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
#endif // _ASMJIT_CORE_PODVECTOR_H
|
|
@ -0,0 +1,401 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/defs.h"
|
||||||
|
#include "../core/intutil.h"
|
||||||
|
#include "../core/stringbuilder.h"
|
||||||
|
|
||||||
|
// [Dependencies - C]
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// Should be placed in read-only memory.
|
||||||
|
static const char StringBuilder_empty[4] = { 0 };
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::StringBuilder - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
StringBuilder::StringBuilder() :
|
||||||
|
_data(const_cast<char*>(StringBuilder_empty)),
|
||||||
|
_length(0),
|
||||||
|
_capacity(0),
|
||||||
|
_canFree(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder::~StringBuilder()
|
||||||
|
{
|
||||||
|
if (_canFree)
|
||||||
|
ASMJIT_FREE(_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::StringBuilder - Prepare / Reserve]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
char* StringBuilder::prepare(uint32_t op, size_t len)
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Set]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if (op == kStringBuilderOpSet)
|
||||||
|
{
|
||||||
|
// We don't care here, but we can't return a NULL pointer since it indicates
|
||||||
|
// failure in memory allocation.
|
||||||
|
if (len == 0)
|
||||||
|
{
|
||||||
|
if (_data != StringBuilder_empty)
|
||||||
|
_data[0] = 0;
|
||||||
|
|
||||||
|
_length = 0;
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_capacity < len)
|
||||||
|
{
|
||||||
|
if (len >= IntUtil::maxValue<size_t>() - sizeof(uintptr_t) * 2)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
size_t to = IntUtil::align<size_t>(len, sizeof(uintptr_t));
|
||||||
|
if (to < 256 - sizeof(uintptr_t))
|
||||||
|
to = 256 - sizeof(uintptr_t);
|
||||||
|
|
||||||
|
char* newData = static_cast<char*>(ASMJIT_MALLOC(to + sizeof(uintptr_t)));
|
||||||
|
if (newData == NULL)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_canFree)
|
||||||
|
ASMJIT_FREE(_data);
|
||||||
|
|
||||||
|
_data = newData;
|
||||||
|
_capacity = to + sizeof(uintptr_t) - 1;
|
||||||
|
_canFree = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_data[len] = 0;
|
||||||
|
_length = len;
|
||||||
|
|
||||||
|
ASMJIT_ASSERT(_length <= _capacity);
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Append]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We don't care here, but we can't return a NULL pointer since it indicates
|
||||||
|
// failure in memory allocation.
|
||||||
|
if (len == 0)
|
||||||
|
return _data + _length;
|
||||||
|
|
||||||
|
// Overflow.
|
||||||
|
if (IntUtil::maxValue<size_t>() - sizeof(uintptr_t) * 2 - _length < len)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
size_t after = _length + len;
|
||||||
|
if (_capacity < after)
|
||||||
|
{
|
||||||
|
size_t to = _capacity;
|
||||||
|
|
||||||
|
if (to < 256)
|
||||||
|
to = 256;
|
||||||
|
|
||||||
|
while (to < 1024 * 1024 && to < after)
|
||||||
|
{
|
||||||
|
to *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to < after)
|
||||||
|
{
|
||||||
|
to = after;
|
||||||
|
if (to < (IntUtil::maxValue<size_t>() - 1024 * 32))
|
||||||
|
to = IntUtil::align<size_t>(to, 1024 * 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
to = IntUtil::align<size_t>(to, sizeof(uintptr_t));
|
||||||
|
char* newData = static_cast<char*>(ASMJIT_MALLOC(to + sizeof(uintptr_t)));
|
||||||
|
|
||||||
|
if (newData == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
::memcpy(newData, _data, _length);
|
||||||
|
|
||||||
|
if (_canFree)
|
||||||
|
ASMJIT_FREE(_data);
|
||||||
|
|
||||||
|
_data = newData;
|
||||||
|
_capacity = to + sizeof(uintptr_t) - 1;
|
||||||
|
_canFree = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ret = _data + _length;
|
||||||
|
_data[after] = 0;
|
||||||
|
_length = after;
|
||||||
|
|
||||||
|
ASMJIT_ASSERT(_length <= _capacity);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StringBuilder::reserve(size_t to)
|
||||||
|
{
|
||||||
|
if (_capacity >= to)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (to >= IntUtil::maxValue<size_t>() - sizeof(uintptr_t) * 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
to = IntUtil::align<size_t>(to, sizeof(uintptr_t));
|
||||||
|
|
||||||
|
char* newData = static_cast<char*>(ASMJIT_MALLOC(to + sizeof(uintptr_t)));
|
||||||
|
if (newData == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
::memcpy(newData, _data, _length + 1);
|
||||||
|
if (_canFree)
|
||||||
|
ASMJIT_FREE(_data);
|
||||||
|
|
||||||
|
_data = newData;
|
||||||
|
_capacity = to + sizeof(uintptr_t) - 1;
|
||||||
|
_canFree = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::StringBuilder - Clear]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void StringBuilder::clear()
|
||||||
|
{
|
||||||
|
if (_data != StringBuilder_empty)
|
||||||
|
_data[0] = 0;
|
||||||
|
_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::StringBuilder - Methods]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
bool StringBuilder::_opString(uint32_t op, const char* str, size_t len)
|
||||||
|
{
|
||||||
|
if (len == kInvalidSize)
|
||||||
|
len = ::strlen(str);
|
||||||
|
|
||||||
|
char* p = prepare(op, len);
|
||||||
|
if (p == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
::memcpy(p, str, len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StringBuilder::_opChars(uint32_t op, char c, size_t len)
|
||||||
|
{
|
||||||
|
char* p = prepare(op, len);
|
||||||
|
if (p == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
::memset(p, c, len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char StringBuilder_numbers[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
bool StringBuilder::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, uint32_t flags)
|
||||||
|
{
|
||||||
|
if (base < 2 || base > 36)
|
||||||
|
base = 10;
|
||||||
|
|
||||||
|
char buf[128];
|
||||||
|
char* p = buf + ASMJIT_ARRAY_SIZE(buf);
|
||||||
|
|
||||||
|
uint64_t orig = i;
|
||||||
|
char sign = '\0';
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Sign]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if ((flags & kStringBuilderNumSigned) != 0 && static_cast<int64_t>(i) < 0)
|
||||||
|
{
|
||||||
|
i = static_cast<uint64_t>(-static_cast<int64_t>(i));
|
||||||
|
sign = '-';
|
||||||
|
}
|
||||||
|
else if ((flags & kStringBuilderNumShowSign) != 0)
|
||||||
|
{
|
||||||
|
sign = '+';
|
||||||
|
}
|
||||||
|
else if ((flags & kStringBuilderNumShowSpace) != 0)
|
||||||
|
{
|
||||||
|
sign = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Number]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
do {
|
||||||
|
uint64_t d = i / base;
|
||||||
|
uint64_t r = i % base;
|
||||||
|
|
||||||
|
*--p = StringBuilder_numbers[r];
|
||||||
|
i = d;
|
||||||
|
} while (i);
|
||||||
|
|
||||||
|
size_t numberLength = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Alternate Form]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if ((flags & kStringBuilderNumAlternate) != 0)
|
||||||
|
{
|
||||||
|
if (base == 8)
|
||||||
|
{
|
||||||
|
if (orig != 0)
|
||||||
|
*--p = '0';
|
||||||
|
}
|
||||||
|
if (base == 16)
|
||||||
|
{
|
||||||
|
*--p = 'x';
|
||||||
|
*--p = '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Width]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if (sign != 0)
|
||||||
|
*--p = sign;
|
||||||
|
|
||||||
|
if (width > 256)
|
||||||
|
width = 256;
|
||||||
|
|
||||||
|
if (width <= numberLength)
|
||||||
|
width = 0;
|
||||||
|
else
|
||||||
|
width -= numberLength;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// Write]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
size_t prefixLength = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p) - numberLength;
|
||||||
|
char* data = prepare(op, prefixLength + width + numberLength);
|
||||||
|
|
||||||
|
if (data == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
::memcpy(data, p, prefixLength);
|
||||||
|
data += prefixLength;
|
||||||
|
|
||||||
|
::memset(data, '0', width);
|
||||||
|
data += width;
|
||||||
|
|
||||||
|
::memcpy(data, p + prefixLength, numberLength);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StringBuilder::_opHex(uint32_t op, const void* data, size_t len)
|
||||||
|
{
|
||||||
|
if (len >= IntUtil::maxValue<size_t>() / 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char* dst = prepare(op, len);
|
||||||
|
if (dst == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const char* src = static_cast<const char*>(data);
|
||||||
|
for (size_t i = 0; i < len; i++, dst += 2, src += 1)
|
||||||
|
{
|
||||||
|
dst[0] = StringBuilder_numbers[(src[0] >> 4) & 0xF];
|
||||||
|
dst[1] = StringBuilder_numbers[(src[0] ) & 0xF];
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StringBuilder::_opVFormat(uint32_t op, const char* fmt, va_list ap)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap);
|
||||||
|
buf[ASMJIT_ARRAY_SIZE(buf) - 1] = '\0';
|
||||||
|
|
||||||
|
return _opString(op, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StringBuilder::setFormat(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
result = _opVFormat(kStringBuilderOpSet, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StringBuilder::appendFormat(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
result = _opVFormat(kStringBuilderOpAppend, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StringBuilder::eq(const char* str, size_t len) const
|
||||||
|
{
|
||||||
|
const char* aData = _data;
|
||||||
|
const char* bData = str;
|
||||||
|
|
||||||
|
size_t aLength = _length;
|
||||||
|
size_t bLength = len;
|
||||||
|
|
||||||
|
if (bLength == kInvalidSize)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < aLength; i++)
|
||||||
|
{
|
||||||
|
if (aData[i] != bData[i] || bData[i] == 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bData[i] == 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (aLength != bLength)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ::memcmp(aData, bData, aLength) == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,197 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_STRINGBUILDER_H
|
||||||
|
#define _ASMJIT_CORE_STRINGBUILDER_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/assert.h"
|
||||||
|
#include "../core/defs.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Core
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::StringBuilder]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief String builder.
|
||||||
|
//!
|
||||||
|
//! String builder was designed to be able to build a string using append like
|
||||||
|
//! operation to append numbers, other strings, or signle characters. It can
|
||||||
|
//! allocate it's own buffer or use a buffer created on the stack.
|
||||||
|
//!
|
||||||
|
//! String builder contains method specific to AsmJit functionality, used for
|
||||||
|
//! logging or HTML output.
|
||||||
|
struct StringBuilder
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(StringBuilder)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API StringBuilder();
|
||||||
|
ASMJIT_API ~StringBuilder();
|
||||||
|
|
||||||
|
inline StringBuilder(const _DontInitialize&) {}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get string builder capacity.
|
||||||
|
inline size_t getCapacity() const
|
||||||
|
{ return _capacity; }
|
||||||
|
|
||||||
|
//! @brief Get length.
|
||||||
|
inline size_t getLength() const
|
||||||
|
{ return _length; }
|
||||||
|
|
||||||
|
//! @brief Get null-terminated string data.
|
||||||
|
inline char* getData()
|
||||||
|
{ return _data; }
|
||||||
|
|
||||||
|
//! @brief Get null-terminated string data (const).
|
||||||
|
inline const char* getData() const
|
||||||
|
{ return _data; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Prepare / Reserve]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Prepare to set/append.
|
||||||
|
ASMJIT_API char* prepare(uint32_t op, size_t len);
|
||||||
|
|
||||||
|
//! @brief Reserve @a to bytes in string builder.
|
||||||
|
ASMJIT_API bool reserve(size_t to);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Clear]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Clear the content in String builder.
|
||||||
|
ASMJIT_API void clear();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Methods]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API bool _opString(uint32_t op, const char* str, size_t len = kInvalidSize);
|
||||||
|
ASMJIT_API bool _opVFormat(uint32_t op, const char* fmt, va_list ap);
|
||||||
|
ASMJIT_API bool _opChars(uint32_t op, char c, size_t len);
|
||||||
|
ASMJIT_API bool _opNumber(uint32_t op, uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0);
|
||||||
|
ASMJIT_API bool _opHex(uint32_t op, const void* data, size_t length);
|
||||||
|
|
||||||
|
//! @brief Replace the current content by @a str of @a len.
|
||||||
|
inline bool setString(const char* str, size_t len = kInvalidSize)
|
||||||
|
{ return _opString(kStringBuilderOpSet, str, len); }
|
||||||
|
|
||||||
|
//! @brief Replace the current content by formatted string @a fmt.
|
||||||
|
inline bool setVFormat(const char* fmt, va_list ap)
|
||||||
|
{ return _opVFormat(kStringBuilderOpSet, fmt, ap); }
|
||||||
|
|
||||||
|
//! @brief Replace the current content by formatted string @a fmt.
|
||||||
|
ASMJIT_API bool setFormat(const char* fmt, ...);
|
||||||
|
|
||||||
|
//! @brief Replace the current content by @a c of @a len.
|
||||||
|
inline bool setChars(char c, size_t len)
|
||||||
|
{ return _opChars(kStringBuilderOpSet, c, len); }
|
||||||
|
|
||||||
|
//! @brief Replace the current content by @a i..
|
||||||
|
inline bool setNumber(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0)
|
||||||
|
{ return _opNumber(kStringBuilderOpSet, i, base, width, flags); }
|
||||||
|
|
||||||
|
//! @brief Append @a str of @a len.
|
||||||
|
inline bool appendString(const char* str, size_t len = kInvalidSize)
|
||||||
|
{ return _opString(kStringBuilderOpAppend, str, len); }
|
||||||
|
|
||||||
|
//! @brief Append a formatted string @a fmt to the current content.
|
||||||
|
inline bool appendVFormat(const char* fmt, va_list ap)
|
||||||
|
{ return _opVFormat(kStringBuilderOpAppend, fmt, ap); }
|
||||||
|
|
||||||
|
//! @brief Append a formatted string @a fmt to the current content.
|
||||||
|
ASMJIT_API bool appendFormat(const char* fmt, ...);
|
||||||
|
|
||||||
|
//! @brief Append @a c of @a len.
|
||||||
|
inline bool appendChars(char c, size_t len)
|
||||||
|
{ return _opChars(kStringBuilderOpAppend, c, len); }
|
||||||
|
|
||||||
|
//! @brief Append @a i.
|
||||||
|
inline bool appendNumber(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0)
|
||||||
|
{ return _opNumber(kStringBuilderOpAppend, i, base, width, flags); }
|
||||||
|
|
||||||
|
//! @brief Check for equality with other @a str.
|
||||||
|
ASMJIT_API bool eq(const char* str, size_t len = kInvalidSize) const;
|
||||||
|
|
||||||
|
//! @brief Check for equality with StringBuilder @a other.
|
||||||
|
inline bool eq(const StringBuilder& other) const
|
||||||
|
{ return eq(other._data); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Operator Overload]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline bool operator==(const StringBuilder& other) const { return eq(other); }
|
||||||
|
inline bool operator!=(const StringBuilder& other) const { return !eq(other); }
|
||||||
|
|
||||||
|
inline bool operator==(const char* str) const { return eq(str); }
|
||||||
|
inline bool operator!=(const char* str) const { return !eq(str); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief String data.
|
||||||
|
char* _data;
|
||||||
|
//! @brief Length.
|
||||||
|
size_t _length;
|
||||||
|
//! @brief Capacity.
|
||||||
|
size_t _capacity;
|
||||||
|
//! @brief Whether the string can be freed.
|
||||||
|
size_t _canFree;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::StringBuilderT]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
template<size_t N>
|
||||||
|
struct StringBuilderT : public StringBuilder
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(StringBuilderT<N>)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline StringBuilderT() :
|
||||||
|
StringBuilder(_DontInitialize())
|
||||||
|
{
|
||||||
|
_data = _embeddedData;
|
||||||
|
_data[0] = 0;
|
||||||
|
|
||||||
|
_length = 0;
|
||||||
|
_capacity = 0;
|
||||||
|
_canFree = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Embedded data.
|
||||||
|
char _embeddedData[(N + sizeof(uintptr_t)) & ~(sizeof(uintptr_t) - 1)];
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
#endif // _ASMJIT_CORE_STRINGBUILDER_H
|
|
@ -0,0 +1,90 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/assert.h"
|
||||||
|
#include "../core/stringutil.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::StringUtil]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
static const char letters[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
char* StringUtil::copy(char* dst, const char* src, size_t len)
|
||||||
|
{
|
||||||
|
if (src == NULL)
|
||||||
|
return dst;
|
||||||
|
|
||||||
|
if (len == kInvalidSize)
|
||||||
|
{
|
||||||
|
while (*src) *dst++ = *src++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(dst, src, len);
|
||||||
|
dst += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* StringUtil::fill(char* dst, const int c, size_t len)
|
||||||
|
{
|
||||||
|
memset(dst, c, len);
|
||||||
|
return dst + len;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* StringUtil::hex(char* dst, const uint8_t* src, size_t len)
|
||||||
|
{
|
||||||
|
for (size_t i = len; i; i--, dst += 2, src += 1)
|
||||||
|
{
|
||||||
|
dst[0] = letters[(src[0] >> 4) & 0xF];
|
||||||
|
dst[1] = letters[(src[0] ) & 0xF];
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not too efficient, but this is mainly for debugging:)
|
||||||
|
char* StringUtil::utoa(char* dst, uintptr_t i, size_t base)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(base <= 16);
|
||||||
|
|
||||||
|
char buf[128];
|
||||||
|
char* p = buf + 128;
|
||||||
|
|
||||||
|
do {
|
||||||
|
uintptr_t b = i % base;
|
||||||
|
*--p = letters[b];
|
||||||
|
i /= base;
|
||||||
|
} while (i);
|
||||||
|
|
||||||
|
return StringUtil::copy(dst, p, (size_t)(buf + 128 - p));
|
||||||
|
}
|
||||||
|
|
||||||
|
char* StringUtil::itoa(char* dst, intptr_t i, size_t base)
|
||||||
|
{
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
*dst++ = '-';
|
||||||
|
i = -i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringUtil::utoa(dst, (size_t)i, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,43 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_STRINGUTIL_H
|
||||||
|
#define _ASMJIT_CORE_STRINGUTIL_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/defs.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Core
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::StringUtil]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief String utilities.
|
||||||
|
struct StringUtil
|
||||||
|
{
|
||||||
|
ASMJIT_API static char* copy(char* dst, const char* src, size_t len = kInvalidSize);
|
||||||
|
ASMJIT_API static char* fill(char* dst, const int c, size_t len);
|
||||||
|
ASMJIT_API static char* hex(char* dst, const uint8_t* src, size_t len);
|
||||||
|
|
||||||
|
ASMJIT_API static char* utoa(char* dst, uintptr_t i, size_t base = 10);
|
||||||
|
ASMJIT_API static char* itoa(char* dst, intptr_t i, size_t base = 10);
|
||||||
|
|
||||||
|
static inline void memset32(uint32_t* p, uint32_t c, size_t len)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < len; i++) p[i] = c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
#endif // _ASMJIT_CORE_STRINGUTIL_H
|
|
@ -0,0 +1,173 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/intutil.h"
|
||||||
|
#include "../core/virtualmemory.h"
|
||||||
|
|
||||||
|
// [Dependencies - Windows]
|
||||||
|
#if defined(ASMJIT_WINDOWS)
|
||||||
|
# include <windows.h>
|
||||||
|
#endif // ASMJIT_WINDOWS
|
||||||
|
|
||||||
|
// [Dependencies - Posix]
|
||||||
|
#if defined(ASMJIT_POSIX)
|
||||||
|
# include <sys/types.h>
|
||||||
|
# include <sys/mman.h>
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif // ASMJIT_POSIX
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::VirtualMemory - Windows]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
#if defined(ASMJIT_WINDOWS)
|
||||||
|
struct VirtualMemoryLocal
|
||||||
|
{
|
||||||
|
VirtualMemoryLocal()
|
||||||
|
|
||||||
|
{
|
||||||
|
SYSTEM_INFO info;
|
||||||
|
GetSystemInfo(&info);
|
||||||
|
|
||||||
|
alignment = info.dwAllocationGranularity;
|
||||||
|
pageSize = IntUtil::roundUpToPowerOf2<uint32_t>(info.dwPageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t alignment;
|
||||||
|
size_t pageSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
static VirtualMemoryLocal& vm()
|
||||||
|
|
||||||
|
{
|
||||||
|
static VirtualMemoryLocal vm;
|
||||||
|
return vm;
|
||||||
|
};
|
||||||
|
|
||||||
|
void* VirtualMemory::alloc(size_t length, size_t* allocated, bool canExecute)
|
||||||
|
|
||||||
|
{
|
||||||
|
return allocProcessMemory(GetCurrentProcess(), length, allocated, canExecute);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMemory::free(void* addr, size_t length)
|
||||||
|
|
||||||
|
{
|
||||||
|
return freeProcessMemory(GetCurrentProcess(), addr, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* VirtualMemory::allocProcessMemory(HANDLE hProcess, size_t length, size_t* allocated, bool canExecute)
|
||||||
|
|
||||||
|
{
|
||||||
|
// VirtualAlloc rounds allocated size to page size automatically.
|
||||||
|
size_t msize = IntUtil::roundUp(length, vm().pageSize);
|
||||||
|
|
||||||
|
// Windows XP SP2 / Vista allow Data Excution Prevention (DEP).
|
||||||
|
WORD protect = canExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
|
||||||
|
LPVOID mbase = VirtualAllocEx(hProcess, NULL, msize, MEM_COMMIT | MEM_RESERVE, protect);
|
||||||
|
if (mbase == NULL) return NULL;
|
||||||
|
|
||||||
|
ASMJIT_ASSERT(IntUtil::isAligned<size_t>(reinterpret_cast<size_t>(mbase), vm().alignment));
|
||||||
|
|
||||||
|
if (allocated != NULL)
|
||||||
|
*allocated = msize;
|
||||||
|
return mbase;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMemory::freeProcessMemory(HANDLE hProcess, void* addr, size_t /* length */)
|
||||||
|
|
||||||
|
{
|
||||||
|
VirtualFreeEx(hProcess, addr, 0, MEM_RELEASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t VirtualMemory::getAlignment()
|
||||||
|
|
||||||
|
{
|
||||||
|
return vm().alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t VirtualMemory::getPageSize()
|
||||||
|
|
||||||
|
{
|
||||||
|
return vm().pageSize;
|
||||||
|
}
|
||||||
|
#endif // ASMJIT_WINDOWS
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::VirtualMemory - Posix]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
#if defined(ASMJIT_POSIX)
|
||||||
|
|
||||||
|
// MacOS uses MAP_ANON instead of MAP_ANONYMOUS.
|
||||||
|
#if !defined(MAP_ANONYMOUS)
|
||||||
|
# define MAP_ANONYMOUS MAP_ANON
|
||||||
|
#endif // MAP_ANONYMOUS
|
||||||
|
|
||||||
|
struct VirtualMemoryLocal
|
||||||
|
{
|
||||||
|
VirtualMemoryLocal()
|
||||||
|
{
|
||||||
|
alignment = pageSize = ::getpagesize();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t alignment;
|
||||||
|
size_t pageSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
static VirtualMemoryLocal& vm()
|
||||||
|
|
||||||
|
{
|
||||||
|
static VirtualMemoryLocal vm;
|
||||||
|
return vm;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* VirtualMemory::alloc(size_t length, size_t* allocated, bool canExecute)
|
||||||
|
|
||||||
|
{
|
||||||
|
size_t msize = IntUtil::roundUp<size_t>(length, vm().pageSize);
|
||||||
|
int protection = PROT_READ | PROT_WRITE | (canExecute ? PROT_EXEC : 0);
|
||||||
|
|
||||||
|
void* mbase = ::mmap(NULL, msize, protection, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
|
if (mbase == MAP_FAILED)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (allocated != NULL)
|
||||||
|
*allocated = msize;
|
||||||
|
return mbase;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMemory::free(void* addr, size_t length)
|
||||||
|
|
||||||
|
{
|
||||||
|
munmap(addr, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t VirtualMemory::getAlignment()
|
||||||
|
|
||||||
|
{
|
||||||
|
return vm().alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t VirtualMemory::getPageSize()
|
||||||
|
|
||||||
|
{
|
||||||
|
return vm().pageSize;
|
||||||
|
}
|
||||||
|
#endif // ASMJIT_POSIX
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,80 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_VIRTUALMEMORY_H
|
||||||
|
#define _ASMJIT_CORE_VIRTUALMEMORY_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/build.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Core
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::VirtualMemory]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Class that helps with allocating memory for executing code
|
||||||
|
//! generated by JIT compiler.
|
||||||
|
//!
|
||||||
|
//! There are defined functions that provides facility to allocate and free
|
||||||
|
//! memory where can be executed code. If processor and operating system
|
||||||
|
//! supports execution protection then you can't run code from normally
|
||||||
|
//! malloc()'ed memory.
|
||||||
|
//!
|
||||||
|
//! Functions are internally implemented by operating system dependent way.
|
||||||
|
//! VirtualAlloc() function is used for Windows operating system and mmap()
|
||||||
|
//! for posix ones. If you want to study or create your own functions, look
|
||||||
|
//! at VirtualAlloc() or mmap() documentation (depends on you target OS).
|
||||||
|
//!
|
||||||
|
//! Under posix operating systems is also useable mprotect() function, that
|
||||||
|
//! can enable execution protection to malloc()'ed memory block.
|
||||||
|
struct VirtualMemory
|
||||||
|
{
|
||||||
|
//! @brief Allocate virtual memory.
|
||||||
|
//!
|
||||||
|
//! Pages are readable/writeable, but they are not guaranteed to be
|
||||||
|
//! executable unless 'canExecute' is true. Returns the address of
|
||||||
|
//! allocated memory, or NULL if failed.
|
||||||
|
ASMJIT_API static void* alloc(size_t length, size_t* allocated, bool canExecute);
|
||||||
|
|
||||||
|
//! @brief Free memory allocated by @c alloc()
|
||||||
|
ASMJIT_API static void free(void* addr, size_t length);
|
||||||
|
|
||||||
|
#if defined(ASMJIT_WINDOWS)
|
||||||
|
//! @brief Allocate virtual memory of @a hProcess.
|
||||||
|
//!
|
||||||
|
//! @note This function is Windows specific.
|
||||||
|
ASMJIT_API static void* allocProcessMemory(HANDLE hProcess, size_t length, size_t* allocated, bool canExecute);
|
||||||
|
|
||||||
|
//! @brief Free virtual memory of @a hProcess.
|
||||||
|
//!
|
||||||
|
//! @note This function is Windows specific.
|
||||||
|
ASMJIT_API static void freeProcessMemory(HANDLE hProcess, void* addr, size_t length);
|
||||||
|
#endif // ASMJIT_WINDOWS
|
||||||
|
|
||||||
|
//! @brief Get the alignment guaranteed by alloc().
|
||||||
|
ASMJIT_API static size_t getAlignment();
|
||||||
|
|
||||||
|
//! @brief Get size of single page.
|
||||||
|
ASMJIT_API static size_t getPageSize();
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_CORE_VIRTUALMEMORY_H
|
|
@ -0,0 +1,126 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/defs.h"
|
||||||
|
#include "../core/intutil.h"
|
||||||
|
#include "../core/zonememory.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::ZoneMemory]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
ZoneMemory::ZoneMemory(size_t chunkSize)
|
||||||
|
{
|
||||||
|
_chunks = NULL;
|
||||||
|
_total = 0;
|
||||||
|
_chunkSize = chunkSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneMemory::~ZoneMemory()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ZoneMemory::alloc(size_t size)
|
||||||
|
{
|
||||||
|
ZoneChunk* cur = _chunks;
|
||||||
|
|
||||||
|
// Align to 4 or 8 bytes.
|
||||||
|
size = IntUtil::align<size_t>(size, sizeof(size_t));
|
||||||
|
|
||||||
|
if (cur == NULL || cur->getRemainingBytes() < size)
|
||||||
|
{
|
||||||
|
size_t chSize = _chunkSize;
|
||||||
|
|
||||||
|
if (chSize < size)
|
||||||
|
chSize = size;
|
||||||
|
|
||||||
|
cur = (ZoneChunk*)ASMJIT_MALLOC(sizeof(ZoneChunk) - sizeof(void*) + chSize);
|
||||||
|
if (cur == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cur->prev = _chunks;
|
||||||
|
cur->pos = 0;
|
||||||
|
cur->size = chSize;
|
||||||
|
|
||||||
|
_chunks = cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* p = cur->data + cur->pos;
|
||||||
|
cur->pos += size;
|
||||||
|
_total += size;
|
||||||
|
|
||||||
|
ASMJIT_ASSERT(cur->pos <= cur->size);
|
||||||
|
return (void*)p;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ZoneMemory::sdup(const char* str)
|
||||||
|
{
|
||||||
|
if (str == NULL) return NULL;
|
||||||
|
|
||||||
|
size_t len = strlen(str);
|
||||||
|
if (len == 0) return NULL;
|
||||||
|
|
||||||
|
// Include NULL terminator and limit string length.
|
||||||
|
if (++len > 256)
|
||||||
|
len = 256;
|
||||||
|
|
||||||
|
char* m = reinterpret_cast<char*>(alloc(IntUtil::align<size_t>(len, 16)));
|
||||||
|
if (m == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memcpy(m, str, len);
|
||||||
|
m[len - 1] = '\0';
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneMemory::clear()
|
||||||
|
{
|
||||||
|
ZoneChunk* cur = _chunks;
|
||||||
|
|
||||||
|
if (cur == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cur = cur->prev;
|
||||||
|
while (cur != NULL)
|
||||||
|
{
|
||||||
|
ZoneChunk* prev = cur->prev;
|
||||||
|
ASMJIT_FREE(cur);
|
||||||
|
cur = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
_chunks->pos = 0;
|
||||||
|
_chunks->prev = NULL;
|
||||||
|
_total = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneMemory::reset()
|
||||||
|
{
|
||||||
|
ZoneChunk* cur = _chunks;
|
||||||
|
|
||||||
|
_chunks = NULL;
|
||||||
|
_total = 0;
|
||||||
|
|
||||||
|
while (cur != NULL)
|
||||||
|
{
|
||||||
|
ZoneChunk* prev = cur->prev;
|
||||||
|
ASMJIT_FREE(cur);
|
||||||
|
cur = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,151 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_CORE_ZONEMEMORY_H
|
||||||
|
#define _ASMJIT_CORE_ZONEMEMORY_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/build.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_Core
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::ZoneChunk]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief One allocated chunk of memory.
|
||||||
|
struct ZoneChunk
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Methods]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get count of remaining (unused) bytes in chunk.
|
||||||
|
inline size_t getRemainingBytes() const { return size - pos; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Link to previous chunk.
|
||||||
|
ZoneChunk* prev;
|
||||||
|
//! @brief Position in this chunk.
|
||||||
|
size_t pos;
|
||||||
|
//! @brief Size of this chunk (in bytes).
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
//! @brief Data.
|
||||||
|
uint8_t data[sizeof(void*)];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::ZoneMemory]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Memory allocator designed to fast alloc memory that will be freed
|
||||||
|
//! in one step.
|
||||||
|
//!
|
||||||
|
//! @note This is hackery for performance. Concept is that objects created
|
||||||
|
//! by @c ZoneMemory are freed all at once. This means that lifetime of
|
||||||
|
//! these objects are the same as the zone object itself.
|
||||||
|
struct ZoneMemory
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create new instance of @c ZoneMemory.
|
||||||
|
//! @param chunkSize Default size for one zone chunk.
|
||||||
|
ASMJIT_API ZoneMemory(size_t chunkSize);
|
||||||
|
|
||||||
|
//! @brief Destroy @ref ZoneMemory instance.
|
||||||
|
ASMJIT_API ~ZoneMemory();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Methods]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Allocate @c size bytes of memory and return pointer to it.
|
||||||
|
//!
|
||||||
|
//! Pointer allocated by this way will be valid until @c ZoneMemory object
|
||||||
|
//! is destroyed. To create class by this way use placement @c new and
|
||||||
|
//! @c delete operators:
|
||||||
|
//!
|
||||||
|
//! @code
|
||||||
|
//! // Example of allocating simple class
|
||||||
|
//!
|
||||||
|
//! // Your class
|
||||||
|
//! class Object
|
||||||
|
//! {
|
||||||
|
//! // members...
|
||||||
|
//! };
|
||||||
|
//!
|
||||||
|
//! // Your function
|
||||||
|
//! void f()
|
||||||
|
//! {
|
||||||
|
//! // We are using AsmJit namespace
|
||||||
|
//! using namespace AsmJit
|
||||||
|
//!
|
||||||
|
//! // Create zone object with chunk size of 65536 bytes.
|
||||||
|
//! ZoneMemory zone(65536);
|
||||||
|
//!
|
||||||
|
//! // Create your objects using zone object allocating, for example:
|
||||||
|
//! Object* obj = new(zone.alloc(sizeof(YourClass))) Object();
|
||||||
|
//!
|
||||||
|
//! // ... lifetime of your objects ...
|
||||||
|
//!
|
||||||
|
//! // Destroy your objects:
|
||||||
|
//! obj->~Object();
|
||||||
|
//!
|
||||||
|
//! // ZoneMemory destructor will free all memory allocated through it,
|
||||||
|
//! // alternative is to call @c zone.reset().
|
||||||
|
//! }
|
||||||
|
//! @endcode
|
||||||
|
ASMJIT_API void* alloc(size_t size);
|
||||||
|
|
||||||
|
//! @brief Helper to duplicate string.
|
||||||
|
ASMJIT_API char* sdup(const char* str);
|
||||||
|
|
||||||
|
//! @brief Free all allocated memory except first block that remains for reuse.
|
||||||
|
//!
|
||||||
|
//! Note that this method will invalidate all instances using this memory
|
||||||
|
//! allocated by this zone instance.
|
||||||
|
ASMJIT_API void clear();
|
||||||
|
|
||||||
|
//! @brief Free all allocated memory at once.
|
||||||
|
//!
|
||||||
|
//! Note that this method will invalidate all instances using this memory
|
||||||
|
//! allocated by this zone instance.
|
||||||
|
ASMJIT_API void reset();
|
||||||
|
|
||||||
|
//! @brief Get total size of allocated objects - by @c alloc().
|
||||||
|
inline size_t getTotal() const { return _total; }
|
||||||
|
//! @brief Get (default) chunk size.
|
||||||
|
inline size_t getChunkSize() const { return _chunkSize; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Last allocated chunk of memory.
|
||||||
|
ZoneChunk* _chunks;
|
||||||
|
//! @brief Total size of allocated objects - by @c alloc() method.
|
||||||
|
size_t _total;
|
||||||
|
//! @brief One chunk size.
|
||||||
|
size_t _chunkSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
#endif // _ASMJIT_CORE_ZONEMEMORY_H
|
|
@ -0,0 +1,26 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_X86_H
|
||||||
|
#define _ASMJIT_X86_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
#include "x86/x86assembler.h"
|
||||||
|
#include "x86/x86compiler.h"
|
||||||
|
#include "x86/x86compilercontext.h"
|
||||||
|
#include "x86/x86compilerfunc.h"
|
||||||
|
#include "x86/x86compileritem.h"
|
||||||
|
#include "x86/x86cpuinfo.h"
|
||||||
|
#include "x86/x86defs.h"
|
||||||
|
#include "x86/x86func.h"
|
||||||
|
#include "x86/x86operand.h"
|
||||||
|
#include "x86/x86util.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_X86_H
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,877 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/intutil.h"
|
||||||
|
#include "../core/stringutil.h"
|
||||||
|
|
||||||
|
#include "../x86/x86assembler.h"
|
||||||
|
#include "../x86/x86compiler.h"
|
||||||
|
#include "../x86/x86compilercontext.h"
|
||||||
|
#include "../x86/x86compilerfunc.h"
|
||||||
|
#include "../x86/x86compileritem.h"
|
||||||
|
#include "../x86/x86util.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::CompilerUtil]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
bool CompilerUtil::isStack16ByteAligned()
|
||||||
|
{
|
||||||
|
// Stack is always aligned to 16-bytes when using 64-bit OS.
|
||||||
|
bool result = (sizeof(uintptr_t) == 8);
|
||||||
|
|
||||||
|
// Modern Linux, APPLE and UNIX guarantees stack alignment to 16 bytes by
|
||||||
|
// default. I'm really not sure about all UNIX operating systems, because
|
||||||
|
// 16-byte alignment is an addition to an older specification.
|
||||||
|
#if (defined(__linux__) || \
|
||||||
|
defined(__linux) || \
|
||||||
|
defined(linux) || \
|
||||||
|
defined(__unix__) || \
|
||||||
|
defined(__FreeBSD__) || \
|
||||||
|
defined(__NetBSD__) || \
|
||||||
|
defined(__OpenBSD__) || \
|
||||||
|
defined(__DARWIN__) || \
|
||||||
|
defined(__APPLE__) )
|
||||||
|
result = true;
|
||||||
|
#endif // __linux__
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86Compiler - Construction / Destruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
X86Compiler::X86Compiler(Context* context) :
|
||||||
|
Compiler(context)
|
||||||
|
{
|
||||||
|
_properties |= IntUtil::maskFromIndex(kX86PropertyOptimizedAlign);
|
||||||
|
}
|
||||||
|
|
||||||
|
X86Compiler::~X86Compiler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Function Builder]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
X86CompilerFuncDecl* X86Compiler::newFunc_(uint32_t convention, uint32_t returnType, const uint32_t* arguments, uint32_t argumentsCount)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(_func == NULL);
|
||||||
|
|
||||||
|
X86CompilerFuncDecl* func = Compiler_newItem<X86CompilerFuncDecl>(this);
|
||||||
|
|
||||||
|
_func = func;
|
||||||
|
_varNameId = 0;
|
||||||
|
|
||||||
|
func->setPrototype(convention, returnType, arguments, argumentsCount);
|
||||||
|
addItem(func);
|
||||||
|
|
||||||
|
bind(func->_entryLabel);
|
||||||
|
func->_createVariables();
|
||||||
|
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
X86CompilerFuncDecl* X86Compiler::endFunc()
|
||||||
|
{
|
||||||
|
X86CompilerFuncDecl* func = getFunc();
|
||||||
|
ASMJIT_ASSERT(func != NULL);
|
||||||
|
|
||||||
|
bind(func->_exitLabel);
|
||||||
|
addItem(func->_end);
|
||||||
|
|
||||||
|
func->setFuncFlag(kFuncFlagIsFinished);
|
||||||
|
_func = NULL;
|
||||||
|
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - EmitInstruction]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
static inline X86CompilerInst* X86Compiler_newInstruction(X86Compiler* self, uint32_t code, Operand* opData, uint32_t opCount)
|
||||||
|
{
|
||||||
|
if (code >= _kX86InstJBegin && code <= _kX86InstJEnd)
|
||||||
|
{
|
||||||
|
void* p = self->_zoneMemory.alloc(sizeof(X86CompilerJmpInst));
|
||||||
|
return new(p) X86CompilerJmpInst(self, code, opData, opCount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
void* p = self->_zoneMemory.alloc(sizeof(X86CompilerInst) + opCount * sizeof(Operand));
|
||||||
|
return new(p) X86CompilerInst(self, code, opData, opCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::_emitInstruction(uint32_t code)
|
||||||
|
{
|
||||||
|
X86CompilerInst* inst = X86Compiler_newInstruction(this, code, NULL, 0);
|
||||||
|
|
||||||
|
if (inst == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addItem(inst);
|
||||||
|
|
||||||
|
if (_cc != NULL)
|
||||||
|
{
|
||||||
|
inst->_offset = _cc->_currentOffset;
|
||||||
|
inst->prepare(*_cc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::_emitInstruction(uint32_t code, const Operand* o0)
|
||||||
|
{
|
||||||
|
Operand* operands = reinterpret_cast<Operand*>(_zoneMemory.alloc(1 * sizeof(Operand)));
|
||||||
|
|
||||||
|
if (operands == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
operands[0] = *o0;
|
||||||
|
X86CompilerInst* inst = X86Compiler_newInstruction(this, code, operands, 1);
|
||||||
|
|
||||||
|
if (inst == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addItem(inst);
|
||||||
|
|
||||||
|
if (_cc != NULL)
|
||||||
|
{
|
||||||
|
inst->_offset = _cc->_currentOffset;
|
||||||
|
inst->prepare(*_cc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::_emitInstruction(uint32_t code, const Operand* o0, const Operand* o1)
|
||||||
|
{
|
||||||
|
Operand* operands = reinterpret_cast<Operand*>(_zoneMemory.alloc(2 * sizeof(Operand)));
|
||||||
|
|
||||||
|
if (operands == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
operands[0] = *o0;
|
||||||
|
operands[1] = *o1;
|
||||||
|
X86CompilerInst* inst = X86Compiler_newInstruction(this, code, operands, 2);
|
||||||
|
|
||||||
|
if (inst == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addItem(inst);
|
||||||
|
|
||||||
|
if (_cc)
|
||||||
|
{
|
||||||
|
inst->_offset = _cc->_currentOffset;
|
||||||
|
inst->prepare(*_cc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::_emitInstruction(uint32_t code, const Operand* o0, const Operand* o1, const Operand* o2)
|
||||||
|
{
|
||||||
|
Operand* operands = reinterpret_cast<Operand*>(_zoneMemory.alloc(3 * sizeof(Operand)));
|
||||||
|
|
||||||
|
if (operands == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
operands[0] = *o0;
|
||||||
|
operands[1] = *o1;
|
||||||
|
operands[2] = *o2;
|
||||||
|
X86CompilerInst* inst = X86Compiler_newInstruction(this, code, operands, 3);
|
||||||
|
|
||||||
|
if (inst == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addItem(inst);
|
||||||
|
|
||||||
|
if (_cc != NULL)
|
||||||
|
{
|
||||||
|
inst->_offset = _cc->_currentOffset;
|
||||||
|
inst->prepare(*_cc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::_emitInstruction(uint32_t code, const Operand* o0, const Operand* o1, const Operand* o2, const Operand* o3)
|
||||||
|
{
|
||||||
|
Operand* operands = reinterpret_cast<Operand*>(_zoneMemory.alloc(4 * sizeof(Operand)));
|
||||||
|
|
||||||
|
if (operands == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
operands[0] = *o0;
|
||||||
|
operands[1] = *o1;
|
||||||
|
operands[2] = *o2;
|
||||||
|
operands[3] = *o3;
|
||||||
|
X86CompilerInst* inst = X86Compiler_newInstruction(this, code, operands, 4);
|
||||||
|
|
||||||
|
if (inst == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addItem(inst);
|
||||||
|
|
||||||
|
if (_cc != NULL)
|
||||||
|
{
|
||||||
|
inst->_offset = _cc->_currentOffset;
|
||||||
|
inst->prepare(*_cc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::_emitInstruction(uint32_t code, const Operand* o0, const Operand* o1, const Operand* o2, const Operand* o3, const Operand* o4)
|
||||||
|
{
|
||||||
|
Operand* operands = reinterpret_cast<Operand*>(_zoneMemory.alloc(5 * sizeof(Operand)));
|
||||||
|
|
||||||
|
if (operands == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
operands[0] = *o0;
|
||||||
|
operands[1] = *o1;
|
||||||
|
operands[2] = *o2;
|
||||||
|
operands[3] = *o3;
|
||||||
|
operands[4] = *o4;
|
||||||
|
X86CompilerInst* inst = X86Compiler_newInstruction(this, code, operands, 5);
|
||||||
|
|
||||||
|
if (inst == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addItem(inst);
|
||||||
|
|
||||||
|
if (_cc != NULL)
|
||||||
|
{
|
||||||
|
inst->_offset = _cc->_currentOffset;
|
||||||
|
inst->prepare(*_cc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::_emitJcc(uint32_t code, const Label* label, uint32_t hint)
|
||||||
|
{
|
||||||
|
if (hint == kCondHintNone)
|
||||||
|
{
|
||||||
|
_emitInstruction(code, label);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Imm imm(hint);
|
||||||
|
_emitInstruction(code, label, &imm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
X86CompilerFuncCall* X86Compiler::_emitCall(const Operand* o0)
|
||||||
|
{
|
||||||
|
X86CompilerFuncDecl* func = getFunc();
|
||||||
|
|
||||||
|
if (func == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoFunction);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
X86CompilerFuncCall* call = Compiler_newItem<X86CompilerFuncCall>(this, func, o0);
|
||||||
|
if (call == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
addItem(call);
|
||||||
|
return call;
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::_emitReturn(const Operand* first, const Operand* second)
|
||||||
|
{
|
||||||
|
X86CompilerFuncDecl* func = getFunc();
|
||||||
|
|
||||||
|
if (func == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoFunction);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
X86CompilerFuncRet* ret = Compiler_newItem<X86CompilerFuncRet>(this, func, first, second);
|
||||||
|
|
||||||
|
if (ret == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorNoHeapMemory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addItem(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Align]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void X86Compiler::align(uint32_t m)
|
||||||
|
{
|
||||||
|
addItem(Compiler_newItem<X86CompilerAlign>(this, m));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Label]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
Label X86Compiler::newLabel()
|
||||||
|
{
|
||||||
|
Label label;
|
||||||
|
label._base.id = static_cast<uint32_t>(_targets.getLength()) | kOperandIdTypeLabel;
|
||||||
|
|
||||||
|
CompilerTarget* target = Compiler_newItem<X86CompilerTarget>(this, label);
|
||||||
|
_targets.append(target);
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::bind(const Label& label)
|
||||||
|
{
|
||||||
|
uint32_t id = label.getId() & kOperandIdValueMask;
|
||||||
|
|
||||||
|
ASMJIT_ASSERT(id != kInvalidValue);
|
||||||
|
ASMJIT_ASSERT(id < _targets.getLength());
|
||||||
|
|
||||||
|
addItem(_targets[id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Variables]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
X86CompilerVar* X86Compiler::_newVar(const char* name, uint32_t type, uint32_t size)
|
||||||
|
{
|
||||||
|
X86CompilerVar* var = reinterpret_cast<X86CompilerVar*>(_zoneMemory.alloc(sizeof(X86CompilerVar)));
|
||||||
|
if (var == NULL) return NULL;
|
||||||
|
|
||||||
|
char nameBuffer[32];
|
||||||
|
if (name == NULL)
|
||||||
|
{
|
||||||
|
sprintf(nameBuffer, "var_%d", _varNameId);
|
||||||
|
name = nameBuffer;
|
||||||
|
_varNameId++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var->_name = _zoneMemory.sdup(name);
|
||||||
|
var->_id = static_cast<uint32_t>(_vars.getLength()) | kOperandIdTypeVar;
|
||||||
|
|
||||||
|
var->_type = static_cast<uint8_t>(type);
|
||||||
|
var->_class = x86VarInfo[type].getClass();
|
||||||
|
var->_priority = 10;
|
||||||
|
|
||||||
|
var->_isRegArgument = false;
|
||||||
|
var->_isMemArgument = false;
|
||||||
|
var->_isCalculated = false;
|
||||||
|
var->_unused = 0;
|
||||||
|
|
||||||
|
var->_size = size;
|
||||||
|
|
||||||
|
var->firstItem = NULL;
|
||||||
|
var->lastItem = NULL;
|
||||||
|
var->funcScope = getFunc();
|
||||||
|
var->funcCall = NULL;
|
||||||
|
|
||||||
|
var->homeRegisterIndex = kRegIndexInvalid;
|
||||||
|
var->prefRegisterMask = 0;
|
||||||
|
|
||||||
|
var->homeMemoryOffset = 0;
|
||||||
|
var->homeMemoryData = NULL;
|
||||||
|
|
||||||
|
var->regIndex = kRegIndexInvalid;
|
||||||
|
var->workOffset = kInvalidValue;
|
||||||
|
|
||||||
|
var->nextActive = NULL;
|
||||||
|
var->prevActive = NULL;
|
||||||
|
|
||||||
|
var->state = kVarStateUnused;
|
||||||
|
var->changed = false;
|
||||||
|
var->saveOnUnuse = false;
|
||||||
|
|
||||||
|
var->regReadCount = 0;
|
||||||
|
var->regWriteCount = 0;
|
||||||
|
var->regRwCount = 0;
|
||||||
|
|
||||||
|
var->regGpbLoCount = 0;
|
||||||
|
var->regGpbHiCount = 0;
|
||||||
|
|
||||||
|
var->memReadCount = 0;
|
||||||
|
var->memWriteCount = 0;
|
||||||
|
var->memRwCount = 0;
|
||||||
|
|
||||||
|
var->tPtr = NULL;
|
||||||
|
|
||||||
|
_vars.append(var);
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
GpVar X86Compiler::newGpVar(uint32_t varType, const char* name)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT((varType < kX86VarTypeCount) && (x86VarInfo[varType].getClass() & kX86VarClassGp) != 0);
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X86)
|
||||||
|
if (x86VarInfo[varType].getSize() > 4)
|
||||||
|
{
|
||||||
|
varType = kX86VarTypeGpd;
|
||||||
|
if (_logger)
|
||||||
|
_logger->logString("*** COMPILER WARNING: QWORD variable translated to DWORD, FIX YOUR CODE! ***\n");
|
||||||
|
}
|
||||||
|
#endif // ASMJIT_X86
|
||||||
|
|
||||||
|
X86CompilerVar* var = _newVar(name, varType, x86VarInfo[varType].getSize());
|
||||||
|
return var->asGpVar();
|
||||||
|
}
|
||||||
|
|
||||||
|
GpVar X86Compiler::getGpArg(uint32_t argIndex)
|
||||||
|
{
|
||||||
|
X86CompilerFuncDecl* func = getFunc();
|
||||||
|
GpVar var;
|
||||||
|
|
||||||
|
if (func != NULL)
|
||||||
|
{
|
||||||
|
X86FuncDecl* decl = func->getDecl();
|
||||||
|
|
||||||
|
if (argIndex < decl->getArgumentsCount())
|
||||||
|
{
|
||||||
|
X86CompilerVar* cv = func->getVar(argIndex);
|
||||||
|
|
||||||
|
var._var.id = cv->getId();
|
||||||
|
var._var.size = cv->getSize();
|
||||||
|
var._var.regCode = x86VarInfo[cv->getType()].getCode();
|
||||||
|
var._var.varType = cv->getType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
MmVar X86Compiler::newMmVar(uint32_t varType, const char* name)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT((varType < kX86VarTypeCount) && (x86VarInfo[varType].getClass() & kX86VarClassMm) != 0);
|
||||||
|
|
||||||
|
X86CompilerVar* var = _newVar(name, varType, 8);
|
||||||
|
return var->asMmVar();
|
||||||
|
}
|
||||||
|
|
||||||
|
MmVar X86Compiler::getMmArg(uint32_t argIndex)
|
||||||
|
{
|
||||||
|
X86CompilerFuncDecl* func = getFunc();
|
||||||
|
MmVar var;
|
||||||
|
|
||||||
|
if (func != NULL)
|
||||||
|
{
|
||||||
|
const X86FuncDecl* decl = func->getDecl();
|
||||||
|
|
||||||
|
if (argIndex < decl->getArgumentsCount())
|
||||||
|
{
|
||||||
|
X86CompilerVar* cv = func->getVar(argIndex);
|
||||||
|
|
||||||
|
var._var.id = cv->getId();
|
||||||
|
var._var.size = cv->getSize();
|
||||||
|
var._var.regCode = x86VarInfo[cv->getType()].getCode();
|
||||||
|
var._var.varType = cv->getType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
XmmVar X86Compiler::newXmmVar(uint32_t varType, const char* name)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT((varType < kX86VarTypeCount) && (x86VarInfo[varType].getClass() & kX86VarClassXmm) != 0);
|
||||||
|
|
||||||
|
X86CompilerVar* var = _newVar(name, varType, 16);
|
||||||
|
return var->asXmmVar();
|
||||||
|
}
|
||||||
|
|
||||||
|
XmmVar X86Compiler::getXmmArg(uint32_t argIndex)
|
||||||
|
{
|
||||||
|
X86CompilerFuncDecl* func = getFunc();
|
||||||
|
XmmVar var;
|
||||||
|
|
||||||
|
if (func != NULL)
|
||||||
|
{
|
||||||
|
const X86FuncDecl* decl = func->getDecl();
|
||||||
|
|
||||||
|
if (argIndex < decl->getArgumentsCount())
|
||||||
|
{
|
||||||
|
X86CompilerVar* cv = func->getVar(argIndex);
|
||||||
|
|
||||||
|
var._var.id = cv->getId();
|
||||||
|
var._var.size = cv->getSize();
|
||||||
|
var._var.regCode = x86VarInfo[cv->getType()].getCode();
|
||||||
|
var._var.varType = cv->getType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::_vhint(Var& var, uint32_t hintId, uint32_t hintValue)
|
||||||
|
{
|
||||||
|
if (var.getId() == kInvalidValue)
|
||||||
|
return;
|
||||||
|
|
||||||
|
X86CompilerVar* cv = _getVar(var.getId());
|
||||||
|
ASMJIT_ASSERT(cv != NULL);
|
||||||
|
|
||||||
|
X86CompilerHint* item = Compiler_newItem<X86CompilerHint>(this, cv, hintId, hintValue);
|
||||||
|
addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::alloc(Var& var)
|
||||||
|
{
|
||||||
|
_vhint(var, kVarHintAlloc, kInvalidValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::alloc(Var& var, uint32_t regIndex)
|
||||||
|
{
|
||||||
|
if (regIndex > 31)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_vhint(var, kVarHintAlloc, IntUtil::maskFromIndex(regIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::alloc(Var& var, const Reg& reg)
|
||||||
|
{
|
||||||
|
_vhint(var, kVarHintAlloc, IntUtil::maskFromIndex(reg.getRegIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::save(Var& var)
|
||||||
|
{
|
||||||
|
_vhint(var, kVarHintSave, kInvalidValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::spill(Var& var)
|
||||||
|
{
|
||||||
|
_vhint(var, kVarHintSpill, kInvalidValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::unuse(Var& var)
|
||||||
|
{
|
||||||
|
_vhint(var, kVarHintUnuse, kInvalidValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t X86Compiler::getPriority(Var& var) const
|
||||||
|
{
|
||||||
|
if (var.getId() == kInvalidValue)
|
||||||
|
return kInvalidValue;
|
||||||
|
|
||||||
|
X86CompilerVar* vdata = _getVar(var.getId());
|
||||||
|
ASMJIT_ASSERT(vdata != NULL);
|
||||||
|
|
||||||
|
return vdata->getPriority();
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::setPriority(Var& var, uint32_t priority)
|
||||||
|
{
|
||||||
|
if (var.getId() == kInvalidValue)
|
||||||
|
return;
|
||||||
|
|
||||||
|
X86CompilerVar* vdata = _getVar(var.getId());
|
||||||
|
ASMJIT_ASSERT(vdata != NULL);
|
||||||
|
|
||||||
|
if (priority > 100) priority = 100;
|
||||||
|
vdata->_priority = static_cast<uint8_t>(priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool X86Compiler::getSaveOnUnuse(Var& var) const
|
||||||
|
{
|
||||||
|
if (var.getId() == kInvalidValue)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
X86CompilerVar* vdata = _getVar(var.getId());
|
||||||
|
ASMJIT_ASSERT(vdata != NULL);
|
||||||
|
|
||||||
|
return (bool)vdata->saveOnUnuse;
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::setSaveOnUnuse(Var& var, bool value)
|
||||||
|
{
|
||||||
|
if (var.getId() == kInvalidValue)
|
||||||
|
return;
|
||||||
|
|
||||||
|
X86CompilerVar* vdata = _getVar(var.getId());
|
||||||
|
ASMJIT_ASSERT(vdata != NULL);
|
||||||
|
|
||||||
|
vdata->saveOnUnuse = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::rename(Var& var, const char* name)
|
||||||
|
{
|
||||||
|
if (var.getId() == kInvalidValue)
|
||||||
|
return;
|
||||||
|
|
||||||
|
X86CompilerVar* vdata = _getVar(var.getId());
|
||||||
|
ASMJIT_ASSERT(vdata != NULL);
|
||||||
|
|
||||||
|
vdata->_name = _zoneMemory.sdup(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - State]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
X86CompilerState* X86Compiler::_newState(uint32_t memVarsCount)
|
||||||
|
{
|
||||||
|
X86CompilerState* state = reinterpret_cast<X86CompilerState*>(_zoneMemory.alloc(
|
||||||
|
sizeof(X86CompilerState) + memVarsCount * sizeof(void*)));
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Compiler - Make]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void* X86Compiler::make()
|
||||||
|
{
|
||||||
|
X86Assembler x86Asm(_context);
|
||||||
|
|
||||||
|
x86Asm._properties = _properties;
|
||||||
|
x86Asm.setLogger(_logger);
|
||||||
|
|
||||||
|
serialize(x86Asm);
|
||||||
|
|
||||||
|
if (this->getError())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (x86Asm.getError())
|
||||||
|
{
|
||||||
|
setError(x86Asm.getError());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* result = x86Asm.make();
|
||||||
|
|
||||||
|
if (_logger)
|
||||||
|
{
|
||||||
|
_logger->logFormat("*** COMPILER SUCCESS - Wrote %u bytes, code: %u, trampolines: %u.\n\n",
|
||||||
|
(unsigned int)x86Asm.getCodeSize(),
|
||||||
|
(unsigned int)x86Asm.getOffset(),
|
||||||
|
(unsigned int)x86Asm.getTrampolineSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86Compiler::serialize(Assembler& a)
|
||||||
|
{
|
||||||
|
X86CompilerContext x86Context(this);
|
||||||
|
X86Assembler& x86Asm = static_cast<X86Assembler&>(a);
|
||||||
|
|
||||||
|
CompilerItem* start = _first;
|
||||||
|
CompilerItem* stop = NULL;
|
||||||
|
|
||||||
|
// Register all labels.
|
||||||
|
x86Asm.registerLabels(_targets.getLength());
|
||||||
|
|
||||||
|
// Make code.
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
_cc = NULL;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [Find Function]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (start == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (start->getType() == kCompilerItemFuncDecl)
|
||||||
|
break;
|
||||||
|
|
||||||
|
start->emit(x86Asm);
|
||||||
|
start = start->getNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [Setup CompilerContext]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
stop = static_cast<X86CompilerFuncDecl*>(start)->getEnd();
|
||||||
|
|
||||||
|
x86Context._func = static_cast<X86CompilerFuncDecl*>(start);
|
||||||
|
x86Context._start = start;
|
||||||
|
x86Context._stop = stop;
|
||||||
|
x86Context._extraBlock = stop->getPrev();
|
||||||
|
|
||||||
|
// Detect whether the function generation was finished.
|
||||||
|
if (!x86Context._func->isFinished() || x86Context._func->getEnd()->getPrev() == NULL)
|
||||||
|
{
|
||||||
|
setError(kErrorIncompleteFunction);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Step 1:
|
||||||
|
// - Assign/increment offset of each item.
|
||||||
|
// - Extract variables from instructions.
|
||||||
|
// - Prepare variables for register allocator:
|
||||||
|
// - Update read(r) / write(w) / read/write(x) statistics.
|
||||||
|
// - Update register / memory usage statistics.
|
||||||
|
// - Find scope (first / last item) of variables.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CompilerItem* cur;
|
||||||
|
for (cur = start; ; cur = cur->getNext())
|
||||||
|
{
|
||||||
|
cur->prepare(x86Context);
|
||||||
|
if (cur == stop)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We set compiler context also to Compiler so newly emitted instructions
|
||||||
|
// can call CompilerItem::prepare() on itself.
|
||||||
|
_cc = &x86Context;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Step 2:
|
||||||
|
// - Translate special instructions (imul, cmpxchg8b, ...).
|
||||||
|
// - Alloc registers.
|
||||||
|
// - Translate forward jumps.
|
||||||
|
// - Alloc memory operands (variables related).
|
||||||
|
// - Emit function prolog.
|
||||||
|
// - Emit function epilog.
|
||||||
|
// - Patch memory operands (variables related).
|
||||||
|
// - Dump function prototype and variable statistics (if enabled).
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Translate special instructions and run alloc registers.
|
||||||
|
cur = start;
|
||||||
|
|
||||||
|
do {
|
||||||
|
do {
|
||||||
|
// Assign current offset of each item back to CompilerContext.
|
||||||
|
x86Context._currentOffset = cur->_offset;
|
||||||
|
// Assign previous item to compiler so each variable spill/alloc will
|
||||||
|
// be emitted before.
|
||||||
|
_current = cur->getPrev();
|
||||||
|
|
||||||
|
cur = cur->translate(x86Context);
|
||||||
|
} while (cur);
|
||||||
|
|
||||||
|
x86Context._isUnreachable = true;
|
||||||
|
|
||||||
|
size_t len = x86Context._backCode.getLength();
|
||||||
|
while (x86Context._backPos < len)
|
||||||
|
{
|
||||||
|
cur = x86Context._backCode[x86Context._backPos++]->getNext();
|
||||||
|
if (!cur->isTranslated()) break;
|
||||||
|
|
||||||
|
cur = NULL;
|
||||||
|
}
|
||||||
|
} while (cur);
|
||||||
|
|
||||||
|
// Translate forward jumps.
|
||||||
|
{
|
||||||
|
ForwardJumpData* j = x86Context._forwardJumps;
|
||||||
|
while (j != NULL)
|
||||||
|
{
|
||||||
|
x86Context._assignState(j->state);
|
||||||
|
_current = j->inst->getPrev();
|
||||||
|
j->inst->doJump(x86Context);
|
||||||
|
j = j->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alloc memory operands (variables related).
|
||||||
|
x86Context._allocMemoryOperands();
|
||||||
|
|
||||||
|
// Emit function prolog / epilog.
|
||||||
|
x86Context.getFunc()->_preparePrologEpilog(x86Context);
|
||||||
|
|
||||||
|
_current = x86Context._func->getEntryTarget();
|
||||||
|
x86Context.getFunc()->_emitProlog(x86Context);
|
||||||
|
|
||||||
|
_current = x86Context._func->getExitTarget();
|
||||||
|
x86Context.getFunc()->_emitEpilog(x86Context);
|
||||||
|
|
||||||
|
// Patch memory operands (variables related).
|
||||||
|
_current = _last;
|
||||||
|
x86Context._patchMemoryOperands(start, stop);
|
||||||
|
|
||||||
|
// Dump function prototype and variable statistics (if enabled).
|
||||||
|
if (_logger)
|
||||||
|
x86Context.getFunc()->_dumpFunction(x86Context);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Hack: need to register labels that was created by the Step 2.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if (x86Asm._labels.getLength() < _targets.getLength())
|
||||||
|
x86Asm.registerLabels(_targets.getLength() - x86Asm._labels.getLength());
|
||||||
|
|
||||||
|
CompilerItem* extraBlock = x86Context._extraBlock;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Step 3:
|
||||||
|
// - Emit instructions to Assembler stream.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
for (cur = start; ; cur = cur->getNext())
|
||||||
|
{
|
||||||
|
cur->emit(x86Asm);
|
||||||
|
if (cur == extraBlock) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Step 4:
|
||||||
|
// - Emit everything else (post action).
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
for (cur = start; ; cur = cur->getNext())
|
||||||
|
{
|
||||||
|
cur->post(x86Asm);
|
||||||
|
if (cur == extraBlock) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = extraBlock->getNext();
|
||||||
|
x86Context._clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,321 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_X86_X86COMPILERCONTEXT_H
|
||||||
|
#define _ASMJIT_X86_X86COMPILERCONTEXT_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/intutil.h"
|
||||||
|
#include "../core/podvector.h"
|
||||||
|
|
||||||
|
#include "../x86/x86assembler.h"
|
||||||
|
#include "../x86/x86compiler.h"
|
||||||
|
#include "../x86/x86compilerfunc.h"
|
||||||
|
#include "../x86/x86compileritem.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_X86
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86CompilerContext]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief Compiler context is used by @ref X86Compiler.
|
||||||
|
//!
|
||||||
|
//! X86Compiler context is used during compilation and normally developer doesn't
|
||||||
|
//! need access to it. The context is user per function (it's reset after each
|
||||||
|
//! function is generated).
|
||||||
|
struct X86CompilerContext : public CompilerContext
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref X86CompilerContext instance.
|
||||||
|
ASMJIT_API X86CompilerContext(X86Compiler* x86Compiler);
|
||||||
|
//! @brief Destroy the @ref X86CompilerContext instance.
|
||||||
|
ASMJIT_API ~X86CompilerContext();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessor]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get compiler as @ref X86Compiler.
|
||||||
|
inline X86Compiler* getCompiler() const
|
||||||
|
{ return reinterpret_cast<X86Compiler*>(_compiler); }
|
||||||
|
|
||||||
|
//! @brief Get function as @ref X86CompilerFuncDecl.
|
||||||
|
inline X86CompilerFuncDecl* getFunc() const
|
||||||
|
{ return reinterpret_cast<X86CompilerFuncDecl*>(_func); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Clear]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Clear context, preparing it for next function generation.
|
||||||
|
ASMJIT_API void _clear();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Register Allocator]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Allocate variable
|
||||||
|
//!
|
||||||
|
//! Calls @c allocGpVar, @c allocMmVar or @c allocXmmVar methods.
|
||||||
|
ASMJIT_API void allocVar(X86CompilerVar* cv, uint32_t regMask, uint32_t vflags);
|
||||||
|
|
||||||
|
//! @brief Save variable.
|
||||||
|
//!
|
||||||
|
//! Calls @c saveGpVar, @c saveMmVar or @c saveXmmVar methods.
|
||||||
|
ASMJIT_API void saveVar(X86CompilerVar* cv);
|
||||||
|
|
||||||
|
//! @brief Spill variable.
|
||||||
|
//!
|
||||||
|
//! Calls @c spillGpVar, @c spillMmVar or @c spillXmmVar methods.
|
||||||
|
ASMJIT_API void spillVar(X86CompilerVar* cv);
|
||||||
|
|
||||||
|
//! @brief Unuse variable (didn't spill, just forget about it).
|
||||||
|
ASMJIT_API void unuseVar(X86CompilerVar* cv, uint32_t toState);
|
||||||
|
|
||||||
|
//! @brief Helper method that is called for each variable per item.
|
||||||
|
inline void _unuseVarOnEndOfScope(CompilerItem* item, X86CompilerVar* cv)
|
||||||
|
{
|
||||||
|
if (cv->lastItem == item)
|
||||||
|
unuseVar(cv, kVarStateUnused);
|
||||||
|
}
|
||||||
|
//! @overload
|
||||||
|
inline void _unuseVarOnEndOfScope(CompilerItem* item, VarAllocRecord* rec)
|
||||||
|
{
|
||||||
|
X86CompilerVar* cv = rec->vdata;
|
||||||
|
if (cv->lastItem == item || (rec->vflags & kVarAllocUnuseAfterUse))
|
||||||
|
unuseVar(cv, kVarStateUnused);
|
||||||
|
}
|
||||||
|
//! @overload
|
||||||
|
inline void _unuseVarOnEndOfScope(CompilerItem* item, VarCallRecord* rec)
|
||||||
|
{
|
||||||
|
X86CompilerVar* v = rec->vdata;
|
||||||
|
if (v->lastItem == item || (rec->flags & VarCallRecord::kFlagUnuseAfterUse))
|
||||||
|
unuseVar(v, kVarStateUnused);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Allocate variable (GP).
|
||||||
|
ASMJIT_API void allocGpVar(X86CompilerVar* cv, uint32_t regMask, uint32_t vflags);
|
||||||
|
//! @brief Save variable (GP).
|
||||||
|
ASMJIT_API void saveGpVar(X86CompilerVar* cv);
|
||||||
|
//! @brief Spill variable (GP).
|
||||||
|
ASMJIT_API void spillGpVar(X86CompilerVar* cv);
|
||||||
|
|
||||||
|
//! @brief Allocate variable (MM).
|
||||||
|
ASMJIT_API void allocMmVar(X86CompilerVar* cv, uint32_t regMask, uint32_t vflags);
|
||||||
|
//! @brief Save variable (MM).
|
||||||
|
ASMJIT_API void saveMmVar(X86CompilerVar* cv);
|
||||||
|
//! @brief Spill variable (MM).
|
||||||
|
ASMJIT_API void spillMmVar(X86CompilerVar* cv);
|
||||||
|
|
||||||
|
//! @brief Allocate variable (XMM).
|
||||||
|
ASMJIT_API void allocXmmVar(X86CompilerVar* cv, uint32_t regMask, uint32_t vflags);
|
||||||
|
//! @brief Save variable (XMM).
|
||||||
|
ASMJIT_API void saveXmmVar(X86CompilerVar* cv);
|
||||||
|
//! @brief Spill variable (XMM).
|
||||||
|
ASMJIT_API void spillXmmVar(X86CompilerVar* cv);
|
||||||
|
|
||||||
|
//! @brief Emit load variable instruction(s).
|
||||||
|
ASMJIT_API void emitLoadVar(X86CompilerVar* cv, uint32_t regIndex);
|
||||||
|
//! @brief Emit save variable instruction(s).
|
||||||
|
ASMJIT_API void emitSaveVar(X86CompilerVar* cv, uint32_t regIndex);
|
||||||
|
|
||||||
|
//! @brief Emit move variable instruction(s).
|
||||||
|
ASMJIT_API void emitMoveVar(X86CompilerVar* cv, uint32_t regIndex, uint32_t vflags);
|
||||||
|
//! @brief Emit exchange variable instruction(s).
|
||||||
|
ASMJIT_API void emitExchangeVar(X86CompilerVar* cv, uint32_t regIndex, uint32_t vflags, X86CompilerVar* other);
|
||||||
|
|
||||||
|
//! @brief Called each time a variable is alloceted.
|
||||||
|
ASMJIT_API void _postAlloc(X86CompilerVar* cv, uint32_t vflags);
|
||||||
|
//! @brief Marks variable home memory as used (must be called at least once
|
||||||
|
//! for each variable that uses function local memory - stack).
|
||||||
|
ASMJIT_API void _markMemoryUsed(X86CompilerVar* cv);
|
||||||
|
|
||||||
|
ASMJIT_API Mem _getVarMem(X86CompilerVar* cv);
|
||||||
|
|
||||||
|
ASMJIT_API X86CompilerVar* _getSpillCandidateGP();
|
||||||
|
ASMJIT_API X86CompilerVar* _getSpillCandidateMM();
|
||||||
|
ASMJIT_API X86CompilerVar* _getSpillCandidateXMM();
|
||||||
|
ASMJIT_API X86CompilerVar* _getSpillCandidateGeneric(X86CompilerVar** varArray, uint32_t count);
|
||||||
|
|
||||||
|
inline bool _isActive(X86CompilerVar* cv)
|
||||||
|
{ return cv->nextActive != NULL; }
|
||||||
|
|
||||||
|
ASMJIT_API void _addActive(X86CompilerVar* cv);
|
||||||
|
ASMJIT_API void _freeActive(X86CompilerVar* cv);
|
||||||
|
ASMJIT_API void _freeAllActive();
|
||||||
|
|
||||||
|
ASMJIT_API void _allocatedVariable(X86CompilerVar* cv);
|
||||||
|
|
||||||
|
inline void _allocatedGpRegister(uint32_t index)
|
||||||
|
{
|
||||||
|
_x86State.usedGP |= IntUtil::maskFromIndex(index);
|
||||||
|
_modifiedGpRegisters |= IntUtil::maskFromIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void _allocatedMmRegister(uint32_t index)
|
||||||
|
{
|
||||||
|
_x86State.usedMM |= IntUtil::maskFromIndex(index);
|
||||||
|
_modifiedMmRegisters |= IntUtil::maskFromIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void _allocatedXmmRegister(uint32_t index)
|
||||||
|
{
|
||||||
|
_x86State.usedXMM |= IntUtil::maskFromIndex(index);
|
||||||
|
_modifiedXmmRegisters |= IntUtil::maskFromIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void _freedGpRegister(uint32_t index)
|
||||||
|
{ _x86State.usedGP &= ~IntUtil::maskFromIndex(index); }
|
||||||
|
|
||||||
|
inline void _freedMmRegister(uint32_t index)
|
||||||
|
{ _x86State.usedMM &= ~IntUtil::maskFromIndex(index); }
|
||||||
|
|
||||||
|
inline void _freedXmmRegister(uint32_t index)
|
||||||
|
{ _x86State.usedXMM &= ~IntUtil::maskFromIndex(index); }
|
||||||
|
|
||||||
|
inline void _markGpRegisterModified(uint32_t index)
|
||||||
|
{ _modifiedGpRegisters |= IntUtil::maskFromIndex(index); }
|
||||||
|
|
||||||
|
inline void _markMmRegisterModified(uint32_t index)
|
||||||
|
{ _modifiedMmRegisters |= IntUtil::maskFromIndex(index); }
|
||||||
|
|
||||||
|
inline void _markXmmRegisterModified(uint32_t index)
|
||||||
|
{ _modifiedXmmRegisters |= IntUtil::maskFromIndex(index); }
|
||||||
|
|
||||||
|
// TODO: Find code which uses this and improve.
|
||||||
|
inline void _newRegisterHomeIndex(X86CompilerVar* cv, uint32_t idx)
|
||||||
|
{
|
||||||
|
if (cv->homeRegisterIndex == kRegIndexInvalid)
|
||||||
|
cv->homeRegisterIndex = idx;
|
||||||
|
cv->prefRegisterMask |= (1U << idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Find code which uses this and improve.
|
||||||
|
inline void _newRegisterHomeMask(X86CompilerVar* cv, uint32_t mask)
|
||||||
|
{
|
||||||
|
cv->prefRegisterMask |= mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Operand Patcher]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API void translateOperands(Operand* operands, uint32_t count);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Backward Code]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API void addBackwardCode(X86CompilerJmpInst* from);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Forward Jump]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API void addForwardJump(X86CompilerJmpInst* inst);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [State]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API X86CompilerState* _saveState();
|
||||||
|
ASMJIT_API void _assignState(X86CompilerState* state);
|
||||||
|
ASMJIT_API void _restoreState(X86CompilerState* state, uint32_t targetOffset = kInvalidValue);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Memory Allocator]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API VarMemBlock* _allocMemBlock(uint32_t size);
|
||||||
|
ASMJIT_API void _freeMemBlock(VarMemBlock* mem);
|
||||||
|
|
||||||
|
ASMJIT_API void _allocMemoryOperands();
|
||||||
|
ASMJIT_API void _patchMemoryOperands(CompilerItem* start, CompilerItem* stop);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief X86 specific compiler state (linked with @ref _state).
|
||||||
|
X86CompilerState _x86State;
|
||||||
|
|
||||||
|
//! @brief Forward jumps (single linked list).
|
||||||
|
ForwardJumpData* _forwardJumps;
|
||||||
|
|
||||||
|
//! @brief Global modified GP registers mask (per function).
|
||||||
|
uint32_t _modifiedGpRegisters;
|
||||||
|
//! @brief Global modified MM registers mask (per function).
|
||||||
|
uint32_t _modifiedMmRegisters;
|
||||||
|
//! @brief Global modified XMM registers mask (per function).
|
||||||
|
uint32_t _modifiedXmmRegisters;
|
||||||
|
|
||||||
|
//! @brief Whether the EBP/RBP register can be used by register allocator.
|
||||||
|
uint32_t _allocableEBP;
|
||||||
|
|
||||||
|
//! @brief ESP adjust constant (changed during PUSH/POP or when using
|
||||||
|
//! stack.
|
||||||
|
int _adjustESP;
|
||||||
|
|
||||||
|
//! @brief Function arguments base pointer (register).
|
||||||
|
uint32_t _argumentsBaseReg;
|
||||||
|
//! @brief Function arguments base offset.
|
||||||
|
int32_t _argumentsBaseOffset;
|
||||||
|
//! @brief Function arguments displacement.
|
||||||
|
int32_t _argumentsActualDisp;
|
||||||
|
|
||||||
|
//! @brief Function variables base pointer (register).
|
||||||
|
uint32_t _variablesBaseReg;
|
||||||
|
//! @brief Function variables base offset.
|
||||||
|
int32_t _variablesBaseOffset;
|
||||||
|
//! @brief Function variables displacement.
|
||||||
|
int32_t _variablesActualDisp;
|
||||||
|
|
||||||
|
//! @brief Used memory blocks (for variables, here is each created mem block
|
||||||
|
//! that can be also in _memFree list).
|
||||||
|
VarMemBlock* _memUsed;
|
||||||
|
//! @brief Free memory blocks (freed, prepared for another allocation).
|
||||||
|
VarMemBlock* _memFree;
|
||||||
|
//! @brief Count of 4-byte memory blocks used by the function.
|
||||||
|
uint32_t _mem4BlocksCount;
|
||||||
|
//! @brief Count of 8-byte memory blocks used by the function.
|
||||||
|
uint32_t _mem8BlocksCount;
|
||||||
|
//! @brief Count of 16-byte memory blocks used by the function.
|
||||||
|
uint32_t _mem16BlocksCount;
|
||||||
|
//! @brief Count of total bytes of stack memory used by the function.
|
||||||
|
uint32_t _memBytesTotal;
|
||||||
|
|
||||||
|
//! @brief List of items which need to be translated. These items are filled
|
||||||
|
//! by @c addBackwardCode().
|
||||||
|
PodVector<X86CompilerJmpInst*> _backCode;
|
||||||
|
|
||||||
|
//! @brief Backward code position (starts at 0).
|
||||||
|
sysuint_t _backPos;
|
||||||
|
//! @brief Whether to emit comments.
|
||||||
|
bool _emitComments;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_X86_X86COMPILERCONTEXT_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,369 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_X86_X86COMPILERFUNC_H
|
||||||
|
#define _ASMJIT_X86_X86COMPILERFUNC_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../x86/x86assembler.h"
|
||||||
|
#include "../x86/x86compiler.h"
|
||||||
|
#include "../x86/x86compileritem.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_X86
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86CompilerFuncDecl]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief @ref X86Compiler specific function declaration item.
|
||||||
|
struct X86CompilerFuncDecl : public CompilerFuncDecl
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(X86CompilerFuncDecl)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref X86CompilerFuncDecl instance.
|
||||||
|
ASMJIT_API X86CompilerFuncDecl(X86Compiler* x86Compiler);
|
||||||
|
//! @brief Destroy the @ref X86CompilerFuncDecl instance.
|
||||||
|
ASMJIT_API virtual ~X86CompilerFuncDecl();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get compiler as @ref X86Compiler.
|
||||||
|
inline X86Compiler* getCompiler() const
|
||||||
|
{ return reinterpret_cast<X86Compiler*>(_compiler); }
|
||||||
|
|
||||||
|
//! @brief Get function end item as @ref X86CompilerFuncEnd.
|
||||||
|
inline X86CompilerFuncEnd* getEnd() const
|
||||||
|
{ return reinterpret_cast<X86CompilerFuncEnd*>(_end); }
|
||||||
|
|
||||||
|
//! @brief Get function declaration as @ref X86FuncDecl.
|
||||||
|
inline X86FuncDecl* getDecl() const
|
||||||
|
{ return reinterpret_cast<X86FuncDecl*>(_decl); }
|
||||||
|
|
||||||
|
//! @brief Get function arguments as variables as @ref X86CompilerVar.
|
||||||
|
inline X86CompilerVar** getVars() const
|
||||||
|
{ return reinterpret_cast<X86CompilerVar**>(_vars); }
|
||||||
|
|
||||||
|
//! @brief Get function argument at @a index.
|
||||||
|
inline X86CompilerVar* getVar(uint32_t index) const
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(index < _x86Decl.getArgumentsCount());
|
||||||
|
return reinterpret_cast<X86CompilerVar**>(_vars)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Get whether it's assumed that stack is aligned to 16 bytes.
|
||||||
|
inline bool isAssumed16ByteAlignment() const
|
||||||
|
{ return hasFuncFlag(kX86FuncFlagAssume16ByteAlignment); }
|
||||||
|
|
||||||
|
//! @brief Get whether it's required to align stack to 16 bytes by function.
|
||||||
|
inline bool isPerformed16ByteAlignment() const
|
||||||
|
{ return hasFuncFlag(kX86FuncFlagPerform16ByteAlignment); }
|
||||||
|
|
||||||
|
//! @brief Get whether the ESP is adjusted.
|
||||||
|
inline bool isEspAdjusted() const
|
||||||
|
{ return hasFuncFlag(kX86FuncFlagIsEspAdjusted); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Interface]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void prepare(CompilerContext& cc);
|
||||||
|
ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Misc]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual int getMaxSize() const;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Prototype]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void setPrototype(
|
||||||
|
uint32_t convention,
|
||||||
|
uint32_t returnType,
|
||||||
|
const uint32_t* arguments,
|
||||||
|
uint32_t argumentsCount);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Helpers]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @internal
|
||||||
|
//!
|
||||||
|
//! @brief Get required stack offset needed to subtract/add Esp/Rsp in
|
||||||
|
//! prolog/epilog.
|
||||||
|
inline int32_t _getRequiredStackOffset() const
|
||||||
|
{ return _funcCallStackSize + _memStackSize16 + _peMovStackSize + _peAdjustStackSize; }
|
||||||
|
|
||||||
|
//! @brief Create variables from FunctionPrototype declaration. This is just
|
||||||
|
//! parsing what FunctionPrototype generated for current function calling
|
||||||
|
//! convention and arguments.
|
||||||
|
ASMJIT_API void _createVariables();
|
||||||
|
|
||||||
|
//! @brief Prepare variables (ids, names, scope, registers).
|
||||||
|
ASMJIT_API void _prepareVariables(CompilerItem* first);
|
||||||
|
|
||||||
|
//! @brief Allocate variables (setting correct state, changing masks, etc).
|
||||||
|
ASMJIT_API void _allocVariables(CompilerContext& cc);
|
||||||
|
|
||||||
|
ASMJIT_API void _preparePrologEpilog(CompilerContext& cc);
|
||||||
|
ASMJIT_API void _dumpFunction(CompilerContext& cc);
|
||||||
|
ASMJIT_API void _emitProlog(CompilerContext& cc);
|
||||||
|
ASMJIT_API void _emitEpilog(CompilerContext& cc);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Function-Call]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Reserve stack for calling other function and mark function as
|
||||||
|
//! callee.
|
||||||
|
ASMJIT_API void reserveStackForFunctionCall(int32_t size);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief X86 function decl.
|
||||||
|
X86FuncDecl _x86Decl;
|
||||||
|
|
||||||
|
//! @brief Modified and preserved GP registers mask.
|
||||||
|
uint32_t _gpModifiedAndPreserved;
|
||||||
|
//! @brief Modified and preserved MM registers mask.
|
||||||
|
uint32_t _mmModifiedAndPreserved;
|
||||||
|
//! @brief Modified and preserved XMM registers mask.
|
||||||
|
uint32_t _xmmModifiedAndPreserved;
|
||||||
|
|
||||||
|
//! @brief Id of MovDQWord instruction (@c kX86InstMovDQA or @c kX86InstMovDQU).
|
||||||
|
//!
|
||||||
|
//! The value is based on stack alignment. If it's guaranteed that stack
|
||||||
|
//! is aligned to 16-bytes then @c kX86InstMovDQA instruction is used, otherwise
|
||||||
|
//! the @c kX86InstMovDQU instruction is used for 16-byte mov.
|
||||||
|
uint32_t _movDqInstCode;
|
||||||
|
|
||||||
|
//! @brief Prolog / epilog stack size for PUSH/POP sequences.
|
||||||
|
int32_t _pePushPopStackSize;
|
||||||
|
//! @brief Prolog / epilog stack size for MOV sequences.
|
||||||
|
int32_t _peMovStackSize;
|
||||||
|
//! @brief Prolog / epilog stack adjust size (to make it 16-byte aligned).
|
||||||
|
int32_t _peAdjustStackSize;
|
||||||
|
|
||||||
|
//! @brief Memory stack size (for all variables and temporary memory).
|
||||||
|
int32_t _memStackSize;
|
||||||
|
//! @brief Like @c _memStackSize, but aligned to 16-bytes.
|
||||||
|
int32_t _memStackSize16;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86CompilerFuncEnd]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief @ref X86Compiler function end item.
|
||||||
|
struct X86CompilerFuncEnd : public CompilerFuncEnd
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(X86CompilerFuncEnd)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref X86CompilerFuncEnd instance.
|
||||||
|
ASMJIT_API X86CompilerFuncEnd(X86Compiler* x86Compiler, X86CompilerFuncDecl* func);
|
||||||
|
//! @brief Destroy the @ref X86CompilerFuncEnd instance.
|
||||||
|
ASMJIT_API virtual ~X86CompilerFuncEnd();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get compiler as @ref X86Compiler.
|
||||||
|
inline X86Compiler* getCompiler() const
|
||||||
|
{ return reinterpret_cast<X86Compiler*>(_compiler); }
|
||||||
|
|
||||||
|
//! @brief Get related function as @ref X86CompilerFuncDecl.
|
||||||
|
inline X86CompilerFuncDecl* getFunc() const
|
||||||
|
{ return reinterpret_cast<X86CompilerFuncDecl*>(_func); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Interface]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void prepare(CompilerContext& cc);
|
||||||
|
ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86CompilerFuncRet]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Function return.
|
||||||
|
struct X86CompilerFuncRet : public CompilerFuncRet
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(X86CompilerFuncRet)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref X86CompilerFuncRet instance.
|
||||||
|
ASMJIT_API X86CompilerFuncRet(X86Compiler* c, X86CompilerFuncDecl* func,
|
||||||
|
const Operand* first, const Operand* second);
|
||||||
|
//! @brief Destroy the @ref X86CompilerFuncRet instance.
|
||||||
|
ASMJIT_API virtual ~X86CompilerFuncRet();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get compiler as @ref X86Compiler.
|
||||||
|
inline X86Compiler* getCompiler() const
|
||||||
|
{ return reinterpret_cast<X86Compiler*>(_compiler); }
|
||||||
|
|
||||||
|
//! @Brief Get related function as @ref X86CompilerFuncDecl.
|
||||||
|
inline X86CompilerFuncDecl* getFunc() const
|
||||||
|
{ return reinterpret_cast<X86CompilerFuncDecl*>(_func); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Interface]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void prepare(CompilerContext& cc);
|
||||||
|
ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
|
||||||
|
ASMJIT_API virtual void emit(Assembler& a);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Misc]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual int getMaxSize() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86CompilerFuncCall]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler function call item.
|
||||||
|
struct X86CompilerFuncCall : public CompilerFuncCall
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(X86CompilerFuncCall)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref X86CompilerFuncCall instance.
|
||||||
|
ASMJIT_API X86CompilerFuncCall(X86Compiler* x86Compiler, X86CompilerFuncDecl* caller, const Operand* target);
|
||||||
|
//! @brief Destroy the @ref X86CompilerFuncCall instance.
|
||||||
|
ASMJIT_API virtual ~X86CompilerFuncCall();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get compiler as @ref X86Compiler.
|
||||||
|
inline X86Compiler* getCompiler() const
|
||||||
|
{ return reinterpret_cast<X86Compiler*>(_compiler); }
|
||||||
|
|
||||||
|
//! @brief Get caller as @ref X86CompilerFuncDecl.
|
||||||
|
inline X86CompilerFuncDecl* getCaller() const
|
||||||
|
{ return reinterpret_cast<X86CompilerFuncDecl*>(_caller); }
|
||||||
|
|
||||||
|
//! @brief Get function prototype.
|
||||||
|
inline const X86FuncDecl* getDecl() const
|
||||||
|
{ return reinterpret_cast<X86FuncDecl*>(_decl); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Interface]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void prepare(CompilerContext& cc);
|
||||||
|
ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Misc]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual int getMaxSize() const;
|
||||||
|
ASMJIT_API virtual bool _tryUnuseVar(CompilerVar* v);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Prototype]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void setPrototype(uint32_t convention, uint32_t returnType, const uint32_t* arguments, uint32_t argumentsCount);
|
||||||
|
|
||||||
|
//! @brief Set function prototype.
|
||||||
|
inline void setPrototype(uint32_t convention, const FuncPrototype& func)
|
||||||
|
{ setPrototype(convention, func.getReturnType(), func.getArguments(), func.getArgumentsCount()); }
|
||||||
|
|
||||||
|
//! @brief Set return value.
|
||||||
|
ASMJIT_API bool setReturn(const Operand& first, const Operand& second = Operand());
|
||||||
|
|
||||||
|
//! @brief Set function argument @a i to @a var.
|
||||||
|
ASMJIT_API bool setArgument(uint32_t i, const Var& var);
|
||||||
|
//! @brief Set function argument @a i to @a imm.
|
||||||
|
ASMJIT_API bool setArgument(uint32_t i, const Imm& imm);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Internal]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API uint32_t _findTemporaryGpRegister(CompilerContext& cc);
|
||||||
|
ASMJIT_API uint32_t _findTemporaryXmmRegister(CompilerContext& cc);
|
||||||
|
|
||||||
|
ASMJIT_API X86CompilerVar* _getOverlappingVariable(CompilerContext& cc, const FuncArg& argType) const;
|
||||||
|
|
||||||
|
ASMJIT_API void _moveAllocatedVariableToStack(CompilerContext& cc, X86CompilerVar* vdata, const FuncArg& argType);
|
||||||
|
ASMJIT_API void _moveSpilledVariableToStack(CompilerContext& cc, X86CompilerVar* vdata, const FuncArg& argType,
|
||||||
|
uint32_t temporaryGpReg,
|
||||||
|
uint32_t temporaryXmmReg);
|
||||||
|
ASMJIT_API void _moveSrcVariableToRegister(CompilerContext& cc, X86CompilerVar* vdata, const FuncArg& argType);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief X86 declaration.
|
||||||
|
X86FuncDecl _x86Decl;
|
||||||
|
|
||||||
|
//! @brief Mask of GP registers used as function arguments.
|
||||||
|
uint32_t _gpParams;
|
||||||
|
//! @brief Mask of MM registers used as function arguments.
|
||||||
|
uint32_t _mmParams;
|
||||||
|
//! @brief Mask of XMM registers used as function arguments.
|
||||||
|
uint32_t _xmmParams;
|
||||||
|
|
||||||
|
//! @brief Variables count.
|
||||||
|
uint32_t _variablesCount;
|
||||||
|
|
||||||
|
//! @brief Variables (extracted from operands).
|
||||||
|
VarCallRecord* _variables;
|
||||||
|
//! @brief Argument index to @c VarCallRecord.
|
||||||
|
VarCallRecord* _argumentToVarRecord[kFuncArgsMax];
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_X86_X86COMPILERFUNC_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,284 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_X86_X86COMPILERITEM_H
|
||||||
|
#define _ASMJIT_X86_X86COMPILERITEM_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../x86/x86assembler.h"
|
||||||
|
#include "../x86/x86compiler.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_X86
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86CompilerAlign]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Compiler align item.
|
||||||
|
struct X86CompilerAlign : public CompilerAlign
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(X86CompilerAlign)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref CompilerAlign instance.
|
||||||
|
ASMJIT_API X86CompilerAlign(X86Compiler* x86Compiler, uint32_t size = 0);
|
||||||
|
//! @brief Destroy the @ref CompilerAlign instance.
|
||||||
|
ASMJIT_API virtual ~X86CompilerAlign();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get compiler as @ref X86Compiler.
|
||||||
|
inline X86Compiler* getCompiler() const
|
||||||
|
{ return reinterpret_cast<X86Compiler*>(_compiler); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Interface]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void emit(Assembler& a);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86CompilerHint]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief @ref X86Compiler variable hint item.
|
||||||
|
struct X86CompilerHint : public CompilerHint
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(X86CompilerHint)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref X86CompilerHint instance.
|
||||||
|
ASMJIT_API X86CompilerHint(X86Compiler* compiler, X86CompilerVar* var, uint32_t hintId, uint32_t hintValue);
|
||||||
|
//! @brief Destroy the @ref X86CompilerHint instance.
|
||||||
|
ASMJIT_API virtual ~X86CompilerHint();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get variable as @ref X86CompilerVar.
|
||||||
|
inline X86CompilerVar* getVar() const
|
||||||
|
{ return reinterpret_cast<X86CompilerVar*>(_var); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Interface]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void prepare(CompilerContext& cc);
|
||||||
|
ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Misc]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual int getMaxSize() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86CompilerTarget]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief X86Compiler target item.
|
||||||
|
struct X86CompilerTarget : public CompilerTarget
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(X86CompilerTarget)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref X86CompilerTarget instance.
|
||||||
|
ASMJIT_API X86CompilerTarget(X86Compiler* x86Compiler, const Label& target);
|
||||||
|
//! @brief Destroy the @ref X86CompilerTarget instance.
|
||||||
|
ASMJIT_API virtual ~X86CompilerTarget();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get compiler as @ref X86Compiler.
|
||||||
|
inline X86Compiler* getCompiler() const
|
||||||
|
{ return reinterpret_cast<X86Compiler*>(_compiler); }
|
||||||
|
|
||||||
|
//! @brief Get state as @ref X86CompilerState.
|
||||||
|
inline X86CompilerState* getState() const
|
||||||
|
{ return reinterpret_cast<X86CompilerState*>(_state); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Interface]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void prepare(CompilerContext& cc);
|
||||||
|
ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
|
||||||
|
ASMJIT_API virtual void emit(Assembler& a);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86CompilerInst]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief @ref X86Compiler instruction item.
|
||||||
|
struct X86CompilerInst : public CompilerInst
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(X86CompilerInst)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref X86CompilerInst instance.
|
||||||
|
ASMJIT_API X86CompilerInst(X86Compiler* x86Compiler, uint32_t code, Operand* opData, uint32_t opCount);
|
||||||
|
//! @brief Destroy the @ref X86CompilerInst instance.
|
||||||
|
ASMJIT_API virtual ~X86CompilerInst();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get compiler as @ref X86Compiler.
|
||||||
|
inline X86Compiler* getCompiler() const
|
||||||
|
{ return reinterpret_cast<X86Compiler*>(_compiler); }
|
||||||
|
|
||||||
|
//! @brief Get whether the instruction is special.
|
||||||
|
inline bool isSpecial() const
|
||||||
|
{ return (_instFlags & kX86CompilerInstFlagIsSpecial) != 0; }
|
||||||
|
|
||||||
|
//! @brief Get whether the instruction is FPU.
|
||||||
|
inline bool isFpu() const
|
||||||
|
{ return (_instFlags & kX86CompilerInstFlagIsFpu) != 0; }
|
||||||
|
|
||||||
|
//! @brief Get whether the instruction is used with GpbLo register.
|
||||||
|
inline bool isGpbLoUsed() const
|
||||||
|
{ return (_instFlags & kX86CompilerInstFlagIsGpbLoUsed) != 0; }
|
||||||
|
|
||||||
|
//! @brief Get whether the instruction is used with GpbHi register.
|
||||||
|
inline bool isGpbHiUsed() const
|
||||||
|
{ return (_instFlags & kX86CompilerInstFlagIsGpbHiUsed) != 0; }
|
||||||
|
|
||||||
|
//! @brief Get memory operand.
|
||||||
|
inline Mem* getMemOp()
|
||||||
|
{ return _memOp; }
|
||||||
|
|
||||||
|
//! @brief Set memory operand.
|
||||||
|
inline void setMemOp(Mem* memOp)
|
||||||
|
{ _memOp = memOp; }
|
||||||
|
|
||||||
|
//! @brief Get operands array (3 operands total).
|
||||||
|
inline VarAllocRecord* getVars()
|
||||||
|
{ return _vars; }
|
||||||
|
|
||||||
|
//! @brief Get operands array (3 operands total).
|
||||||
|
inline const VarAllocRecord* getVars() const
|
||||||
|
{ return _vars; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Interface]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void prepare(CompilerContext& cc);
|
||||||
|
ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
|
||||||
|
ASMJIT_API virtual void emit(Assembler& a);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Misc]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual int getMaxSize() const;
|
||||||
|
ASMJIT_API virtual bool _tryUnuseVar(CompilerVar* v);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Memory operand or NULL.
|
||||||
|
Mem* _memOp;
|
||||||
|
//! @brief Variables (extracted from operands).
|
||||||
|
VarAllocRecord* _vars;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86CompilerJmpInst]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief @ref X86Compiler "jmp" instruction item.
|
||||||
|
struct X86CompilerJmpInst : public X86CompilerInst
|
||||||
|
{
|
||||||
|
ASMJIT_NO_COPY(X86CompilerJmpInst)
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API X86CompilerJmpInst(X86Compiler* x86Compiler, uint32_t code, Operand* opData, uint32_t opCount);
|
||||||
|
ASMJIT_API virtual ~X86CompilerJmpInst();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline X86CompilerJmpInst* getJumpNext() const
|
||||||
|
{ return _jumpNext; }
|
||||||
|
|
||||||
|
inline bool isTaken() const
|
||||||
|
{ return (_instFlags & kX86CompilerInstFlagIsTaken) != 0; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Interface]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual void prepare(CompilerContext& cc);
|
||||||
|
ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
|
||||||
|
ASMJIT_API virtual void emit(Assembler& a);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [DoJump]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API void doJump(CompilerContext& cc);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Jump]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API virtual CompilerTarget* getJumpTarget() const;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Jump target.
|
||||||
|
X86CompilerTarget* _jumpTarget;
|
||||||
|
//! @brief Next jump to the same target in a single linked list.
|
||||||
|
X86CompilerJmpInst *_jumpNext;
|
||||||
|
//! @brief State associated with the jump.
|
||||||
|
X86CompilerState* _state;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_X86_X86COMPILERITEM_H
|
|
@ -0,0 +1,304 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../x86/x86cpuinfo.h"
|
||||||
|
#include "../x86/x86defs.h"
|
||||||
|
|
||||||
|
// 2009-02-05: Thanks to Mike Tajmajer for VC7.1 compiler support. It shouldn't
|
||||||
|
// affect x64 compilation, because x64 compiler starts with VS2005 (VC8.0).
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# if _MSC_VER >= 1400
|
||||||
|
# include <intrin.h>
|
||||||
|
# endif // _MSC_VER >= 1400 (>= VS2005)
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86CpuVendor]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
struct X86CpuVendor
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
char text[12];
|
||||||
|
};
|
||||||
|
|
||||||
|
static const X86CpuVendor x86CpuVendor[] =
|
||||||
|
{
|
||||||
|
{ kCpuIntel , { 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'I', 'n', 't', 'e', 'l' } },
|
||||||
|
|
||||||
|
{ kCpuAmd , { 'A', 'u', 't', 'h', 'e', 'n', 't', 'i', 'c', 'A', 'M', 'D' } },
|
||||||
|
{ kCpuAmd , { 'A', 'M', 'D', 'i', 's', 'b', 'e', 't', 't', 'e', 'r', '!' } },
|
||||||
|
|
||||||
|
{ kCpuNSM , { 'G', 'e', 'o', 'd', 'e', ' ', 'b', 'y', ' ', 'N', 'S', 'C' } },
|
||||||
|
{ kCpuNSM , { 'C', 'y', 'r', 'i', 'x', 'I', 'n', 's', 't', 'e', 'a', 'd' } },
|
||||||
|
|
||||||
|
{ kCpuTransmeta, { 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'T', 'M', 'x', '8', '6' } },
|
||||||
|
{ kCpuTransmeta, { 'T', 'r', 'a', 'n', 's', 'm', 'e', 't', 'a', 'C', 'P', 'U' } },
|
||||||
|
|
||||||
|
{ kCpuVia , { 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 } },
|
||||||
|
{ kCpuVia , { 'C', 'e', 'n', 't', 'a', 'u', 'r', 'H', 'a', 'u', 'l', 's' } }
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool x86CpuVendorEq(const X86CpuVendor& info, const char* vendorString)
|
||||||
|
{
|
||||||
|
const uint32_t* a = reinterpret_cast<const uint32_t*>(info.text);
|
||||||
|
const uint32_t* b = reinterpret_cast<const uint32_t*>(vendorString);
|
||||||
|
|
||||||
|
return (a[0] == b[0]) &
|
||||||
|
(a[1] == b[1]) &
|
||||||
|
(a[2] == b[2]) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::x86CpuSimplifyBrandString]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
static inline void x86CpuSimplifyBrandString(char* s)
|
||||||
|
{
|
||||||
|
// Always clear the current character in the buffer. This ensures that there
|
||||||
|
// is no garbage after the string NULL terminator.
|
||||||
|
char* d = s;
|
||||||
|
|
||||||
|
char prev = 0;
|
||||||
|
char curr = s[0];
|
||||||
|
s[0] = '\0';
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (curr == 0) break;
|
||||||
|
|
||||||
|
if (curr == ' ')
|
||||||
|
{
|
||||||
|
if (prev == '@') goto _Skip;
|
||||||
|
if (s[1] == ' ' || s[1] == '@') goto _Skip;
|
||||||
|
}
|
||||||
|
|
||||||
|
d[0] = curr;
|
||||||
|
d++;
|
||||||
|
prev = curr;
|
||||||
|
|
||||||
|
_Skip:
|
||||||
|
curr = *++s;
|
||||||
|
s[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
d[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::x86CpuId]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// This is messy, I know. cpuid is implemented as intrinsic in VS2005, but
|
||||||
|
// we should support other compilers as well. Main problem is that MS compilers
|
||||||
|
// in 64-bit mode not allows to use inline assembler, so we need intrinsic and
|
||||||
|
// we need also asm version.
|
||||||
|
|
||||||
|
// x86CpuId() and detectCpuInfo() for x86 and x64 platforms begins here.
|
||||||
|
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
||||||
|
void x86CpuId(uint32_t in, X86CpuId* out)
|
||||||
|
{
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
|
// 2009-02-05: Thanks to Mike Tajmajer for supporting VC7.1 compiler.
|
||||||
|
// ASMJIT_X64 is here only for readibility, only VS2005 can compile 64-bit code.
|
||||||
|
# if _MSC_VER >= 1400 || defined(ASMJIT_X64)
|
||||||
|
// Done by intrinsics.
|
||||||
|
__cpuid(reinterpret_cast<int*>(out->i), in);
|
||||||
|
# else // _MSC_VER < 1400
|
||||||
|
uint32_t cpuid_in = in;
|
||||||
|
uint32_t* cpuid_out = out->i;
|
||||||
|
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
mov eax, cpuid_in
|
||||||
|
mov edi, cpuid_out
|
||||||
|
cpuid
|
||||||
|
mov dword ptr[edi + 0], eax
|
||||||
|
mov dword ptr[edi + 4], ebx
|
||||||
|
mov dword ptr[edi + 8], ecx
|
||||||
|
mov dword ptr[edi + 12], edx
|
||||||
|
}
|
||||||
|
# endif // _MSC_VER < 1400
|
||||||
|
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
|
||||||
|
// Note, need to preserve ebx/rbx register!
|
||||||
|
# if defined(ASMJIT_X86)
|
||||||
|
# define __myCpuId(a, b, c, d, inp) \
|
||||||
|
asm ("mov %%ebx, %%edi\n" \
|
||||||
|
"cpuid\n" \
|
||||||
|
"xchg %%edi, %%ebx\n" \
|
||||||
|
: "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
|
||||||
|
# else
|
||||||
|
# define __myCpuId(a, b, c, d, inp) \
|
||||||
|
asm ("mov %%rbx, %%rdi\n" \
|
||||||
|
"cpuid\n" \
|
||||||
|
"xchg %%rdi, %%rbx\n" \
|
||||||
|
: "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
|
||||||
|
# endif
|
||||||
|
__myCpuId(out->eax, out->ebx, out->ecx, out->edx, in);
|
||||||
|
|
||||||
|
#endif // Compiler #ifdef.
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::x86CpuDetect]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void x86CpuDetect(X86CpuInfo* out)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
X86CpuId regs;
|
||||||
|
|
||||||
|
// Clear everything except the '_size' member.
|
||||||
|
memset(reinterpret_cast<uint8_t*>(out) + sizeof(uint32_t),
|
||||||
|
0, sizeof(CpuInfo) - sizeof(uint32_t));
|
||||||
|
|
||||||
|
// Fill safe defaults.
|
||||||
|
memcpy(out->_vendorString, "Unknown", 8);
|
||||||
|
out->_numberOfProcessors = CpuInfo::detectNumberOfProcessors();
|
||||||
|
|
||||||
|
// Get vendor string/id.
|
||||||
|
x86CpuId(0, ®s);
|
||||||
|
|
||||||
|
memcpy(out->_vendorString, ®s.ebx, 4);
|
||||||
|
memcpy(out->_vendorString + 4, ®s.edx, 4);
|
||||||
|
memcpy(out->_vendorString + 8, ®s.ecx, 4);
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (x86CpuVendorEq(x86CpuVendor[i], out->_vendorString))
|
||||||
|
{
|
||||||
|
out->_vendorId = x86CpuVendor[i].id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get feature flags in ecx/edx, and family/model in eax.
|
||||||
|
x86CpuId(1, ®s);
|
||||||
|
|
||||||
|
// Fill family and model fields.
|
||||||
|
out->_family = (regs.eax >> 8) & 0x0F;
|
||||||
|
out->_model = (regs.eax >> 4) & 0x0F;
|
||||||
|
out->_stepping = (regs.eax ) & 0x0F;
|
||||||
|
|
||||||
|
// Use extended family and model fields.
|
||||||
|
if (out->_family == 0x0F)
|
||||||
|
{
|
||||||
|
out->_family += ((regs.eax >> 20) & 0xFF);
|
||||||
|
out->_model += ((regs.eax >> 16) & 0x0F) << 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->_processorType = ((regs.eax >> 12) & 0x03);
|
||||||
|
out->_brandIndex = ((regs.ebx ) & 0xFF);
|
||||||
|
out->_flushCacheLineSize = ((regs.ebx >> 8) & 0xFF) * 8;
|
||||||
|
out->_maxLogicalProcessors = ((regs.ebx >> 16) & 0xFF);
|
||||||
|
out->_apicPhysicalId = ((regs.ebx >> 24) & 0xFF);
|
||||||
|
|
||||||
|
if (regs.ecx & 0x00000001U) out->_features |= kX86FeatureSse3;
|
||||||
|
if (regs.ecx & 0x00000002U) out->_features |= kX86FeaturePclMulDQ;
|
||||||
|
if (regs.ecx & 0x00000008U) out->_features |= kX86FeatureMonitorMWait;
|
||||||
|
if (regs.ecx & 0x00000200U) out->_features |= kX86FeatureSsse3;
|
||||||
|
if (regs.ecx & 0x00002000U) out->_features |= kX86FeatureCmpXchg16B;
|
||||||
|
if (regs.ecx & 0x00080000U) out->_features |= kX86FeatureSse41;
|
||||||
|
if (regs.ecx & 0x00100000U) out->_features |= kX86FeatureSse42;
|
||||||
|
if (regs.ecx & 0x00400000U) out->_features |= kX86FeatureMovBE;
|
||||||
|
if (regs.ecx & 0x00800000U) out->_features |= kX86FeaturePopCnt;
|
||||||
|
if (regs.ecx & 0x10000000U) out->_features |= kX86FeatureAvx;
|
||||||
|
|
||||||
|
if (regs.edx & 0x00000010U) out->_features |= kX86FeatureRdtsc;
|
||||||
|
if (regs.edx & 0x00000100U) out->_features |= kX86FeatureCmpXchg8B;
|
||||||
|
if (regs.edx & 0x00008000U) out->_features |= kX86FeatureCMov;
|
||||||
|
if (regs.edx & 0x00800000U) out->_features |= kX86FeatureMmx;
|
||||||
|
if (regs.edx & 0x01000000U) out->_features |= kX86FeatureFXSR;
|
||||||
|
if (regs.edx & 0x02000000U) out->_features |= kX86FeatureSse | kX86FeatureMmxExt;
|
||||||
|
if (regs.edx & 0x04000000U) out->_features |= kX86FeatureSse | kX86FeatureSse2;
|
||||||
|
if (regs.edx & 0x10000000U) out->_features |= kX86FeatureMultiThreading;
|
||||||
|
|
||||||
|
if (out->_vendorId == kCpuAmd && (regs.edx & 0x10000000U))
|
||||||
|
{
|
||||||
|
// AMD sets Multithreading to ON if it has more cores.
|
||||||
|
if (out->_numberOfProcessors == 1) out->_numberOfProcessors = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This comment comes from V8 and I think that its important:
|
||||||
|
//
|
||||||
|
// Opteron Rev E has i bug in which on very rare occasions i locked
|
||||||
|
// instruction doesn't act as i read-acquire barrier if followed by i
|
||||||
|
// non-locked read-modify-write instruction. Rev F has this bug in
|
||||||
|
// pre-release versions, but not in versions released to customers,
|
||||||
|
// so we test only for Rev E, which is family 15, model 32..63 inclusive.
|
||||||
|
|
||||||
|
if (out->_vendorId == kCpuAmd && out->_family == 15 && out->_model >= 32 && out->_model <= 63)
|
||||||
|
{
|
||||||
|
out->_bugs |= kX86BugAmdLockMB;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calling cpuid with 0x80000000 as the in argument
|
||||||
|
// gets the number of valid extended IDs.
|
||||||
|
|
||||||
|
x86CpuId(0x80000000, ®s);
|
||||||
|
|
||||||
|
uint32_t exIds = regs.eax;
|
||||||
|
if (exIds > 0x80000004) exIds = 0x80000004;
|
||||||
|
|
||||||
|
uint32_t* brand = reinterpret_cast<uint32_t*>(out->_brandString);
|
||||||
|
|
||||||
|
for (i = 0x80000001; i <= exIds; i++)
|
||||||
|
{
|
||||||
|
x86CpuId(i, ®s);
|
||||||
|
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 0x80000001:
|
||||||
|
if (regs.ecx & 0x00000001U) out->_features |= kX86FeatureLahfSahf;
|
||||||
|
if (regs.ecx & 0x00000020U) out->_features |= kX86FeatureLzCnt;
|
||||||
|
if (regs.ecx & 0x00000040U) out->_features |= kX86FeatureSse4A;
|
||||||
|
if (regs.ecx & 0x00000080U) out->_features |= kX86FeatureMSse;
|
||||||
|
if (regs.ecx & 0x00000100U) out->_features |= kX86FeaturePrefetch;
|
||||||
|
|
||||||
|
if (regs.edx & 0x00100000U) out->_features |= kX86FeatureExecuteDisableBit;
|
||||||
|
if (regs.edx & 0x00200000U) out->_features |= kX86FeatureFFXSR;
|
||||||
|
if (regs.edx & 0x00400000U) out->_features |= kX86FeatureMmxExt;
|
||||||
|
if (regs.edx & 0x08000000U) out->_features |= kX86FeatureRdtscP;
|
||||||
|
if (regs.edx & 0x20000000U) out->_features |= kX86Feature64Bit;
|
||||||
|
if (regs.edx & 0x40000000U) out->_features |= kX86Feature3dNowExt | kX86FeatureMmxExt;
|
||||||
|
if (regs.edx & 0x80000000U) out->_features |= kX86Feature3dNow;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x80000002:
|
||||||
|
case 0x80000003:
|
||||||
|
case 0x80000004:
|
||||||
|
*brand++ = regs.eax;
|
||||||
|
*brand++ = regs.ebx;
|
||||||
|
*brand++ = regs.ecx;
|
||||||
|
*brand++ = regs.edx;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Additional features can be detected in the future.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simplify the brand string (remove unnecessary spaces to make it printable).
|
||||||
|
x86CpuSimplifyBrandString(out->_brandString);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // AsmJit
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,130 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_X86_X86CPUINFO_H
|
||||||
|
#define _ASMJIT_X86_X86CPUINFO_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/cpuinfo.h"
|
||||||
|
#include "../core/defs.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_X86
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86CpuId]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief X86 CpuId output.
|
||||||
|
union X86CpuId
|
||||||
|
{
|
||||||
|
//! @brief EAX/EBX/ECX/EDX output.
|
||||||
|
uint32_t i[4];
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
//! @brief EAX output.
|
||||||
|
uint32_t eax;
|
||||||
|
//! @brief EBX output.
|
||||||
|
uint32_t ebx;
|
||||||
|
//! @brief ECX output.
|
||||||
|
uint32_t ecx;
|
||||||
|
//! @brief EDX output.
|
||||||
|
uint32_t edx;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86CpuInfo]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
struct X86CpuInfo : public CpuInfo
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline X86CpuInfo(uint32_t size = sizeof(X86CpuInfo)) :
|
||||||
|
CpuInfo(size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get processor type.
|
||||||
|
inline uint32_t getProcessorType() const { return _processorType; }
|
||||||
|
//! @brief Get brand index.
|
||||||
|
inline uint32_t getBrandIndex() const { return _brandIndex; }
|
||||||
|
//! @brief Get flush cache line size.
|
||||||
|
inline uint32_t getFlushCacheLineSize() const { return _flushCacheLineSize; }
|
||||||
|
//! @brief Get maximum logical processors count.
|
||||||
|
inline uint32_t getMaxLogicalProcessors() const { return _maxLogicalProcessors; }
|
||||||
|
//! @brief Get APIC physical ID.
|
||||||
|
inline uint32_t getApicPhysicalId() const { return _apicPhysicalId; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Statics]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get global instance of @ref X86CpuInfo.
|
||||||
|
static inline const X86CpuInfo* getGlobal()
|
||||||
|
{ return static_cast<const X86CpuInfo*>(CpuInfo::getGlobal()); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Processor type.
|
||||||
|
uint32_t _processorType;
|
||||||
|
//! @brief Brand index.
|
||||||
|
uint32_t _brandIndex;
|
||||||
|
//! @brief Flush cache line size in bytes.
|
||||||
|
uint32_t _flushCacheLineSize;
|
||||||
|
//! @brief Maximum number of addressable IDs for logical processors.
|
||||||
|
uint32_t _maxLogicalProcessors;
|
||||||
|
//! @brief Initial APIC ID.
|
||||||
|
uint32_t _apicPhysicalId;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::x86CpuId]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X86) || defined(ASMJIT_X64)
|
||||||
|
//! @brief Calls CPUID instruction with eax == @a in and stores output to @a out.
|
||||||
|
//!
|
||||||
|
//! @c cpuid() function has one input parameter that is passed to cpuid through
|
||||||
|
//! eax register and results in four output values representing result of cpuid
|
||||||
|
//! instruction (eax, ebx, ecx and edx registers).
|
||||||
|
ASMJIT_API void x86CpuId(uint32_t in, X86CpuId* out);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::x86CpuDetect]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Detect CPU features to CpuInfo structure @a out.
|
||||||
|
//!
|
||||||
|
//! @sa @c CpuInfo.
|
||||||
|
ASMJIT_API void x86CpuDetect(X86CpuInfo* out);
|
||||||
|
#endif // ASMJIT_X86 || ASMJIT_X64
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_X86_X86CPUINFO_H
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,645 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/assert.h"
|
||||||
|
#include "../core/intutil.h"
|
||||||
|
#include "../core/stringutil.h"
|
||||||
|
|
||||||
|
#include "../x86/x86defs.h"
|
||||||
|
#include "../x86/x86func.h"
|
||||||
|
#include "../x86/x86util.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86FuncDecl - Accessors]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
uint32_t X86FuncDecl::findArgumentByRegCode(uint32_t regCode) const
|
||||||
|
{
|
||||||
|
uint32_t type = regCode & kRegTypeMask;
|
||||||
|
uint32_t idx = regCode & kRegIndexMask;
|
||||||
|
|
||||||
|
uint32_t clazz;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case kX86RegTypeGpd:
|
||||||
|
case kX86RegTypeGpq:
|
||||||
|
clazz = kX86VarClassGp;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kX86RegTypeX87:
|
||||||
|
clazz = kX86VarClassX87;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kX86RegTypeMm:
|
||||||
|
clazz = kX86VarClassMm;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kX86RegTypeXmm:
|
||||||
|
clazz = kX86VarClassXmm;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return kInvalidValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < _argumentsCount; i++)
|
||||||
|
{
|
||||||
|
const FuncArg& arg = _arguments[i];
|
||||||
|
|
||||||
|
if (arg.getRegIndex() == idx && (X86Util::getVarClassFromVarType(arg.getVarType()) & clazz) != 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kInvalidValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86FuncDecl - SetPrototype - InitCallingConvention]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
static void X86FuncDecl_initCallingConvention(X86FuncDecl* self, uint32_t convention)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Inir]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
self->_convention = convention;
|
||||||
|
self->_calleePopsStack = false;
|
||||||
|
self->_argumentsDirection = kFuncArgsRTL;
|
||||||
|
|
||||||
|
for (i = 0; i < ASMJIT_ARRAY_SIZE(self->_gpList); i++)
|
||||||
|
self->_gpList[i] = kRegIndexInvalid;
|
||||||
|
|
||||||
|
for (i = 0; i < ASMJIT_ARRAY_SIZE(self->_xmmList); i++)
|
||||||
|
self->_xmmList[i] = kRegIndexInvalid;
|
||||||
|
|
||||||
|
self->_gpListMask = 0x0;
|
||||||
|
self->_mmListMask = 0x0;
|
||||||
|
self->_xmmListMask = 0x0;
|
||||||
|
|
||||||
|
self->_gpPreservedMask = 0x0;
|
||||||
|
self->_mmPreservedMask = 0x0;
|
||||||
|
self->_xmmPreservedMask = 0x0;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [X86 Calling Conventions]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X86)
|
||||||
|
self->_gpPreservedMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEbx) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEsp) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEbp) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEsi) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEdi));
|
||||||
|
self->_xmmPreservedMask = 0;
|
||||||
|
|
||||||
|
switch (convention)
|
||||||
|
{
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [CDecl]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
case kX86FuncConvCDecl:
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [StdCall]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
case kX86FuncConvStdCall:
|
||||||
|
self->_calleePopsStack = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [MS-ThisCall]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
case kX86FuncConvMsThisCall:
|
||||||
|
self->_calleePopsStack = true;
|
||||||
|
|
||||||
|
self->_gpList[0] = kX86RegIndexEcx;
|
||||||
|
|
||||||
|
self->_gpListMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEcx));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [MS-FastCall]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
case kX86FuncConvMsFastCall:
|
||||||
|
self->_calleePopsStack = true;
|
||||||
|
|
||||||
|
self->_gpList[0] = kX86RegIndexEcx;
|
||||||
|
self->_gpList[1] = kX86RegIndexEdx;
|
||||||
|
|
||||||
|
self->_gpListMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEcx) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEdx));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [Borland-FastCall]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
case kX86FuncConvBorlandFastCall:
|
||||||
|
self->_calleePopsStack = true;
|
||||||
|
self->_argumentsDirection = kFuncArgsLTR;
|
||||||
|
|
||||||
|
self->_gpList[0] = kX86RegIndexEax;
|
||||||
|
self->_gpList[1] = kX86RegIndexEdx;
|
||||||
|
self->_gpList[2] = kX86RegIndexEcx;
|
||||||
|
|
||||||
|
self->_gpListMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEax) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEdx) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEcx));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [Gcc-FastCall]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
case kX86FuncConvGccFastCall:
|
||||||
|
self->_calleePopsStack = true;
|
||||||
|
|
||||||
|
self->_gpList[0] = kX86RegIndexEcx;
|
||||||
|
self->_gpList[1] = kX86RegIndexEdx;
|
||||||
|
|
||||||
|
self->_gpListMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEcx) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEdx));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [Gcc-Regparm(1)]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
case kX86FuncConvGccRegParm1:
|
||||||
|
self->_calleePopsStack = false;
|
||||||
|
|
||||||
|
self->_gpList[0] = kX86RegIndexEax;
|
||||||
|
self->_gpListMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEax));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [Gcc-Regparm(2)]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
case kX86FuncConvGccRegParm2:
|
||||||
|
self->_calleePopsStack = false;
|
||||||
|
|
||||||
|
self->_gpList[0] = kX86RegIndexEax;
|
||||||
|
self->_gpList[1] = kX86RegIndexEdx;
|
||||||
|
|
||||||
|
self->_gpListMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEax) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEdx));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [Gcc-Regparm(3)]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
case kX86FuncConvGccRegParm3:
|
||||||
|
self->_calleePopsStack = false;
|
||||||
|
|
||||||
|
self->_gpList[0] = kX86RegIndexEax;
|
||||||
|
self->_gpList[1] = kX86RegIndexEdx;
|
||||||
|
self->_gpList[2] = kX86RegIndexEcx;
|
||||||
|
|
||||||
|
self->_gpListMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEax) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEdx) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexEcx));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [Illegal]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Illegal calling convention.
|
||||||
|
ASMJIT_ASSERT(0);
|
||||||
|
}
|
||||||
|
#endif // ASMJIT_X86
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [X64 Calling Conventions]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X64)
|
||||||
|
switch (convention)
|
||||||
|
{
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [X64-Windows]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
case kX86FuncConvX64W:
|
||||||
|
self->_gpList[0] = kX86RegIndexRcx;
|
||||||
|
self->_gpList[1] = kX86RegIndexRdx;
|
||||||
|
self->_gpList[2] = kX86RegIndexR8;
|
||||||
|
self->_gpList[3] = kX86RegIndexR9;
|
||||||
|
|
||||||
|
self->_xmmList[0] = kX86RegIndexXmm0;
|
||||||
|
self->_xmmList[1] = kX86RegIndexXmm1;
|
||||||
|
self->_xmmList[2] = kX86RegIndexXmm2;
|
||||||
|
self->_xmmList[3] = kX86RegIndexXmm3;
|
||||||
|
|
||||||
|
self->_gpListMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRcx ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRdx ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexR8 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexR9 ));
|
||||||
|
|
||||||
|
self->_xmmListMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm0 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm1 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm2 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm3 ));
|
||||||
|
|
||||||
|
self->_gpPreservedMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRbx ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRsp ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRbp ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRsi ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRdi ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexR12 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexR13 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexR14 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexR15 ));
|
||||||
|
|
||||||
|
self->_xmmPreservedMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm6 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm7 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm8 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm9 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm10) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm11) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm12) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm13) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm14) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm15));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [X64-Unix]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
case kX86FuncConvX64U:
|
||||||
|
self->_gpList[0] = kX86RegIndexRdi;
|
||||||
|
self->_gpList[1] = kX86RegIndexRsi;
|
||||||
|
self->_gpList[2] = kX86RegIndexRdx;
|
||||||
|
self->_gpList[3] = kX86RegIndexRcx;
|
||||||
|
self->_gpList[4] = kX86RegIndexR8;
|
||||||
|
self->_gpList[5] = kX86RegIndexR9;
|
||||||
|
|
||||||
|
self->_xmmList[0] = kX86RegIndexXmm0;
|
||||||
|
self->_xmmList[1] = kX86RegIndexXmm1;
|
||||||
|
self->_xmmList[2] = kX86RegIndexXmm2;
|
||||||
|
self->_xmmList[3] = kX86RegIndexXmm3;
|
||||||
|
self->_xmmList[4] = kX86RegIndexXmm4;
|
||||||
|
self->_xmmList[5] = kX86RegIndexXmm5;
|
||||||
|
self->_xmmList[6] = kX86RegIndexXmm6;
|
||||||
|
self->_xmmList[7] = kX86RegIndexXmm7;
|
||||||
|
|
||||||
|
self->_gpListMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRdi ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRsi ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRdx ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRcx ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexR8 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexR9 ));
|
||||||
|
|
||||||
|
self->_xmmListMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm0 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm1 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm2 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm3 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm4 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm5 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm6 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexXmm7 ));
|
||||||
|
|
||||||
|
self->_gpPreservedMask = static_cast<uint16_t>(
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRbx ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRsp ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexRbp ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexR12 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexR13 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexR14 ) |
|
||||||
|
IntUtil::maskFromIndex(kX86RegIndexR15 ));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// [Illegal]
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Illegal calling convention.
|
||||||
|
ASMJIT_ASSERT(0);
|
||||||
|
}
|
||||||
|
#endif // ASMJIT_X64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86FuncDecl - SetPrototype - InitDefinition]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
static void X86FuncDecl_initDefinition(X86FuncDecl* self,
|
||||||
|
uint32_t returnType, const uint32_t* argumentsData, uint32_t argumentsCount)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(argumentsCount <= kFuncArgsMax);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Init]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int32_t i = 0;
|
||||||
|
int32_t gpPos = 0;
|
||||||
|
int32_t xmmPos = 0;
|
||||||
|
int32_t stackOffset = 0;
|
||||||
|
|
||||||
|
self->_returnType = returnType;
|
||||||
|
self->_argumentsCount = static_cast<uint8_t>(argumentsCount);
|
||||||
|
|
||||||
|
while (i < static_cast<int32_t>(argumentsCount))
|
||||||
|
{
|
||||||
|
FuncArg& arg = self->_arguments[i];
|
||||||
|
|
||||||
|
arg._varType = static_cast<uint8_t>(argumentsData[i]);
|
||||||
|
arg._regIndex = kRegIndexInvalid;
|
||||||
|
arg._stackOffset = kFuncStackInvalid;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < kFuncArgsMax)
|
||||||
|
{
|
||||||
|
FuncArg& arg = self->_arguments[i];
|
||||||
|
arg.reset();
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->_argumentsStackSize = 0;
|
||||||
|
self->_gpArgumentsMask = 0x0;
|
||||||
|
self->_mmArgumentsMask = 0x0;
|
||||||
|
self->_xmmArgumentsMask = 0x0;
|
||||||
|
|
||||||
|
if (self->_argumentsCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [X86 Calling Conventions (32-bit)]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X86)
|
||||||
|
// Register arguments (Integer), always left-to-right.
|
||||||
|
for (i = 0; i != argumentsCount; i++)
|
||||||
|
{
|
||||||
|
FuncArg& arg = self->_arguments[i];
|
||||||
|
uint32_t varType = arg.getVarType();
|
||||||
|
|
||||||
|
if (X86Util::isVarTypeInt(varType) && gpPos < 16 && self->_gpList[gpPos] != kRegIndexInvalid)
|
||||||
|
{
|
||||||
|
arg._regIndex = self->_gpList[gpPos++];
|
||||||
|
self->_gpArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack arguments.
|
||||||
|
int32_t iStart = static_cast<int32_t>(argumentsCount - 1);
|
||||||
|
int32_t iEnd = -1;
|
||||||
|
int32_t iStep = -1;
|
||||||
|
|
||||||
|
if (self->_argumentsDirection == kFuncArgsLTR)
|
||||||
|
{
|
||||||
|
iStart = 0;
|
||||||
|
iEnd = static_cast<int32_t>(argumentsCount);
|
||||||
|
iStep = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = iStart; i != iEnd; i += iStep)
|
||||||
|
{
|
||||||
|
FuncArg& arg = self->_arguments[i];
|
||||||
|
uint32_t varType = arg.getVarType();
|
||||||
|
|
||||||
|
if (arg.hasRegIndex())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (X86Util::isVarTypeInt(varType))
|
||||||
|
{
|
||||||
|
stackOffset -= 4;
|
||||||
|
arg._stackOffset = static_cast<int16_t>(stackOffset);
|
||||||
|
}
|
||||||
|
else if (X86Util::isVarTypeFloat(varType))
|
||||||
|
{
|
||||||
|
int32_t size = static_cast<int32_t>(x86VarInfo[varType].getSize());
|
||||||
|
stackOffset -= size;
|
||||||
|
arg._stackOffset = static_cast<int16_t>(stackOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // ASMJIT_X86
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [X64 Calling Conventions (64-bit)]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X64)
|
||||||
|
// Windows 64-bit specific.
|
||||||
|
if (self->_convention == kX86FuncConvX64W)
|
||||||
|
{
|
||||||
|
int32_t max = argumentsCount < 4 ? argumentsCount : 4;
|
||||||
|
|
||||||
|
// Register arguments (Integer / FP), always left-to-right.
|
||||||
|
for (i = 0; i != max; i++)
|
||||||
|
{
|
||||||
|
FuncArg& arg = self->_arguments[i];
|
||||||
|
uint32_t varType = arg.getVarType();
|
||||||
|
|
||||||
|
if (X86Util::isVarTypeInt(varType))
|
||||||
|
{
|
||||||
|
arg._regIndex = self->_gpList[i];
|
||||||
|
self->_gpArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
|
||||||
|
}
|
||||||
|
else if (X86Util::isVarTypeFloat(varType))
|
||||||
|
{
|
||||||
|
arg._regIndex = self->_xmmList[i];
|
||||||
|
self->_xmmArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack arguments (always right-to-left).
|
||||||
|
for (i = argumentsCount - 1; i != -1; i--)
|
||||||
|
{
|
||||||
|
FuncArg& arg = self->_arguments[i];
|
||||||
|
uint32_t varType = arg.getVarType();
|
||||||
|
|
||||||
|
if (arg.isAssigned())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (X86Util::isVarTypeInt(varType))
|
||||||
|
{
|
||||||
|
stackOffset -= 8; // Always 8 bytes.
|
||||||
|
arg._stackOffset = stackOffset;
|
||||||
|
}
|
||||||
|
else if (X86Util::isVarTypeFloat(varType))
|
||||||
|
{
|
||||||
|
int32_t size = static_cast<int32_t>(x86VarInfo[varType].getSize());
|
||||||
|
stackOffset -= size;
|
||||||
|
arg._stackOffset = stackOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 32 bytes shadow space (X64W calling convention specific).
|
||||||
|
stackOffset -= 4 * 8;
|
||||||
|
}
|
||||||
|
// Linux/Unix 64-bit (AMD64 calling convention).
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Register arguments (Integer), always left-to-right.
|
||||||
|
for (i = 0; i != static_cast<int32_t>(argumentsCount); i++)
|
||||||
|
{
|
||||||
|
FuncArg& arg = self->_arguments[i];
|
||||||
|
uint32_t varType = arg.getVarType();
|
||||||
|
|
||||||
|
if (X86Util::isVarTypeInt(varType) && gpPos < 32 && self->_gpList[gpPos] != kRegIndexInvalid)
|
||||||
|
{
|
||||||
|
arg._regIndex = self->_gpList[gpPos++];
|
||||||
|
self->_gpArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register arguments (FP), always left-to-right.
|
||||||
|
for (i = 0; i != static_cast<int32_t>(argumentsCount); i++)
|
||||||
|
{
|
||||||
|
FuncArg& arg = self->_arguments[i];
|
||||||
|
uint32_t varType = arg.getVarType();
|
||||||
|
|
||||||
|
if (X86Util::isVarTypeFloat(varType))
|
||||||
|
{
|
||||||
|
arg._regIndex = self->_xmmList[xmmPos++];
|
||||||
|
self->_xmmArgumentsMask |= static_cast<uint16_t>(IntUtil::maskFromIndex(arg.getRegIndex()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack arguments.
|
||||||
|
for (i = argumentsCount - 1; i != -1; i--)
|
||||||
|
{
|
||||||
|
FuncArg& arg = self->_arguments[i];
|
||||||
|
uint32_t varType = arg.getVarType();
|
||||||
|
|
||||||
|
if (arg.isAssigned())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (X86Util::isVarTypeInt(varType))
|
||||||
|
{
|
||||||
|
stackOffset -= 8;
|
||||||
|
arg._stackOffset = static_cast<int16_t>(stackOffset);
|
||||||
|
}
|
||||||
|
else if (X86Util::isVarTypeFloat(varType))
|
||||||
|
{
|
||||||
|
int32_t size = (int32_t)x86VarInfo[varType].getSize();
|
||||||
|
|
||||||
|
stackOffset -= size;
|
||||||
|
arg._stackOffset = static_cast<int16_t>(stackOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // ASMJIT_X64
|
||||||
|
|
||||||
|
// Modify stack offset (all function parameters will be in positive stack
|
||||||
|
// offset that is never zero).
|
||||||
|
for (i = 0; i < (int32_t)argumentsCount; i++)
|
||||||
|
{
|
||||||
|
FuncArg& arg = self->_arguments[i];
|
||||||
|
if (!arg.hasRegIndex())
|
||||||
|
{
|
||||||
|
arg._stackOffset += static_cast<uint16_t>(static_cast<int32_t>(sizeof(uintptr_t)) - stackOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self->_argumentsStackSize = (uint32_t)(-stackOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86FuncDecl::setPrototype(uint32_t convention, uint32_t returnType, const uint32_t* arguments, uint32_t argumentsCount)
|
||||||
|
{
|
||||||
|
// Limit maximum function arguments to kFuncArgsMax.
|
||||||
|
if (argumentsCount > kFuncArgsMax)
|
||||||
|
argumentsCount = kFuncArgsMax;
|
||||||
|
|
||||||
|
X86FuncDecl_initCallingConvention(this, convention);
|
||||||
|
X86FuncDecl_initDefinition(this, returnType, arguments, argumentsCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86FuncDecl - Reset]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void X86FuncDecl::reset()
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Core]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
_returnType = kVarTypeInvalid;
|
||||||
|
_argumentsCount = 0;
|
||||||
|
|
||||||
|
_reserved0[0] = 0;
|
||||||
|
_reserved0[1] = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ASMJIT_ARRAY_SIZE(_arguments); i++)
|
||||||
|
_arguments[i].reset();
|
||||||
|
|
||||||
|
_argumentsStackSize = 0;
|
||||||
|
_gpArgumentsMask = 0x0;
|
||||||
|
_mmArgumentsMask = 0x0;
|
||||||
|
_xmmArgumentsMask = 0x0;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Convention]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
_convention = kFuncConvNone;
|
||||||
|
_calleePopsStack = false;
|
||||||
|
_argumentsDirection = kFuncArgsRTL;
|
||||||
|
_reserved1 = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ASMJIT_ARRAY_SIZE(_gpList); i++)
|
||||||
|
_gpList[i] = kRegIndexInvalid;
|
||||||
|
|
||||||
|
for (i = 0; i < ASMJIT_ARRAY_SIZE(_xmmList); i++)
|
||||||
|
_xmmList[i] = kRegIndexInvalid;
|
||||||
|
|
||||||
|
_gpListMask = 0x0;
|
||||||
|
_mmListMask = 0x0;
|
||||||
|
_xmmListMask = 0x0;
|
||||||
|
|
||||||
|
_gpPreservedMask = 0x0;
|
||||||
|
_mmPreservedMask = 0x0;
|
||||||
|
_xmmPreservedMask = 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,257 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_X86_X86FUNC_H
|
||||||
|
#define _ASMJIT_X86_X86FUNC_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../core/defs.h"
|
||||||
|
#include "../core/func.h"
|
||||||
|
|
||||||
|
#include "../x86/x86defs.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_X86
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::TypeId]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
ASMJIT_DECLARE_TYPE_CORE(kX86VarTypeIntPtr);
|
||||||
|
ASMJIT_DECLARE_TYPE_ID(void, kVarTypeInvalid);
|
||||||
|
ASMJIT_DECLARE_TYPE_ID(Void, kVarTypeInvalid);
|
||||||
|
|
||||||
|
ASMJIT_DECLARE_TYPE_ID(int8_t, kX86VarTypeGpd);
|
||||||
|
ASMJIT_DECLARE_TYPE_ID(uint8_t, kX86VarTypeGpd);
|
||||||
|
|
||||||
|
ASMJIT_DECLARE_TYPE_ID(int16_t, kX86VarTypeGpd);
|
||||||
|
ASMJIT_DECLARE_TYPE_ID(uint16_t, kX86VarTypeGpd);
|
||||||
|
|
||||||
|
ASMJIT_DECLARE_TYPE_ID(int32_t, kX86VarTypeGpd);
|
||||||
|
ASMJIT_DECLARE_TYPE_ID(uint32_t, kX86VarTypeGpd);
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X64)
|
||||||
|
ASMJIT_DECLARE_TYPE_ID(int64_t, kX86VarTypeGpq);
|
||||||
|
ASMJIT_DECLARE_TYPE_ID(uint64_t, kX86VarTypeGpq);
|
||||||
|
#endif // ASMJIT_X64
|
||||||
|
|
||||||
|
ASMJIT_DECLARE_TYPE_ID(float, kX86VarTypeFloat);
|
||||||
|
ASMJIT_DECLARE_TYPE_ID(double, kX86VarTypeDouble);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86FuncDecl]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief X86 function, including calling convention, arguments and their
|
||||||
|
//! register indices or stack positions.
|
||||||
|
struct X86FuncDecl : public FuncDecl
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Construction / Destruction]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Create a new @ref FunctionX86 instance.
|
||||||
|
inline X86FuncDecl()
|
||||||
|
{ reset(); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors - Core]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get stack size needed for function arguments passed on the stack.
|
||||||
|
inline uint32_t getArgumentsStackSize() const
|
||||||
|
{ return _argumentsStackSize; }
|
||||||
|
|
||||||
|
//! @brief Get bit-mask of GP registers used to pass function arguments.
|
||||||
|
inline uint32_t getGpArgumentsMask() const
|
||||||
|
{ return _gpArgumentsMask; }
|
||||||
|
|
||||||
|
//! @brief Get bit-mask of MM registers used to pass function arguments.
|
||||||
|
inline uint32_t getMmArgumentsMask() const
|
||||||
|
{ return _mmArgumentsMask; }
|
||||||
|
|
||||||
|
//! @brief Get bit-mask of XMM registers used to pass function arguments.
|
||||||
|
inline uint32_t getXmmArgumentsMask() const
|
||||||
|
{ return _xmmArgumentsMask; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Accessors - Convention]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get function calling convention, see @c kX86FuncConv.
|
||||||
|
inline uint32_t getConvention() const
|
||||||
|
{ return _convention; }
|
||||||
|
|
||||||
|
//! @brief Get whether the callee pops the stack.
|
||||||
|
inline uint32_t getCalleePopsStack() const
|
||||||
|
{ return _calleePopsStack; }
|
||||||
|
|
||||||
|
//! @brief Get direction of arguments passed on the stack.
|
||||||
|
//!
|
||||||
|
//! Direction should be always @c kFuncArgsRTL.
|
||||||
|
//!
|
||||||
|
//! @note This is related to used calling convention, it's not affected by
|
||||||
|
//! number of function arguments or their types.
|
||||||
|
inline uint32_t getArgumentsDirection() const
|
||||||
|
{ return _argumentsDirection; }
|
||||||
|
|
||||||
|
//! @brief Get registers used to pass first integer parameters by current
|
||||||
|
//! calling convention.
|
||||||
|
//!
|
||||||
|
//! @note This is related to used calling convention, it's not affected by
|
||||||
|
//! number of function arguments or their types.
|
||||||
|
inline const uint8_t* getGpList() const
|
||||||
|
{ return _gpList; }
|
||||||
|
|
||||||
|
//! @brief Get registers used to pass first SP-FP or DP-FPparameters by
|
||||||
|
//! current calling convention.
|
||||||
|
//!
|
||||||
|
//! @note This is related to used calling convention, it's not affected by
|
||||||
|
//! number of function arguments or their types.
|
||||||
|
inline const uint8_t* getXmmList() const
|
||||||
|
{ return _xmmList; }
|
||||||
|
|
||||||
|
//! @brief Get bit-mask of GP registers which might be used for arguments.
|
||||||
|
inline uint32_t getGpListMask() const
|
||||||
|
{ return _gpListMask; }
|
||||||
|
|
||||||
|
//! @brief Get bit-mask of MM registers which might be used for arguments.
|
||||||
|
inline uint32_t getMmListMask() const
|
||||||
|
{ return _mmListMask; }
|
||||||
|
|
||||||
|
//! @brief Get bit-mask of XMM registers which might be used for arguments.
|
||||||
|
inline uint32_t getXmmListMask() const
|
||||||
|
{ return _xmmListMask; }
|
||||||
|
|
||||||
|
//! @brief Get bit-mask of general purpose registers that's preserved
|
||||||
|
//! (non-volatile).
|
||||||
|
//!
|
||||||
|
//! @note This is related to used calling convention, it's not affected by
|
||||||
|
//! number of function arguments or their types.
|
||||||
|
inline uint32_t getGpPreservedMask() const
|
||||||
|
{ return _gpPreservedMask; }
|
||||||
|
|
||||||
|
//! @brief Get bit-mask of MM registers that's preserved (non-volatile).
|
||||||
|
//!
|
||||||
|
//! @note No standardized calling function is not preserving MM registers.
|
||||||
|
//! This member is here for extension writers who need for some reason custom
|
||||||
|
//! calling convention that can be called through code generated by AsmJit
|
||||||
|
//! (or other runtime code generator).
|
||||||
|
inline uint32_t getMmPreservedMask() const
|
||||||
|
{ return _mmPreservedMask; }
|
||||||
|
|
||||||
|
//! @brief Get bit-mask of XMM registers that's preserved (non-volatile).
|
||||||
|
//!
|
||||||
|
//! @note This is related to used calling convention, it's not affected by
|
||||||
|
//! number of function arguments or their types.
|
||||||
|
inline uint32_t getXmmPreservedMask() const
|
||||||
|
{ return _xmmPreservedMask; }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Methods]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Find argument ID by the register code.
|
||||||
|
ASMJIT_API uint32_t findArgumentByRegCode(uint32_t regCode) const;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [SetPrototype]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Set function prototype.
|
||||||
|
//!
|
||||||
|
//! This will set function calling convention and setup arguments variables.
|
||||||
|
//!
|
||||||
|
//! @note This function will allocate variables, it can be called only once.
|
||||||
|
ASMJIT_API void setPrototype(uint32_t convention, uint32_t returnType, const uint32_t* arguments, uint32_t argumentsCount);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Reset]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASMJIT_API void reset();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Members - Core]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Count of bytes consumed by arguments on the stack.
|
||||||
|
uint16_t _argumentsStackSize;
|
||||||
|
//! @brief Bitmask for GP registers used as passed function arguments.
|
||||||
|
uint16_t _gpArgumentsMask;
|
||||||
|
//! @brief Bitmask for MM registers used as passed function arguments.
|
||||||
|
uint16_t _mmArgumentsMask;
|
||||||
|
//! @brief Bitmask for XMM registers used as passed function arguments.
|
||||||
|
uint16_t _xmmArgumentsMask;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Membes - Convention]
|
||||||
|
//
|
||||||
|
// This section doesn't depend on function arguments or return type. It
|
||||||
|
// depends only on function calling convention and it's filled according to
|
||||||
|
// that value.
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Calling convention.
|
||||||
|
uint8_t _convention;
|
||||||
|
//! @brief Whether a callee pops stack.
|
||||||
|
uint8_t _calleePopsStack;
|
||||||
|
//! @brief Direction for arguments passed on the stack, see @c kFuncArgsDirection.
|
||||||
|
uint8_t _argumentsDirection;
|
||||||
|
//! @brief Reserved for future use #1 (alignment).
|
||||||
|
uint8_t _reserved1;
|
||||||
|
|
||||||
|
//! @brief List of register IDs used for GP arguments (order is important).
|
||||||
|
//!
|
||||||
|
//! @note All registers in _gpList are also specified in @ref _gpListMask.
|
||||||
|
//! Unused fields are filled by @ref kRegIndexInvalid.
|
||||||
|
uint8_t _gpList[16];
|
||||||
|
//! @brief List of register IDs used for XMM arguments (order is important).
|
||||||
|
//!
|
||||||
|
//! @note All registers in _gpList are also specified in @ref _xmmListMask.
|
||||||
|
//! Unused fields are filled by @ref kRegIndexInvalid.
|
||||||
|
uint8_t _xmmList[16];
|
||||||
|
|
||||||
|
//! @brief Bitmask for GP registers which might be used by arguments.
|
||||||
|
//!
|
||||||
|
//! @note All registers in _gpListMask are also specified in @ref _gpList.
|
||||||
|
uint16_t _gpListMask;
|
||||||
|
//! @brief Bitmask for MM registers which might be used by arguments.
|
||||||
|
uint16_t _mmListMask;
|
||||||
|
//! @brief Bitmask for XMM registers which might be used by arguments.
|
||||||
|
//!
|
||||||
|
//! @note All registers in _xmmListMask are also specified in @ref _xmmList.
|
||||||
|
uint16_t _xmmListMask;
|
||||||
|
|
||||||
|
//! @brief Bitmask for GP registers preserved across the function call.
|
||||||
|
//!
|
||||||
|
//! @note Preserved register mask is complement to @ref _gpListMask.
|
||||||
|
uint16_t _gpPreservedMask;
|
||||||
|
//! @brief Bitmask for MM registers preserved across the function call.
|
||||||
|
//!
|
||||||
|
//! @note Preserved register mask is complement to @ref _mmListMask.
|
||||||
|
uint16_t _mmPreservedMask;
|
||||||
|
//! @brief Bitmask for XMM registers preserved across the function call.
|
||||||
|
//!
|
||||||
|
//! @note Preserved register mask is complement to @ref _xmmListMask.
|
||||||
|
uint16_t _xmmPreservedMask;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_X86_X86FUNC_H
|
|
@ -0,0 +1,385 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../x86/x86defs.h"
|
||||||
|
#include "../x86/x86operand.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Registers - no_reg]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
const GpReg no_reg(_Initialize(), kInvalidValue);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Registers - 8-bit]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
const GpReg al(_Initialize(), kX86RegAl);
|
||||||
|
const GpReg cl(_Initialize(), kX86RegCl);
|
||||||
|
const GpReg dl(_Initialize(), kX86RegDl);
|
||||||
|
const GpReg bl(_Initialize(), kX86RegBl);
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X64)
|
||||||
|
const GpReg spl(_Initialize(), kX86RegSpl);
|
||||||
|
const GpReg bpl(_Initialize(), kX86RegBpl);
|
||||||
|
const GpReg sil(_Initialize(), kX86RegSil);
|
||||||
|
const GpReg dil(_Initialize(), kX86RegDil);
|
||||||
|
|
||||||
|
const GpReg r8b(_Initialize(), kX86RegR8b);
|
||||||
|
const GpReg r9b(_Initialize(), kX86RegR9b);
|
||||||
|
const GpReg r10b(_Initialize(), kX86RegR10b);
|
||||||
|
const GpReg r11b(_Initialize(), kX86RegR11b);
|
||||||
|
const GpReg r12b(_Initialize(), kX86RegR12b);
|
||||||
|
const GpReg r13b(_Initialize(), kX86RegR13b);
|
||||||
|
const GpReg r14b(_Initialize(), kX86RegR14b);
|
||||||
|
const GpReg r15b(_Initialize(), kX86RegR15b);
|
||||||
|
#endif // ASMJIT_X64
|
||||||
|
|
||||||
|
const GpReg ah(_Initialize(), kX86RegAh);
|
||||||
|
const GpReg ch(_Initialize(), kX86RegCh);
|
||||||
|
const GpReg dh(_Initialize(), kX86RegDh);
|
||||||
|
const GpReg bh(_Initialize(), kX86RegBh);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Registers - 16-bit]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
const GpReg ax(_Initialize(), kX86RegAx);
|
||||||
|
const GpReg cx(_Initialize(), kX86RegCx);
|
||||||
|
const GpReg dx(_Initialize(), kX86RegDx);
|
||||||
|
const GpReg bx(_Initialize(), kX86RegBx);
|
||||||
|
const GpReg sp(_Initialize(), kX86RegSp);
|
||||||
|
const GpReg bp(_Initialize(), kX86RegBp);
|
||||||
|
const GpReg si(_Initialize(), kX86RegSi);
|
||||||
|
const GpReg di(_Initialize(), kX86RegDi);
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X64)
|
||||||
|
const GpReg r8w(_Initialize(), kX86RegR8w);
|
||||||
|
const GpReg r9w(_Initialize(), kX86RegR9w);
|
||||||
|
const GpReg r10w(_Initialize(), kX86RegR10w);
|
||||||
|
const GpReg r11w(_Initialize(), kX86RegR11w);
|
||||||
|
const GpReg r12w(_Initialize(), kX86RegR12w);
|
||||||
|
const GpReg r13w(_Initialize(), kX86RegR13w);
|
||||||
|
const GpReg r14w(_Initialize(), kX86RegR14w);
|
||||||
|
const GpReg r15w(_Initialize(), kX86RegR15w);
|
||||||
|
#endif // ASMJIT_X64
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Registers - 32-bit]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
const GpReg eax(_Initialize(), kX86RegEax);
|
||||||
|
const GpReg ecx(_Initialize(), kX86RegEcx);
|
||||||
|
const GpReg edx(_Initialize(), kX86RegEdx);
|
||||||
|
const GpReg ebx(_Initialize(), kX86RegEbx);
|
||||||
|
const GpReg esp(_Initialize(), kX86RegEsp);
|
||||||
|
const GpReg ebp(_Initialize(), kX86RegEbp);
|
||||||
|
const GpReg esi(_Initialize(), kX86RegEsi);
|
||||||
|
const GpReg edi(_Initialize(), kX86RegEdi);
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X64)
|
||||||
|
const GpReg r8d(_Initialize(), kX86RegR8d);
|
||||||
|
const GpReg r9d(_Initialize(), kX86RegR9d);
|
||||||
|
const GpReg r10d(_Initialize(), kX86RegR10d);
|
||||||
|
const GpReg r11d(_Initialize(), kX86RegR11d);
|
||||||
|
const GpReg r12d(_Initialize(), kX86RegR12d);
|
||||||
|
const GpReg r13d(_Initialize(), kX86RegR13d);
|
||||||
|
const GpReg r14d(_Initialize(), kX86RegR14d);
|
||||||
|
const GpReg r15d(_Initialize(), kX86RegR15d);
|
||||||
|
#endif // ASMJIT_X64
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Registers - 64-bit]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X64)
|
||||||
|
const GpReg rax(_Initialize(), kX86RegRax);
|
||||||
|
const GpReg rcx(_Initialize(), kX86RegRcx);
|
||||||
|
const GpReg rdx(_Initialize(), kX86RegRdx);
|
||||||
|
const GpReg rbx(_Initialize(), kX86RegRbx);
|
||||||
|
const GpReg rsp(_Initialize(), kX86RegRsp);
|
||||||
|
const GpReg rbp(_Initialize(), kX86RegRbp);
|
||||||
|
const GpReg rsi(_Initialize(), kX86RegRsi);
|
||||||
|
const GpReg rdi(_Initialize(), kX86RegRdi);
|
||||||
|
|
||||||
|
const GpReg r8(_Initialize(), kX86RegR8);
|
||||||
|
const GpReg r9(_Initialize(), kX86RegR9);
|
||||||
|
const GpReg r10(_Initialize(), kX86RegR10);
|
||||||
|
const GpReg r11(_Initialize(), kX86RegR11);
|
||||||
|
const GpReg r12(_Initialize(), kX86RegR12);
|
||||||
|
const GpReg r13(_Initialize(), kX86RegR13);
|
||||||
|
const GpReg r14(_Initialize(), kX86RegR14);
|
||||||
|
const GpReg r15(_Initialize(), kX86RegR15);
|
||||||
|
#endif // ASMJIT_X64
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Registers - Native (AsmJit extension)]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
const GpReg zax(_Initialize(), kX86RegZax);
|
||||||
|
const GpReg zcx(_Initialize(), kX86RegZcx);
|
||||||
|
const GpReg zdx(_Initialize(), kX86RegZdx);
|
||||||
|
const GpReg zbx(_Initialize(), kX86RegZbx);
|
||||||
|
const GpReg zsp(_Initialize(), kX86RegZsp);
|
||||||
|
const GpReg zbp(_Initialize(), kX86RegZbp);
|
||||||
|
const GpReg zsi(_Initialize(), kX86RegZsi);
|
||||||
|
const GpReg zdi(_Initialize(), kX86RegZdi);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Registers - MM]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
const MmReg mm0(_Initialize(), kX86RegMm0);
|
||||||
|
const MmReg mm1(_Initialize(), kX86RegMm1);
|
||||||
|
const MmReg mm2(_Initialize(), kX86RegMm2);
|
||||||
|
const MmReg mm3(_Initialize(), kX86RegMm3);
|
||||||
|
const MmReg mm4(_Initialize(), kX86RegMm4);
|
||||||
|
const MmReg mm5(_Initialize(), kX86RegMm5);
|
||||||
|
const MmReg mm6(_Initialize(), kX86RegMm6);
|
||||||
|
const MmReg mm7(_Initialize(), kX86RegMm7);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Registers - XMM]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
const XmmReg xmm0(_Initialize(), kX86RegXmm0);
|
||||||
|
const XmmReg xmm1(_Initialize(), kX86RegXmm1);
|
||||||
|
const XmmReg xmm2(_Initialize(), kX86RegXmm2);
|
||||||
|
const XmmReg xmm3(_Initialize(), kX86RegXmm3);
|
||||||
|
const XmmReg xmm4(_Initialize(), kX86RegXmm4);
|
||||||
|
const XmmReg xmm5(_Initialize(), kX86RegXmm5);
|
||||||
|
const XmmReg xmm6(_Initialize(), kX86RegXmm6);
|
||||||
|
const XmmReg xmm7(_Initialize(), kX86RegXmm7);
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X64)
|
||||||
|
const XmmReg xmm8(_Initialize(), kX86RegXmm8);
|
||||||
|
const XmmReg xmm9(_Initialize(), kX86RegXmm9);
|
||||||
|
const XmmReg xmm10(_Initialize(), kX86RegXmm10);
|
||||||
|
const XmmReg xmm11(_Initialize(), kX86RegXmm11);
|
||||||
|
const XmmReg xmm12(_Initialize(), kX86RegXmm12);
|
||||||
|
const XmmReg xmm13(_Initialize(), kX86RegXmm13);
|
||||||
|
const XmmReg xmm14(_Initialize(), kX86RegXmm14);
|
||||||
|
const XmmReg xmm15(_Initialize(), kX86RegXmm15);
|
||||||
|
#endif // ASMJIT_X64
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Registers - Segment]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
const SegmentReg cs(_Initialize(), kX86RegCs);
|
||||||
|
const SegmentReg ss(_Initialize(), kX86RegSs);
|
||||||
|
const SegmentReg ds(_Initialize(), kX86RegDs);
|
||||||
|
const SegmentReg es(_Initialize(), kX86RegEs);
|
||||||
|
const SegmentReg fs(_Initialize(), kX86RegFs);
|
||||||
|
const SegmentReg gs(_Initialize(), kX86RegGs);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Var]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
Mem _BaseVarMem(const Var& var, uint32_t size)
|
||||||
|
{
|
||||||
|
Mem m; //(_DontInitialize());
|
||||||
|
|
||||||
|
m._mem.op = kOperandMem;
|
||||||
|
m._mem.size = static_cast<uint8_t>(size == kInvalidValue ? var.getSize() : size);
|
||||||
|
m._mem.type = kOperandMemNative;
|
||||||
|
m._mem.segment = kX86SegNone;
|
||||||
|
m._mem.sizePrefix = 0;
|
||||||
|
m._mem.shift = 0;
|
||||||
|
|
||||||
|
m._mem.id = var.getId();
|
||||||
|
m._mem.base = kInvalidValue;
|
||||||
|
m._mem.index = kInvalidValue;
|
||||||
|
|
||||||
|
m._mem.target = NULL;
|
||||||
|
m._mem.displacement = 0;
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Mem _BaseVarMem(const Var& var, uint32_t size, sysint_t disp)
|
||||||
|
{
|
||||||
|
Mem m; //(_DontInitialize());
|
||||||
|
|
||||||
|
m._mem.op = kOperandMem;
|
||||||
|
m._mem.size = static_cast<uint8_t>(size == kInvalidValue ? var.getSize() : size);
|
||||||
|
m._mem.type = kOperandMemNative;
|
||||||
|
m._mem.segment = kX86SegNone;
|
||||||
|
m._mem.sizePrefix = 0;
|
||||||
|
m._mem.shift = 0;
|
||||||
|
|
||||||
|
m._mem.id = var.getId();
|
||||||
|
|
||||||
|
m._mem.base = kInvalidValue;
|
||||||
|
m._mem.index = kInvalidValue;
|
||||||
|
|
||||||
|
m._mem.target = NULL;
|
||||||
|
m._mem.displacement = disp;
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mem _BaseVarMem(const Var& var, uint32_t size, const GpVar& index, uint32_t shift, sysint_t disp)
|
||||||
|
{
|
||||||
|
Mem m; //(_DontInitialize());
|
||||||
|
|
||||||
|
m._mem.op = kOperandMem;
|
||||||
|
m._mem.size = static_cast<uint8_t>(size == kInvalidValue ? var.getSize() : size);
|
||||||
|
m._mem.type = kOperandMemNative;
|
||||||
|
m._mem.segment = kX86SegNone;
|
||||||
|
m._mem.sizePrefix = 0;
|
||||||
|
m._mem.shift = shift;
|
||||||
|
|
||||||
|
m._mem.id = var.getId();
|
||||||
|
|
||||||
|
m._mem.base = kInvalidValue;
|
||||||
|
m._mem.index = index.getId();
|
||||||
|
|
||||||
|
m._mem.target = NULL;
|
||||||
|
m._mem.displacement = disp;
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Mem - ptr[]]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
Mem ptr(const Label& label, sysint_t disp, uint32_t size)
|
||||||
|
{
|
||||||
|
return Mem(label, disp, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mem ptr(const Label& label, const GpReg& index, uint32_t shift, sysint_t disp, uint32_t size)
|
||||||
|
{
|
||||||
|
Mem m(label, disp, size);
|
||||||
|
|
||||||
|
m._mem.index = index.getRegIndex();
|
||||||
|
m._mem.shift = shift;
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mem ptr(const Label& label, const GpVar& index, uint32_t shift, sysint_t disp, uint32_t size)
|
||||||
|
{
|
||||||
|
Mem m(label, disp, size);
|
||||||
|
|
||||||
|
m._mem.index = index.getId();
|
||||||
|
m._mem.shift = shift;
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Mem - ptr[] - Absolute Addressing]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
ASMJIT_API Mem ptr_abs(void* target, sysint_t disp, uint32_t size)
|
||||||
|
{
|
||||||
|
Mem m;
|
||||||
|
|
||||||
|
m._mem.size = size;
|
||||||
|
m._mem.type = kOperandMemAbsolute;
|
||||||
|
m._mem.segment = kX86SegNone;
|
||||||
|
|
||||||
|
m._mem.target = target;
|
||||||
|
m._mem.displacement = disp;
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASMJIT_API Mem ptr_abs(void* target, const GpReg& index, uint32_t shift, sysint_t disp, uint32_t size)
|
||||||
|
{
|
||||||
|
Mem m;// (_DontInitialize());
|
||||||
|
|
||||||
|
m._mem.op = kOperandMem;
|
||||||
|
m._mem.size = size;
|
||||||
|
m._mem.type = kOperandMemAbsolute;
|
||||||
|
m._mem.segment = kX86SegNone;
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X86)
|
||||||
|
m._mem.sizePrefix = index.getSize() != 4;
|
||||||
|
#else
|
||||||
|
m._mem.sizePrefix = index.getSize() != 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m._mem.shift = shift;
|
||||||
|
|
||||||
|
m._mem.id = kInvalidValue;
|
||||||
|
m._mem.base = kInvalidValue;
|
||||||
|
m._mem.index = index.getRegIndex();
|
||||||
|
|
||||||
|
m._mem.target = target;
|
||||||
|
m._mem.displacement = disp;
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASMJIT_API Mem ptr_abs(void* target, const GpVar& index, uint32_t shift, sysint_t disp, uint32_t size)
|
||||||
|
{
|
||||||
|
Mem m;// (_DontInitialize());
|
||||||
|
|
||||||
|
m._mem.op = kOperandMem;
|
||||||
|
m._mem.size = size;
|
||||||
|
m._mem.type = kOperandMemAbsolute;
|
||||||
|
m._mem.segment = kX86SegNone;
|
||||||
|
|
||||||
|
#if defined(ASMJIT_X86)
|
||||||
|
m._mem.sizePrefix = index.getSize() != 4;
|
||||||
|
#else
|
||||||
|
m._mem.sizePrefix = index.getSize() != 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m._mem.shift = shift;
|
||||||
|
|
||||||
|
m._mem.id = kInvalidValue;
|
||||||
|
m._mem.base = kInvalidValue;
|
||||||
|
m._mem.index = index.getId();
|
||||||
|
|
||||||
|
m._mem.target = target;
|
||||||
|
m._mem.displacement = disp;
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::Mem - ptr[base + displacement]]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
Mem ptr(const GpReg& base, sysint_t disp, uint32_t size)
|
||||||
|
{
|
||||||
|
return Mem(base, disp, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mem ptr(const GpReg& base, const GpReg& index, uint32_t shift, sysint_t disp, uint32_t size)
|
||||||
|
{
|
||||||
|
return Mem(base, index, shift, disp, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mem ptr(const GpVar& base, sysint_t disp, uint32_t size)
|
||||||
|
{
|
||||||
|
return Mem(base, disp, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mem ptr(const GpVar& base, const GpVar& index, uint32_t shift, sysint_t disp, uint32_t size)
|
||||||
|
{
|
||||||
|
return Mem(base, index, shift, disp, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,138 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
#define ASMJIT_EXPORTS
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../x86/x86defs.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::_x86UtilJccFromCond]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
const uint32_t _x86UtilJccFromCond[20] =
|
||||||
|
{
|
||||||
|
kX86InstJO,
|
||||||
|
kX86InstJNO,
|
||||||
|
kX86InstJB,
|
||||||
|
kX86InstJAE,
|
||||||
|
kX86InstJE,
|
||||||
|
kX86InstJNE,
|
||||||
|
kX86InstJBE,
|
||||||
|
kX86InstJA,
|
||||||
|
kX86InstJS,
|
||||||
|
kX86InstJNS,
|
||||||
|
kX86InstJPE,
|
||||||
|
kX86InstJPO,
|
||||||
|
kX86InstJL,
|
||||||
|
kX86InstJGE,
|
||||||
|
kX86InstJLE,
|
||||||
|
kX86InstJG,
|
||||||
|
|
||||||
|
kInstNone,
|
||||||
|
kInstNone,
|
||||||
|
kInstNone,
|
||||||
|
kInstNone
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::_x86UtilMovccFromCond]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
const uint32_t _x86UtilMovccFromCond[20] =
|
||||||
|
{
|
||||||
|
kX86InstCMovO,
|
||||||
|
kX86InstCMovNO,
|
||||||
|
kX86InstCMovB,
|
||||||
|
kX86InstCMovAE,
|
||||||
|
kX86InstCMovE,
|
||||||
|
kX86InstCMovNE,
|
||||||
|
kX86InstCMovBE,
|
||||||
|
kX86InstCMovA,
|
||||||
|
kX86InstCMovS,
|
||||||
|
kX86InstCMovNS,
|
||||||
|
kX86InstCMovPE,
|
||||||
|
kX86InstCMovPO,
|
||||||
|
kX86InstCMovL,
|
||||||
|
kX86InstCMovGE,
|
||||||
|
kX86InstCMovLE,
|
||||||
|
kX86InstCMovG,
|
||||||
|
|
||||||
|
kInstNone,
|
||||||
|
kInstNone,
|
||||||
|
kInstNone,
|
||||||
|
kInstNone
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::_x86UtilSetccFromCond]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
const uint32_t _x86UtilSetccFromCond[20] =
|
||||||
|
{
|
||||||
|
kX86InstSetO,
|
||||||
|
kX86InstSetNO,
|
||||||
|
kX86InstSetB,
|
||||||
|
kX86InstSetAE,
|
||||||
|
kX86InstSetE,
|
||||||
|
kX86InstSetNE,
|
||||||
|
kX86InstSetBE,
|
||||||
|
kX86InstSetA,
|
||||||
|
kX86InstSetS,
|
||||||
|
kX86InstSetNS,
|
||||||
|
kX86InstSetPE,
|
||||||
|
kX86InstSetPO,
|
||||||
|
kX86InstSetL,
|
||||||
|
kX86InstSetGE,
|
||||||
|
kX86InstSetLE,
|
||||||
|
kX86InstSetG,
|
||||||
|
|
||||||
|
kInstNone,
|
||||||
|
kInstNone,
|
||||||
|
kInstNone,
|
||||||
|
kInstNone
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::_x86UtilReversedCond]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
const uint32_t _x86UtilReversedCond[20] =
|
||||||
|
{
|
||||||
|
/* x86CondO -> */ kX86CondO,
|
||||||
|
/* x86CondNO -> */ kX86CondNO,
|
||||||
|
/* x86CondB -> */ kX86CondA,
|
||||||
|
/* x86CondAE -> */ kX86CondBE,
|
||||||
|
/* x86CondE -> */ kX86CondE,
|
||||||
|
/* x86CondNE -> */ kX86CondNE,
|
||||||
|
/* x86CondBE -> */ kX86CondAE,
|
||||||
|
/* x86CondA -> */ kX86CondB,
|
||||||
|
/* x86CondS -> */ kX86CondS,
|
||||||
|
/* x86CondNS -> */ kX86CondNS,
|
||||||
|
/* x86CondPE -> */ kX86CondPE,
|
||||||
|
/* x86CondPO -> */ kX86CondPO,
|
||||||
|
|
||||||
|
/* x86CondL -> */ kX86CondG,
|
||||||
|
/* x86CondGE -> */ kX86CondLE,
|
||||||
|
|
||||||
|
/* x86CondLE -> */ kX86CondGE,
|
||||||
|
/* x86CondG -> */ kX86CondL,
|
||||||
|
|
||||||
|
/* kX86CondFpuUnordered -> */ kX86CondFpuUnordered,
|
||||||
|
/* kX86CondFpuNotUnordered -> */ kX86CondFpuNotUnordered,
|
||||||
|
|
||||||
|
0x12,
|
||||||
|
0x13
|
||||||
|
};
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
#include "../core/apiend.h"
|
|
@ -0,0 +1,122 @@
|
||||||
|
// [AsmJit]
|
||||||
|
// Complete JIT Assembler for C++ Language.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See COPYING file in this package.
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#ifndef _ASMJIT_X86_X86UTIL_H
|
||||||
|
#define _ASMJIT_X86_X86UTIL_H
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../x86/x86defs.h"
|
||||||
|
#include "../x86/x86operand.h"
|
||||||
|
|
||||||
|
// [Api-Begin]
|
||||||
|
#include "../core/apibegin.h"
|
||||||
|
|
||||||
|
namespace AsmJit {
|
||||||
|
|
||||||
|
//! @addtogroup AsmJit_X86
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [AsmJit::X86Util]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief Map condition code to "jcc" group of instructions.
|
||||||
|
ASMJIT_VAR const uint32_t _x86UtilJccFromCond[20];
|
||||||
|
//! @brief Map condition code to "cmovcc" group of instructions.
|
||||||
|
ASMJIT_VAR const uint32_t _x86UtilMovccFromCond[20];
|
||||||
|
//! @brief Map condition code to "setcc" group of instructions.
|
||||||
|
ASMJIT_VAR const uint32_t _x86UtilSetccFromCond[20];
|
||||||
|
//! @brief Map condition code to reversed condition code.
|
||||||
|
ASMJIT_VAR const uint32_t _x86UtilReversedCond[20];
|
||||||
|
|
||||||
|
struct X86Util
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Condition Codes]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! @brief Get the equivalent of negated condition code.
|
||||||
|
static inline uint32_t getNegatedCond(uint32_t cond)
|
||||||
|
{
|
||||||
|
return static_cast<kX86Cond>(cond ^ static_cast<uint32_t>(cond < kX86CondNone));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Corresponds to transposing the operands of a comparison.
|
||||||
|
static inline uint32_t getReversedCond(uint32_t cond)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86UtilReversedCond));
|
||||||
|
return _x86UtilReversedCond[cond];
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Translate condition code @a cc to jcc instruction code.
|
||||||
|
//! @sa @c kX86InstCode, @c kX86InstJ.
|
||||||
|
static inline uint32_t getJccInstFromCond(uint32_t cond)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86UtilJccFromCond));
|
||||||
|
return _x86UtilJccFromCond[cond];
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Translate condition code @a cc to cmovcc instruction code.
|
||||||
|
//! @sa @c kX86InstCode, @c kX86InstCMov.
|
||||||
|
static inline uint32_t getCMovccInstFromCond(uint32_t cond)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86UtilMovccFromCond));
|
||||||
|
return _x86UtilMovccFromCond[cond];
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Translate condition code @a cc to setcc instruction code.
|
||||||
|
//! @sa @c kX86InstCode, @c kX86InstSet.
|
||||||
|
static inline uint32_t getSetccInstFromCond(uint32_t cond)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_x86UtilSetccFromCond));
|
||||||
|
return _x86UtilSetccFromCond[cond];
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Variables]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static inline uint32_t getVarClassFromVarType(uint32_t varType)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(varType < kX86VarTypeCount);
|
||||||
|
return x86VarInfo[varType].getClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t getVarSizeFromVarType(uint32_t varType)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(varType < kX86VarTypeCount);
|
||||||
|
return x86VarInfo[varType].getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t getRegCodeFromVarType(uint32_t varType, uint32_t regIndex)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(varType < kX86VarTypeCount);
|
||||||
|
return x86VarInfo[varType].getCode() | regIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool isVarTypeInt(uint32_t varType)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(varType < kX86VarTypeCount);
|
||||||
|
return (x86VarInfo[varType].getClass() & kX86VarClassGp) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool isVarTypeFloat(uint32_t varType)
|
||||||
|
{
|
||||||
|
ASMJIT_ASSERT(varType < kX86VarTypeCount);
|
||||||
|
return (x86VarInfo[varType].getFlags() & (kX86VarFlagSP | kX86VarFlagDP)) != 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
} // AsmJit namespace
|
||||||
|
|
||||||
|
// [Api-End]
|
||||||
|
#include "../core/apiend.h"
|
||||||
|
|
||||||
|
// [Guard]
|
||||||
|
#endif // _ASMJIT_X86_X86UTIL_H
|
|
@ -1887,141 +1887,289 @@
|
||||||
Name="AsmJit"
|
Name="AsmJit"
|
||||||
>
|
>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\utils\AsmJit\ApiBegin.h"
|
RelativePath="..\utils\AsmJit\asmjit.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\utils\AsmJit\ApiEnd.h"
|
RelativePath="..\utils\AsmJit\config.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\utils\AsmJit\AsmJit.h"
|
RelativePath="..\utils\AsmJit\COPYING.txt"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\utils\AsmJit\Assembler.h"
|
RelativePath="..\utils\AsmJit\core.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\utils\AsmJit\AssemblerX86X64.cpp"
|
RelativePath="..\utils\AsmJit\x86.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<Filter
|
||||||
RelativePath="..\utils\AsmJit\AssemblerX86X64.h"
|
Name="core"
|
||||||
>
|
>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\core\apibegin.h"
|
||||||
RelativePath="..\utils\AsmJit\Build.h"
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\apiend.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\assembler.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\assembler.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\assert.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\assert.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\buffer.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\buffer.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\build.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compiler.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compiler.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compilercontext.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compilercontext.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compilerfunc.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compilerfunc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compileritem.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compileritem.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\context.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\context.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\cpuinfo.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\cpuinfo.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\defs.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\defs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\func.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\func.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\intutil.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\lock.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\logger.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\logger.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\memorymanager.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\memorymanager.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\memorymarker.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\memorymarker.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\operand.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\operand.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\podvector.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\stringbuilder.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\stringbuilder.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\stringutil.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\stringutil.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\virtualmemory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\virtualmemory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\zonememory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\zonememory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="x86"
|
||||||
>
|
>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86assembler.cpp"
|
||||||
RelativePath="..\utils\AsmJit\CodeGenerator.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86assembler.h"
|
||||||
RelativePath="..\utils\AsmJit\CodeGenerator.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compiler.cpp"
|
||||||
RelativePath="..\utils\AsmJit\Compiler.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compiler.h"
|
||||||
RelativePath="..\utils\AsmJit\Compiler.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compilercontext.cpp"
|
||||||
RelativePath="..\utils\AsmJit\CompilerX86X64.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compilercontext.h"
|
||||||
RelativePath="..\utils\AsmJit\CompilerX86X64.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compilerfunc.cpp"
|
||||||
RelativePath="..\utils\AsmJit\Config.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compilerfunc.h"
|
||||||
RelativePath="..\utils\AsmJit\CpuInfo.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compileritem.cpp"
|
||||||
RelativePath="..\utils\AsmJit\CpuInfo.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compileritem.h"
|
||||||
RelativePath="..\utils\AsmJit\Defs.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86cpuinfo.cpp"
|
||||||
RelativePath="..\utils\AsmJit\Defs.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86cpuinfo.h"
|
||||||
RelativePath="..\utils\AsmJit\DefsX86X64.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86defs.cpp"
|
||||||
RelativePath="..\utils\AsmJit\DefsX86X64.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86defs.h"
|
||||||
RelativePath="..\utils\AsmJit\Logger.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86func.cpp"
|
||||||
RelativePath="..\utils\AsmJit\Logger.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86func.h"
|
||||||
RelativePath="..\utils\AsmJit\MemoryManager.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86operand.cpp"
|
||||||
RelativePath="..\utils\AsmJit\MemoryManager.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86operand.h"
|
||||||
RelativePath="..\utils\AsmJit\MemoryMarker.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86util.cpp"
|
||||||
RelativePath="..\utils\AsmJit\MemoryMarker.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86util.h"
|
||||||
RelativePath="..\utils\AsmJit\Operand.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
</Filter>
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\OperandX86X64.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\OperandX86X64.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\Platform.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\Platform.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\Util.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\Util.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\Util_p.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
<VisualStudioProject
|
<VisualStudioProject
|
||||||
ProjectType="Visual C++"
|
ProjectType="Visual C++"
|
||||||
Version="9.00"
|
Version="9,00"
|
||||||
Name="DeSmuME_VS2008"
|
Name="DeSmuME_VS2008"
|
||||||
ProjectGUID="{9F5F72A1-D3A5-4918-B460-E076B16D10A9}"
|
ProjectGUID="{9F5F72A1-D3A5-4918-B460-E076B16D10A9}"
|
||||||
RootNamespace="DeSmuME"
|
RootNamespace="DeSmuME"
|
||||||
|
@ -1337,59 +1337,11 @@
|
||||||
Name="AsmJit"
|
Name="AsmJit"
|
||||||
>
|
>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\utils\AsmJit\ApiBegin.h"
|
RelativePath="..\utils\AsmJit\asmjit.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\utils\AsmJit\ApiEnd.h"
|
RelativePath="..\utils\AsmJit\config.h"
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\AsmJit.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\Assembler.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\AssemblerX86X64.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\AssemblerX86X64.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\Build.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\CodeGenerator.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\CodeGenerator.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\Compiler.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\Compiler.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\CompilerX86X64.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\CompilerX86X64.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\utils\AsmJit\Config.h"
|
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
@ -1397,89 +1349,277 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\utils\AsmJit\CpuInfo.cpp"
|
RelativePath="..\utils\AsmJit\core.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\utils\AsmJit\CpuInfo.h"
|
RelativePath="..\utils\AsmJit\x86.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<Filter
|
||||||
RelativePath="..\utils\AsmJit\Defs.cpp"
|
Name="core"
|
||||||
>
|
>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\core\apibegin.h"
|
||||||
RelativePath="..\utils\AsmJit\Defs.h"
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\apiend.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\assembler.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\assembler.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\assert.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\assert.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\buffer.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\buffer.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\build.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compiler.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compiler.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compilercontext.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compilercontext.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compilerfunc.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compilerfunc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compileritem.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\compileritem.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\context.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\context.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\cpuinfo.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\cpuinfo.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\defs.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\defs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\func.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\func.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\intutil.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\lock.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\logger.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\logger.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\memorymanager.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\memorymanager.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\memorymarker.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\memorymarker.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\operand.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\operand.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\podvector.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\stringbuilder.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\stringbuilder.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\stringutil.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\stringutil.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\virtualmemory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\virtualmemory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\zonememory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\core\zonememory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="x86"
|
||||||
>
|
>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86assembler.cpp"
|
||||||
RelativePath="..\utils\AsmJit\DefsX86X64.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86assembler.h"
|
||||||
RelativePath="..\utils\AsmJit\DefsX86X64.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compiler.cpp"
|
||||||
RelativePath="..\utils\AsmJit\Logger.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compiler.h"
|
||||||
RelativePath="..\utils\AsmJit\Logger.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compilercontext.cpp"
|
||||||
RelativePath="..\utils\AsmJit\MemoryManager.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compilercontext.h"
|
||||||
RelativePath="..\utils\AsmJit\MemoryManager.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compilerfunc.cpp"
|
||||||
RelativePath="..\utils\AsmJit\MemoryMarker.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compilerfunc.h"
|
||||||
RelativePath="..\utils\AsmJit\MemoryMarker.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compileritem.cpp"
|
||||||
RelativePath="..\utils\AsmJit\Operand.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86compileritem.h"
|
||||||
RelativePath="..\utils\AsmJit\OperandX86X64.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86cpuinfo.cpp"
|
||||||
RelativePath="..\utils\AsmJit\OperandX86X64.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86cpuinfo.h"
|
||||||
RelativePath="..\utils\AsmJit\Platform.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86defs.cpp"
|
||||||
RelativePath="..\utils\AsmJit\Platform.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86defs.h"
|
||||||
RelativePath="..\utils\AsmJit\README.txt"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86func.cpp"
|
||||||
RelativePath="..\utils\AsmJit\Util.cpp"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86func.h"
|
||||||
RelativePath="..\utils\AsmJit\Util.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
<File
|
RelativePath="..\utils\AsmJit\x86\x86operand.cpp"
|
||||||
RelativePath="..\utils\AsmJit\Util_p.h"
|
>
|
||||||
>
|
</File>
|
||||||
</File>
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\x86\x86operand.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\x86\x86util.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\utils\AsmJit\x86\x86util.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
|
|
|
@ -126,11 +126,11 @@
|
||||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Template|x64'" />
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Template|x64'" />
|
||||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Template|x64'" />
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Template|x64'" />
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)_x64_release</TargetName>
|
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)_x64_release</TargetName>
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)_x64_release</TargetName>
|
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)_x64_debug</TargetName>
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Dev+|x64'">$(ProjectName)_x64_release</TargetName>
|
<TargetName Condition="'$(Configuration)|$(Platform)'=='Dev+|x64'">$(ProjectName)_x64_dev+</TargetName>
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)_release</TargetName>
|
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)_release</TargetName>
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)_release</TargetName>
|
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)_debug</TargetName>
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">$(ProjectName)_release</TargetName>
|
<TargetName Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">$(ProjectName)_dev+</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
|
@ -443,19 +443,35 @@
|
||||||
<ClCompile Include="..\SPU.cpp" />
|
<ClCompile Include="..\SPU.cpp" />
|
||||||
<ClCompile Include="..\texcache.cpp" />
|
<ClCompile Include="..\texcache.cpp" />
|
||||||
<ClCompile Include="..\thumb_instructions.cpp" />
|
<ClCompile Include="..\thumb_instructions.cpp" />
|
||||||
<ClCompile Include="..\utils\AsmJit\AssemblerX86X64.cpp" />
|
<ClCompile Include="..\utils\AsmJit\core\assembler.cpp" />
|
||||||
<ClCompile Include="..\utils\AsmJit\CodeGenerator.cpp" />
|
<ClCompile Include="..\utils\AsmJit\core\assert.cpp" />
|
||||||
<ClCompile Include="..\utils\AsmJit\Compiler.cpp" />
|
<ClCompile Include="..\utils\AsmJit\core\buffer.cpp" />
|
||||||
<ClCompile Include="..\utils\AsmJit\CompilerX86X64.cpp" />
|
<ClCompile Include="..\utils\AsmJit\core\compiler.cpp" />
|
||||||
<ClCompile Include="..\utils\AsmJit\CpuInfo.cpp" />
|
<ClCompile Include="..\utils\AsmJit\core\compilercontext.cpp" />
|
||||||
<ClCompile Include="..\utils\AsmJit\Defs.cpp" />
|
<ClCompile Include="..\utils\AsmJit\core\compilerfunc.cpp" />
|
||||||
<ClCompile Include="..\utils\AsmJit\DefsX86X64.cpp" />
|
<ClCompile Include="..\utils\AsmJit\core\compileritem.cpp" />
|
||||||
<ClCompile Include="..\utils\AsmJit\Logger.cpp" />
|
<ClCompile Include="..\utils\AsmJit\core\context.cpp" />
|
||||||
<ClCompile Include="..\utils\AsmJit\MemoryManager.cpp" />
|
<ClCompile Include="..\utils\AsmJit\core\cpuinfo.cpp" />
|
||||||
<ClCompile Include="..\utils\AsmJit\MemoryMarker.cpp" />
|
<ClCompile Include="..\utils\AsmJit\core\defs.cpp" />
|
||||||
<ClCompile Include="..\utils\AsmJit\OperandX86X64.cpp" />
|
<ClCompile Include="..\utils\AsmJit\core\func.cpp" />
|
||||||
<ClCompile Include="..\utils\AsmJit\Platform.cpp" />
|
<ClCompile Include="..\utils\AsmJit\core\logger.cpp" />
|
||||||
<ClCompile Include="..\utils\AsmJit\Util.cpp" />
|
<ClCompile Include="..\utils\AsmJit\core\memorymanager.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\memorymarker.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\operand.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\stringbuilder.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\stringutil.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\virtualmemory.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\zonememory.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86assembler.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86compiler.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86compilercontext.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86compilerfunc.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86compileritem.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86cpuinfo.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86defs.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86func.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86operand.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86util.cpp" />
|
||||||
<ClCompile Include="..\utils\datetime.cpp" />
|
<ClCompile Include="..\utils\datetime.cpp" />
|
||||||
<ClCompile Include="..\utils\dlditool.cpp" />
|
<ClCompile Include="..\utils\dlditool.cpp" />
|
||||||
<ClCompile Include="..\utils\emufat.cpp" />
|
<ClCompile Include="..\utils\emufat.cpp" />
|
||||||
|
@ -707,27 +723,45 @@
|
||||||
<ClInclude Include="..\SPU.h" />
|
<ClInclude Include="..\SPU.h" />
|
||||||
<ClInclude Include="..\texcache.h" />
|
<ClInclude Include="..\texcache.h" />
|
||||||
<ClInclude Include="..\types.h" />
|
<ClInclude Include="..\types.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\ApiBegin.h" />
|
<ClInclude Include="..\utils\AsmJit\asmjit.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\ApiEnd.h" />
|
<ClInclude Include="..\utils\AsmJit\config.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\AsmJit.h" />
|
<ClInclude Include="..\utils\AsmJit\core.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\Assembler.h" />
|
<ClInclude Include="..\utils\AsmJit\core\apibegin.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\AssemblerX86X64.h" />
|
<ClInclude Include="..\utils\AsmJit\core\apiend.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\Build.h" />
|
<ClInclude Include="..\utils\AsmJit\core\assembler.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\CodeGenerator.h" />
|
<ClInclude Include="..\utils\AsmJit\core\assert.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\Compiler.h" />
|
<ClInclude Include="..\utils\AsmJit\core\buffer.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\CompilerX86X64.h" />
|
<ClInclude Include="..\utils\AsmJit\core\build.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\Config.h" />
|
<ClInclude Include="..\utils\AsmJit\core\compiler.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\CpuInfo.h" />
|
<ClInclude Include="..\utils\AsmJit\core\compilercontext.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\Defs.h" />
|
<ClInclude Include="..\utils\AsmJit\core\compilerfunc.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\DefsX86X64.h" />
|
<ClInclude Include="..\utils\AsmJit\core\compileritem.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\Logger.h" />
|
<ClInclude Include="..\utils\AsmJit\core\context.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\MemoryManager.h" />
|
<ClInclude Include="..\utils\AsmJit\core\cpuinfo.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\MemoryMarker.h" />
|
<ClInclude Include="..\utils\AsmJit\core\defs.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\Operand.h" />
|
<ClInclude Include="..\utils\AsmJit\core\func.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\OperandX86X64.h" />
|
<ClInclude Include="..\utils\AsmJit\core\intutil.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\Platform.h" />
|
<ClInclude Include="..\utils\AsmJit\core\lock.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\Util.h" />
|
<ClInclude Include="..\utils\AsmJit\core\logger.h" />
|
||||||
<ClInclude Include="..\utils\AsmJit\Util_p.h" />
|
<ClInclude Include="..\utils\AsmJit\core\memorymanager.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\memorymarker.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\operand.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\podvector.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\stringbuilder.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\stringutil.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\virtualmemory.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\zonememory.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86assembler.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86compiler.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86compilercontext.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86compilerfunc.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86compileritem.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86cpuinfo.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86defs.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86func.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86operand.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86util.h" />
|
||||||
<ClInclude Include="..\utils\datetime.h" />
|
<ClInclude Include="..\utils\datetime.h" />
|
||||||
<ClInclude Include="..\utils\emufat.h" />
|
<ClInclude Include="..\utils\emufat.h" />
|
||||||
<ClInclude Include="..\utils\emufat_types.h" />
|
<ClInclude Include="..\utils\emufat_types.h" />
|
||||||
|
@ -886,7 +920,6 @@
|
||||||
<None Include="..\instruction_tabdef.inc" />
|
<None Include="..\instruction_tabdef.inc" />
|
||||||
<None Include="..\thumb_tabdef.inc" />
|
<None Include="..\thumb_tabdef.inc" />
|
||||||
<None Include="..\utils\AsmJit\COPYING.txt" />
|
<None Include="..\utils\AsmJit\COPYING.txt" />
|
||||||
<None Include="..\utils\AsmJit\README.txt" />
|
|
||||||
<None Include="bitmap1.bmp" />
|
<None Include="bitmap1.bmp" />
|
||||||
<None Include="DeSmuME.ico" />
|
<None Include="DeSmuME.ico" />
|
||||||
<CustomBuild Include="directx\directx.7z">
|
<CustomBuild Include="directx\directx.7z">
|
||||||
|
|
|
@ -64,6 +64,12 @@
|
||||||
<Filter Include="Windows\fex\unrar">
|
<Filter Include="Windows\fex\unrar">
|
||||||
<UniqueIdentifier>{24398c49-4650-412e-b46f-4725ad4f5b11}</UniqueIdentifier>
|
<UniqueIdentifier>{24398c49-4650-412e-b46f-4725ad4f5b11}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Core\utils\AsmJit\core">
|
||||||
|
<UniqueIdentifier>{82c38db3-d06d-44b5-a9a4-be3c002d0db0}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Core\utils\AsmJit\x86">
|
||||||
|
<UniqueIdentifier>{0d620905-0dcf-47a4-bac2-91f307aa9994}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\addons.cpp">
|
<ClCompile Include="..\addons.cpp">
|
||||||
|
@ -480,45 +486,6 @@
|
||||||
<ClCompile Include="importSave.cpp">
|
<ClCompile Include="importSave.cpp">
|
||||||
<Filter>Windows</Filter>
|
<Filter>Windows</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\utils\AsmJit\AssemblerX86X64.cpp">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\utils\AsmJit\CodeGenerator.cpp">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\utils\AsmJit\Compiler.cpp">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\utils\AsmJit\CompilerX86X64.cpp">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\utils\AsmJit\CpuInfo.cpp">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\utils\AsmJit\Defs.cpp">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\utils\AsmJit\DefsX86X64.cpp">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\utils\AsmJit\Logger.cpp">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\utils\AsmJit\MemoryManager.cpp">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\utils\AsmJit\MemoryMarker.cpp">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\utils\AsmJit\OperandX86X64.cpp">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\utils\AsmJit\Platform.cpp">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\utils\AsmJit\Util.cpp">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\arm_jit.cpp">
|
<ClCompile Include="..\arm_jit.cpp">
|
||||||
<Filter>Core</Filter>
|
<Filter>Core</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -720,6 +687,93 @@
|
||||||
<ClCompile Include="File_Extractor\unrar\crc.cpp">
|
<ClCompile Include="File_Extractor\unrar\crc.cpp">
|
||||||
<Filter>Windows\fex\unrar</Filter>
|
<Filter>Windows\fex\unrar</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\assembler.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\assert.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\buffer.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\compiler.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\compilercontext.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\compilerfunc.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\compileritem.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\context.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\cpuinfo.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\defs.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\func.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\logger.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\memorymanager.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\memorymarker.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\operand.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\stringbuilder.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\stringutil.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\virtualmemory.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\zonememory.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86assembler.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86compiler.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86compilercontext.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86compilerfunc.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86compileritem.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86cpuinfo.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86defs.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86func.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86operand.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86util.cpp">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\addons.h">
|
<ClInclude Include="..\addons.h">
|
||||||
|
@ -1122,69 +1176,6 @@
|
||||||
<ClInclude Include="importSave.h">
|
<ClInclude Include="importSave.h">
|
||||||
<Filter>Windows</Filter>
|
<Filter>Windows</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\utils\AsmJit\ApiBegin.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\ApiEnd.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\AsmJit.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\Assembler.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\AssemblerX86X64.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\Build.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\CodeGenerator.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\Compiler.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\CompilerX86X64.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\Config.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\CpuInfo.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\Defs.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\DefsX86X64.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\Logger.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\MemoryManager.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\MemoryMarker.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\Operand.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\OperandX86X64.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\Platform.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\Util.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\utils\AsmJit\Util_p.h">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\arm_jit.h">
|
<ClInclude Include="..\arm_jit.h">
|
||||||
<Filter>Core</Filter>
|
<Filter>Core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -1386,6 +1377,123 @@
|
||||||
<ClInclude Include="FEX_Interface.h">
|
<ClInclude Include="FEX_Interface.h">
|
||||||
<Filter>Windows</Filter>
|
<Filter>Windows</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\asmjit.h">
|
||||||
|
<Filter>Core\utils\AsmJit</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\config.h">
|
||||||
|
<Filter>Core\utils\AsmJit</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core.h">
|
||||||
|
<Filter>Core\utils\AsmJit</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86.h">
|
||||||
|
<Filter>Core\utils\AsmJit</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\apibegin.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\apiend.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\assembler.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\assert.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\buffer.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\build.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\compiler.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\compilercontext.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\compilerfunc.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\compileritem.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\context.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\cpuinfo.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\defs.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\func.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\intutil.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\lock.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\logger.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\memorymanager.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\memorymarker.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\operand.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\podvector.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\stringbuilder.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\stringutil.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\virtualmemory.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\zonememory.h">
|
||||||
|
<Filter>Core\utils\AsmJit\core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86assembler.h">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86compiler.h">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86compilercontext.h">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86compilerfunc.h">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86compileritem.h">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86cpuinfo.h">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86defs.h">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86func.h">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86operand.h">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86util.h">
|
||||||
|
<Filter>Core\utils\AsmJit\x86</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\instruction_tabdef.inc">
|
<None Include="..\instruction_tabdef.inc">
|
||||||
|
@ -1403,12 +1511,6 @@
|
||||||
<None Include="..\filter\hq4x.dat">
|
<None Include="..\filter\hq4x.dat">
|
||||||
<Filter>Core\filter</Filter>
|
<Filter>Core\filter</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="..\utils\AsmJit\COPYING.txt">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="..\utils\AsmJit\README.txt">
|
|
||||||
<Filter>Core\utils\AsmJit</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="File_Extractor\7z_C\7zC.txt">
|
<None Include="File_Extractor\7z_C\7zC.txt">
|
||||||
<Filter>Windows\fex\7z</Filter>
|
<Filter>Windows\fex\7z</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
@ -1436,6 +1538,9 @@
|
||||||
<None Include="File_Extractor\unrar\whatsnew.txt">
|
<None Include="File_Extractor\unrar\whatsnew.txt">
|
||||||
<Filter>Windows\fex\unrar</Filter>
|
<Filter>Windows\fex\unrar</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="..\utils\AsmJit\COPYING.txt">
|
||||||
|
<Filter>Core\utils\AsmJit</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="resources.rc">
|
<ResourceCompile Include="resources.rc">
|
||||||
|
|
|
@ -1,28 +1,26 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2008
|
# Visual Studio 2012
|
||||||
Project("{EAF909A5-FA59-4C3D-9431-0FCC20D5BCF9}") = "DeSmuME_Intel", "DeSmuME_Intel.icproj", "{61FB2DAF-A8E9-4CCC-ADF4-B824B4F00187}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DeSmuME_VS2012", "DeSmuME_2012.vcxproj", "{9F5F72A1-D3A5-4918-B460-E076B16D10A9}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
|
Dev+|Win32 = Dev+|Win32
|
||||||
|
Dev+|x64 = Dev+|x64
|
||||||
Release|Win32 = Release|Win32
|
Release|Win32 = Release|Win32
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{61FB2DAF-A8E9-4CCC-ADF4-B824B4F00187}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{61FB2DAF-A8E9-4CCC-ADF4-B824B4F00187}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{61FB2DAF-A8E9-4CCC-ADF4-B824B4F00187}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{61FB2DAF-A8E9-4CCC-ADF4-B824B4F00187}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{61FB2DAF-A8E9-4CCC-ADF4-B824B4F00187}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{61FB2DAF-A8E9-4CCC-ADF4-B824B4F00187}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{61FB2DAF-A8E9-4CCC-ADF4-B824B4F00187}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{61FB2DAF-A8E9-4CCC-ADF4-B824B4F00187}.Release|x64.Build.0 = Release|x64
|
|
||||||
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Debug|Win32.ActiveCfg = Debug|Win32
|
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Debug|Win32.Build.0 = Debug|Win32
|
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Debug|x64.ActiveCfg = Debug|x64
|
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Debug|x64.Build.0 = Debug|x64
|
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Dev+|Win32.ActiveCfg = Dev+|Win32
|
||||||
|
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Dev+|Win32.Build.0 = Dev+|Win32
|
||||||
|
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Dev+|x64.ActiveCfg = Dev+|x64
|
||||||
|
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Dev+|x64.Build.0 = Dev+|x64
|
||||||
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Release|Win32.ActiveCfg = Release|Win32
|
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Release|Win32.Build.0 = Release|Win32
|
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Release|Win32.Build.0 = Release|Win32
|
||||||
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Release|x64.ActiveCfg = Release|x64
|
{9F5F72A1-D3A5-4918-B460-E076B16D10A9}.Release|x64.ActiveCfg = Release|x64
|
|
@ -0,0 +1,944 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Dev+|Win32">
|
||||||
|
<Configuration>Dev+</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Dev+|x64">
|
||||||
|
<Configuration>Dev+</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectName>DeSmuME_VS2012</ProjectName>
|
||||||
|
<ProjectGuid>{9F5F72A1-D3A5-4918-B460-E076B16D10A9}</ProjectGuid>
|
||||||
|
<RootNamespace>DeSmuME</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Dev+|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Dev+|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<OutDir>$(SolutionDir)\__bins\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\.VS2012\$(Configuration)\$(Platform)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)_debug</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<OutDir>$(SolutionDir)\__bins\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\.VS2012\$(Configuration)\$(Platform)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)_x64_debug</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<OutDir>$(SolutionDir)\__bins\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\.VS2012\$(Configuration)\$(Platform)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)_release</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<OutDir>$(SolutionDir)\__bins\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\.VS2012\$(Configuration)\$(Platform)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)_x64_release</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">
|
||||||
|
<OutDir>$(SolutionDir)\__bins\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\.VS2012\$(Configuration)\$(Platform)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)_dev+</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Dev+|x64'">
|
||||||
|
<OutDir>$(SolutionDir)\__bins\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\.VS2012\$(Configuration)\$(Platform)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)_x64_dev+</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>defaultconfig\SubWCRev.bat</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||||
|
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||||
|
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||||
|
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<AdditionalIncludeDirectories>.;..;lua\include;glib-2.20.1\build;glib-2.20.1\build\glib;.\zlib123;.\zziplib;.\winpcap;userconfig;defaultconfig;.\agg\include;.\agg\examples;.\wx\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>DEBUG;_CRT_SECURE_NO_DEPRECATE;GLIB_STATIC_COMPILATION;WIN32;BETA_VERSION;NOMINMAX;HAVE_LIBZ;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||||
|
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||||
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
<CallingConvention>Cdecl</CallingConvention>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib;libelf_libdwarf-vc8-Win32.lib;lua51.lib;glib-vc8-Win32.lib;zlib-vc8-Win32.lib;agg-2.5.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)$(ProjectName)_debug.exe</OutputFile>
|
||||||
|
<AdditionalLibraryDirectories>.\zlib123;agg;.libs;.libs\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<DelayLoadDLLs>lua51.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<GenerateMapFile>true</GenerateMapFile>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
</Link>
|
||||||
|
<Manifest>
|
||||||
|
<AdditionalManifestFiles>DeSmuME_x86.manifest;%(AdditionalManifestFiles)</AdditionalManifestFiles>
|
||||||
|
</Manifest>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>defaultconfig\SubWCRev.bat</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||||
|
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||||
|
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||||
|
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<AdditionalIncludeDirectories>.;..;lua\include;glib-2.20.1\build;glib-2.20.1\build\glib;.\zlib123;.\zziplib;.\winpcap;userconfig;defaultconfig;.\agg\include;.\agg\examples;.\wx\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>DEBUG;_CRT_SECURE_NO_DEPRECATE;GLIB_STATIC_COMPILATION;WIN32;BETA_VERSION;NOMINMAX;HAVE_LIBZ;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||||
|
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||||
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CallingConvention>Cdecl</CallingConvention>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;libelf_libdwarf-vc8-x64.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)$(ProjectName)_x64_debug.exe</OutputFile>
|
||||||
|
<AdditionalLibraryDirectories>.\zlib123;agg;.libs\x64;.libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<DelayLoadDLLs>lua51.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<GenerateMapFile>true</GenerateMapFile>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
<Manifest>
|
||||||
|
<AdditionalManifestFiles>DeSmuME_x64.manifest;%(AdditionalManifestFiles)</AdditionalManifestFiles>
|
||||||
|
</Manifest>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>defaultconfig\SubWCRev.bat</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
|
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<AdditionalIncludeDirectories>.;..;lua\include;glib-2.20.1\build;glib-2.20.1\build\glib;.\zlib123;.\zziplib;.\winpcap;userconfig;defaultconfig;.\agg\include;.\agg\examples;.\wx\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;GLIB_STATIC_COMPILATION;WIN32;HAVE_LIBZ;NOMINMAX;RELEASE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
|
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||||
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
|
<WarningLevel>Level1</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CallingConvention>Cdecl</CallingConvention>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib;libelf_libdwarf-vc8-Win32.lib;lua51.lib;glib-vc8-Win32.lib;zlib-vc8-Win32.lib;agg-2.5.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)$(ProjectName)_release.exe</OutputFile>
|
||||||
|
<AdditionalLibraryDirectories>.\zlib123;agg;.libs;.libs\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<DelayLoadDLLs>lua51.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
<Profile>false</Profile>
|
||||||
|
</Link>
|
||||||
|
<Manifest>
|
||||||
|
<AdditionalManifestFiles>DeSmuME_x86.manifest;%(AdditionalManifestFiles)</AdditionalManifestFiles>
|
||||||
|
</Manifest>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>defaultconfig\SubWCRev.bat</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
|
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<AdditionalIncludeDirectories>.;..;lua\include;glib-2.20.1\build;glib-2.20.1\build\glib;.\zlib123;.\zziplib;.\winpcap;userconfig;defaultconfig;.\agg\include;.\agg\examples;.\wx\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;GLIB_STATIC_COMPILATION;WIN32;HAVE_LIBZ;NOMINMAX;RELEASE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
|
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||||
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
|
<WarningLevel>Level1</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CallingConvention>Cdecl</CallingConvention>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;libelf_libdwarf-vc8-x64.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)$(ProjectName)_x64_release.exe</OutputFile>
|
||||||
|
<AdditionalLibraryDirectories>.\zlib123;agg;.libs\x64;.libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<DelayLoadDLLs>lua51.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
<Profile>false</Profile>
|
||||||
|
</Link>
|
||||||
|
<Manifest>
|
||||||
|
<AdditionalManifestFiles>DeSmuME_x64.manifest;%(AdditionalManifestFiles)</AdditionalManifestFiles>
|
||||||
|
</Manifest>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>defaultconfig\SubWCRev.bat</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>Full</Optimization>
|
||||||
|
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
|
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<AdditionalIncludeDirectories>.;..;lua\include;glib-2.20.1\build;glib-2.20.1\build\glib;.\zlib123;.\zziplib;.\winpcap;userconfig;defaultconfig;.\agg\include;.\agg\examples;.\wx\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;GLIB_STATIC_COMPILATION;WIN32;HAVE_LIBZ;NOMINMAX;RELEASE;NDEBUG;FASTBUILD;DEVELOPER;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
|
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||||
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
|
<WarningLevel>Level1</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CallingConvention>Cdecl</CallingConvention>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>directx-win32-ddraw-dinput8-dsound-dxerr8-dxguid.lib;libelf_libdwarf-vc8-Win32.lib;lua51.lib;glib-vc8-Win32.lib;zlib-vc8-Win32.lib;agg-2.5.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)$(ProjectName)_dev+.exe</OutputFile>
|
||||||
|
<AdditionalLibraryDirectories>.\zlib123;agg;.libs;.libs\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<DelayLoadDLLs>lua51.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<LinkTimeCodeGeneration />
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
<Profile>false</Profile>
|
||||||
|
</Link>
|
||||||
|
<Manifest>
|
||||||
|
<AdditionalManifestFiles>DeSmuME_x86.manifest;%(AdditionalManifestFiles)</AdditionalManifestFiles>
|
||||||
|
</Manifest>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Dev+|x64'">
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>defaultconfig\SubWCRev.bat</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
|
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<AdditionalIncludeDirectories>.;..;lua\include;glib-2.20.1\build;glib-2.20.1\build\glib;.\zlib123;.\zziplib;.\winpcap;userconfig;defaultconfig;.\agg\include;.\agg\examples;.\wx\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;GLIB_STATIC_COMPILATION;WIN32;HAVE_LIBZ;NOMINMAX;RELEASE;NDEBUG;DEVELOPER;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
|
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||||
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
|
<WarningLevel>Level1</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CallingConvention>Cdecl</CallingConvention>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;libelf_libdwarf-vc8-x64.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)$(ProjectName)_x64_dev+.exe</OutputFile>
|
||||||
|
<AdditionalLibraryDirectories>.\zlib123;agg;.libs\x64;.libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<DelayLoadDLLs>lua51.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<LinkTimeCodeGeneration />
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
<Profile>false</Profile>
|
||||||
|
</Link>
|
||||||
|
<Manifest>
|
||||||
|
<AdditionalManifestFiles>DeSmuME_x64.manifest;%(AdditionalManifestFiles)</AdditionalManifestFiles>
|
||||||
|
</Manifest>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\addons.cpp" />
|
||||||
|
<ClCompile Include="..\aggdraw.cpp" />
|
||||||
|
<ClCompile Include="..\arm_instructions.cpp" />
|
||||||
|
<ClCompile Include="..\arm_jit.cpp" />
|
||||||
|
<ClCompile Include="..\armcpu.cpp" />
|
||||||
|
<ClCompile Include="..\bios.cpp" />
|
||||||
|
<ClCompile Include="..\cheatSystem.cpp" />
|
||||||
|
<ClCompile Include="..\commandline.cpp">
|
||||||
|
<CallingConvention Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">Cdecl</CallingConvention>
|
||||||
|
<CallingConvention Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Cdecl</CallingConvention>
|
||||||
|
<CallingConvention Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Cdecl</CallingConvention>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\common.cpp" />
|
||||||
|
<ClCompile Include="..\cp15.cpp" />
|
||||||
|
<ClCompile Include="..\debug.cpp" />
|
||||||
|
<ClCompile Include="..\Disassembler.cpp" />
|
||||||
|
<ClCompile Include="..\driver.cpp" />
|
||||||
|
<ClCompile Include="..\emufile.cpp" />
|
||||||
|
<ClCompile Include="..\FIFO.cpp" />
|
||||||
|
<ClCompile Include="..\firmware.cpp" />
|
||||||
|
<ClCompile Include="..\fs-windows.cpp" />
|
||||||
|
<ClCompile Include="..\gfx3d.cpp" />
|
||||||
|
<ClCompile Include="..\GPU.cpp" />
|
||||||
|
<ClCompile Include="..\GPU_OSD.cpp" />
|
||||||
|
<ClCompile Include="..\lua-engine.cpp" />
|
||||||
|
<ClCompile Include="..\matrix.cpp" />
|
||||||
|
<ClCompile Include="..\mc.cpp" />
|
||||||
|
<ClCompile Include="..\MMU.cpp" />
|
||||||
|
<ClCompile Include="..\movie.cpp" />
|
||||||
|
<ClCompile Include="..\NDSSystem.cpp" />
|
||||||
|
<ClCompile Include="..\OGLRender.cpp" />
|
||||||
|
<ClCompile Include="..\path.cpp" />
|
||||||
|
<ClCompile Include="..\rasterize.cpp" />
|
||||||
|
<ClCompile Include="..\readwrite.cpp" />
|
||||||
|
<ClCompile Include="..\render3D.cpp" />
|
||||||
|
<ClCompile Include="..\ROMReader.cpp" />
|
||||||
|
<ClCompile Include="..\rtc.cpp" />
|
||||||
|
<ClCompile Include="..\saves.cpp" />
|
||||||
|
<ClCompile Include="..\slot1.cpp" />
|
||||||
|
<ClCompile Include="..\SPU.cpp" />
|
||||||
|
<ClCompile Include="..\texcache.cpp" />
|
||||||
|
<ClCompile Include="..\thumb_instructions.cpp" />
|
||||||
|
<ClCompile Include="..\version.cpp" />
|
||||||
|
<ClCompile Include="..\wifi.cpp" />
|
||||||
|
<ClCompile Include="..\addons\slot1_none.cpp" />
|
||||||
|
<ClCompile Include="..\addons\slot1_r4.cpp" />
|
||||||
|
<ClCompile Include="..\addons\slot1_retail.cpp" />
|
||||||
|
<ClCompile Include="..\addons\slot1_retail_nand.cpp" />
|
||||||
|
<ClCompile Include="..\addons\slot2_expMemory.cpp" />
|
||||||
|
<ClCompile Include="..\addons\slot2_gbagame.cpp" />
|
||||||
|
<ClCompile Include="..\addons\slot2_guitarGrip.cpp" />
|
||||||
|
<ClCompile Include="..\addons\slot2_mpcf.cpp" />
|
||||||
|
<ClCompile Include="..\addons\slot2_none.cpp" />
|
||||||
|
<ClCompile Include="..\addons\slot2_paddle.cpp" />
|
||||||
|
<ClCompile Include="..\addons\slot2_piano.cpp" />
|
||||||
|
<ClCompile Include="..\addons\slot2_rumblepak.cpp" />
|
||||||
|
<ClCompile Include="..\gdbstub\gdbstub.cpp" />
|
||||||
|
<ClCompile Include="..\utils\ConvertUTF.c" />
|
||||||
|
<ClCompile Include="..\utils\datetime.cpp" />
|
||||||
|
<ClCompile Include="..\utils\dlditool.cpp" />
|
||||||
|
<ClCompile Include="..\utils\emufat.cpp" />
|
||||||
|
<ClCompile Include="..\utils\guid.cpp" />
|
||||||
|
<ClCompile Include="..\utils\md5.cpp" />
|
||||||
|
<ClCompile Include="..\utils\task.cpp" />
|
||||||
|
<ClCompile Include="..\utils\vfat.cpp" />
|
||||||
|
<ClCompile Include="..\utils\xstring.cpp" />
|
||||||
|
<ClCompile Include="..\utils\decrypt\crc.cpp">
|
||||||
|
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)decrypt\</ObjectFileName>
|
||||||
|
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)decrypt\</ObjectFileName>
|
||||||
|
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">$(IntDir)decrypt\</ObjectFileName>
|
||||||
|
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Dev+|x64'">$(IntDir)decrypt\</ObjectFileName>
|
||||||
|
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)decrypt\</ObjectFileName>
|
||||||
|
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)decrypt\</ObjectFileName>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\utils\decrypt\decrypt.cpp" />
|
||||||
|
<ClCompile Include="..\utils\decrypt\header.cpp" />
|
||||||
|
<ClCompile Include="..\utils\libfat\cache.cpp" />
|
||||||
|
<ClCompile Include="..\utils\libfat\directory.cpp" />
|
||||||
|
<ClCompile Include="..\utils\libfat\disc.cpp" />
|
||||||
|
<ClCompile Include="..\utils\libfat\fatdir.cpp" />
|
||||||
|
<ClCompile Include="..\utils\libfat\fatfile.cpp" />
|
||||||
|
<ClCompile Include="..\utils\libfat\file_allocation_table.cpp" />
|
||||||
|
<ClCompile Include="..\utils\libfat\filetime.cpp" />
|
||||||
|
<ClCompile Include="..\utils\libfat\libfat.cpp" />
|
||||||
|
<ClCompile Include="..\utils\libfat\libfat_public_api.cpp" />
|
||||||
|
<ClCompile Include="..\utils\libfat\lock.cpp" />
|
||||||
|
<ClCompile Include="..\utils\libfat\partition.cpp" />
|
||||||
|
<ClCompile Include="..\utils\tinyxml\tinystr.cpp" />
|
||||||
|
<ClCompile Include="..\utils\tinyxml\tinyxml.cpp" />
|
||||||
|
<ClCompile Include="..\utils\tinyxml\tinyxmlerror.cpp" />
|
||||||
|
<ClCompile Include="..\utils\tinyxml\tinyxmlparser.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\assembler.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\assert.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\buffer.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\compiler.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\compilercontext.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\compilerfunc.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\compileritem.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\context.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\cpuinfo.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\defs.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\func.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\logger.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\memorymanager.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\memorymarker.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\operand.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\stringbuilder.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\stringutil.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\virtualmemory.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\core\zonememory.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86assembler.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86compiler.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86compilercontext.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86compilerfunc.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86compileritem.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86cpuinfo.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86defs.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86func.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86operand.cpp" />
|
||||||
|
<ClCompile Include="..\utils\AsmJit\x86\x86util.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\metaspu.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\SndOut.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\Timestretcher.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\win32\ConfigSoundtouch.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\SoundTouch\3dnow_win.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\SoundTouch\AAFilter.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\SoundTouch\cpu_detect_x86_win.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\SoundTouch\FIFOSampleBuffer.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\SoundTouch\FIRFilter.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\SoundTouch\mmx_optimized.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\SoundTouch\RateTransposer.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\SoundTouch\SoundTouch.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\SoundTouch\sse_optimized.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\SoundTouch\TDStretch.cpp" />
|
||||||
|
<ClCompile Include="..\metaspu\SoundTouch\WavFile.cpp" />
|
||||||
|
<ClCompile Include="..\wxdlg\wxdlg3dViewer.cpp" />
|
||||||
|
<ClCompile Include="..\filter\2xsai.cpp" />
|
||||||
|
<ClCompile Include="..\filter\bilinear.cpp" />
|
||||||
|
<ClCompile Include="..\filter\epx.cpp" />
|
||||||
|
<ClCompile Include="..\filter\hq2x.cpp" />
|
||||||
|
<ClCompile Include="..\filter\hq4x.cpp" />
|
||||||
|
<ClCompile Include="..\filter\lq2x.cpp" />
|
||||||
|
<ClCompile Include="..\filter\scanline.cpp" />
|
||||||
|
<ClCompile Include="AboutBox.cpp" />
|
||||||
|
<ClCompile Include="aviout.cpp" />
|
||||||
|
<ClCompile Include="cheatsWin.cpp" />
|
||||||
|
<ClCompile Include="colorctrl.cpp" />
|
||||||
|
<ClCompile Include="console.cpp" />
|
||||||
|
<ClCompile Include="CWindow.cpp" />
|
||||||
|
<ClCompile Include="FEX_Interface.cpp" />
|
||||||
|
<ClCompile Include="FirmConfig.cpp" />
|
||||||
|
<ClCompile Include="gbaslot_config.cpp" />
|
||||||
|
<ClCompile Include="hotkey.cpp" />
|
||||||
|
<ClCompile Include="importSave.cpp" />
|
||||||
|
<ClCompile Include="inputdx.cpp" />
|
||||||
|
<ClCompile Include="luaconsole.cpp" />
|
||||||
|
<ClCompile Include="main.cpp" />
|
||||||
|
<ClCompile Include="mic.cpp" />
|
||||||
|
<ClCompile Include="ogl.cpp" />
|
||||||
|
<ClCompile Include="OpenArchive.cpp" />
|
||||||
|
<ClCompile Include="pathsettings.cpp" />
|
||||||
|
<ClCompile Include="recentroms.cpp" />
|
||||||
|
<ClCompile Include="replay.cpp" />
|
||||||
|
<ClCompile Include="slot1_config.cpp" />
|
||||||
|
<ClCompile Include="snddx.cpp" />
|
||||||
|
<ClCompile Include="throttle.cpp" />
|
||||||
|
<ClCompile Include="winutil.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\fex\Binary_Extractor.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\fex\blargg_common.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\fex\blargg_errors.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\fex\Data_Reader.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\fex\fex.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\fex\File_Extractor.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\fex\Gzip_Extractor.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\fex\Gzip_Reader.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\fex\Rar_Extractor.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\fex\Zip7_Extractor.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\fex\Zip_Extractor.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\fex\Zlib_Inflater.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\7zAlloc.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\7zBuf.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\7zBuf2.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\7zCrc.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\7zCrcOpt.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\7zDec.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\7zFile.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\7zIn.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\7zStream.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\Alloc.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\Bcj2.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\Bra.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\Bra86.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\BraIA64.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\CpuArch.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\Delta.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\LzFind.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\LzFindMt.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\Lzma2Dec.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\Lzma2Enc.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\Lzma86Dec.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\Lzma86Enc.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\LzmaDec.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\LzmaEnc.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\LzmaLib.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\MtCoder.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\Ppmd7.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\Ppmd7Dec.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\Ppmd7Enc.c" />
|
||||||
|
<ClCompile Include="File_Extractor\7z_C\Threads.c" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\archive.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\arcread.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\coder.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\crc.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\encname.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\extract.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\getbits.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\model.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\rarvm.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\rarvmtbl.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\rawread.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\suballoc.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\unicode.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\unpack.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\unpack15.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\unpack20.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\unrar.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\unrar_misc.cpp" />
|
||||||
|
<ClCompile Include="File_Extractor\unrar\unrar_open.cpp" />
|
||||||
|
<ClCompile Include="disView.cpp" />
|
||||||
|
<ClCompile Include="ginfo.cpp" />
|
||||||
|
<ClCompile Include="IORegView.cpp" />
|
||||||
|
<ClCompile Include="lightView.cpp" />
|
||||||
|
<ClCompile Include="mapView.cpp" />
|
||||||
|
<ClCompile Include="matrixView.cpp" />
|
||||||
|
<ClCompile Include="memView.cpp" />
|
||||||
|
<ClCompile Include="oamView.cpp" />
|
||||||
|
<ClCompile Include="palView.cpp" />
|
||||||
|
<ClCompile Include="ram_search.cpp" />
|
||||||
|
<ClCompile Include="ramwatch.cpp" />
|
||||||
|
<ClCompile Include="soundView.cpp" />
|
||||||
|
<ClCompile Include="tileView.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\addons.h" />
|
||||||
|
<ClInclude Include="..\arm_jit.h" />
|
||||||
|
<ClInclude Include="..\armcpu.h" />
|
||||||
|
<ClInclude Include="..\bios.h" />
|
||||||
|
<ClInclude Include="..\bits.h" />
|
||||||
|
<ClInclude Include="..\cheatSystem.h" />
|
||||||
|
<ClInclude Include="..\commandline.h" />
|
||||||
|
<ClInclude Include="..\common.h" />
|
||||||
|
<ClInclude Include="..\cp15.h" />
|
||||||
|
<ClInclude Include="..\debug.h" />
|
||||||
|
<ClInclude Include="..\Disassembler.h" />
|
||||||
|
<ClInclude Include="..\driver.h" />
|
||||||
|
<ClInclude Include="..\emufile.h" />
|
||||||
|
<ClInclude Include="..\fat.h" />
|
||||||
|
<ClInclude Include="..\FIFO.h" />
|
||||||
|
<ClInclude Include="..\firmware.h" />
|
||||||
|
<ClInclude Include="..\fs.h" />
|
||||||
|
<ClInclude Include="..\gfx3d.h" />
|
||||||
|
<ClInclude Include="..\GPU.h" />
|
||||||
|
<ClInclude Include="..\GPU_osd.h" />
|
||||||
|
<ClInclude Include="..\instruction_attributes.h" />
|
||||||
|
<ClInclude Include="..\instructions.h" />
|
||||||
|
<ClInclude Include="..\lua-engine.h" />
|
||||||
|
<ClInclude Include="..\matrix.h" />
|
||||||
|
<ClInclude Include="..\mc.h" />
|
||||||
|
<ClInclude Include="..\mem.h" />
|
||||||
|
<ClInclude Include="..\mic.h" />
|
||||||
|
<ClInclude Include="..\MMU.h" />
|
||||||
|
<ClInclude Include="..\MMU_timing.h" />
|
||||||
|
<ClInclude Include="..\movie.h" />
|
||||||
|
<ClInclude Include="..\NDSSystem.h" />
|
||||||
|
<ClInclude Include="..\OGLRender.h" />
|
||||||
|
<ClInclude Include="..\path.h" />
|
||||||
|
<ClInclude Include="..\rasterize.h" />
|
||||||
|
<ClInclude Include="..\readwrite.h" />
|
||||||
|
<ClInclude Include="..\registers.h" />
|
||||||
|
<ClInclude Include="..\render3D.h" />
|
||||||
|
<ClInclude Include="..\ROMReader.h" />
|
||||||
|
<ClInclude Include="..\rtc.h" />
|
||||||
|
<ClInclude Include="..\saves.h" />
|
||||||
|
<ClInclude Include="..\shaders.h" />
|
||||||
|
<ClInclude Include="..\slot1.h" />
|
||||||
|
<ClInclude Include="..\SPU.h" />
|
||||||
|
<ClInclude Include="..\texcache.h" />
|
||||||
|
<ClInclude Include="..\types.h" />
|
||||||
|
<ClInclude Include="..\version.h" />
|
||||||
|
<ClInclude Include="..\wifi.h" />
|
||||||
|
<ClInclude Include="..\utils\xstring.h" />
|
||||||
|
<ClInclude Include="..\gdbstub.h" />
|
||||||
|
<ClInclude Include="..\utils\ConvertUTF.h" />
|
||||||
|
<ClInclude Include="..\utils\datetime.h" />
|
||||||
|
<ClInclude Include="..\utils\emufat.h" />
|
||||||
|
<ClInclude Include="..\utils\guid.h" />
|
||||||
|
<ClInclude Include="..\utils\md5.h" />
|
||||||
|
<ClInclude Include="..\utils\task.h" />
|
||||||
|
<ClInclude Include="..\utils\valuearray.h" />
|
||||||
|
<ClInclude Include="..\utils\vfat.h" />
|
||||||
|
<ClInclude Include="..\utils\decrypt\crc.h" />
|
||||||
|
<ClInclude Include="..\utils\decrypt\decrypt.h" />
|
||||||
|
<ClInclude Include="..\utils\decrypt\header.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\bit_ops.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\cache.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\common.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\directory.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\disc.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\disc_io.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\fat.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\fatdir.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\fatfile.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\file_allocation_table.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\filetime.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\libfat_pc.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\libfat_public_api.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\lock.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\mem_allocate.h" />
|
||||||
|
<ClInclude Include="..\utils\libfat\partition.h" />
|
||||||
|
<ClInclude Include="..\utils\tinyxml\tinystr.h" />
|
||||||
|
<ClInclude Include="..\utils\tinyxml\tinyxml.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\asmjit.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\config.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\apibegin.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\apiend.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\assembler.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\assert.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\buffer.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\build.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\compiler.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\compilercontext.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\compilerfunc.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\compileritem.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\context.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\cpuinfo.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\defs.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\func.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\intutil.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\lock.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\logger.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\memorymanager.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\memorymarker.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\operand.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\podvector.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\stringbuilder.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\stringutil.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\virtualmemory.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\core\zonememory.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86assembler.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86compiler.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86compilercontext.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86compilerfunc.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86compileritem.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86cpuinfo.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86defs.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86func.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86operand.h" />
|
||||||
|
<ClInclude Include="..\utils\AsmJit\x86\x86util.h" />
|
||||||
|
<ClInclude Include="..\metaspu\metaspu.h" />
|
||||||
|
<ClInclude Include="..\metaspu\SndOut.h" />
|
||||||
|
<ClInclude Include="..\metaspu\win32\Dialogs.h" />
|
||||||
|
<ClInclude Include="..\metaspu\SoundTouch\AAFilter.h" />
|
||||||
|
<ClInclude Include="..\metaspu\SoundTouch\BPMDetect.h" />
|
||||||
|
<ClInclude Include="..\metaspu\SoundTouch\cpu_detect.h" />
|
||||||
|
<ClInclude Include="..\metaspu\SoundTouch\FIFOSampleBuffer.h" />
|
||||||
|
<ClInclude Include="..\metaspu\SoundTouch\FIFOSamplePipe.h" />
|
||||||
|
<ClInclude Include="..\metaspu\SoundTouch\FIRFilter.h" />
|
||||||
|
<ClInclude Include="..\metaspu\SoundTouch\RateTransposer.h" />
|
||||||
|
<ClInclude Include="..\metaspu\SoundTouch\SoundTouch.h" />
|
||||||
|
<ClInclude Include="..\metaspu\SoundTouch\STTypes.h" />
|
||||||
|
<ClInclude Include="..\metaspu\SoundTouch\TDStretch.h" />
|
||||||
|
<ClInclude Include="..\metaspu\SoundTouch\WavFile.h" />
|
||||||
|
<ClInclude Include="..\wxdlg\wxdlg3dViewer.h" />
|
||||||
|
<ClInclude Include="..\filter\filter.h" />
|
||||||
|
<ClInclude Include="..\filter\hq2x.h" />
|
||||||
|
<ClInclude Include="..\filter\hq4x.h" />
|
||||||
|
<ClInclude Include="..\filter\interp.h" />
|
||||||
|
<ClInclude Include="..\filter\lq2x.h" />
|
||||||
|
<ClInclude Include="AboutBox.h" />
|
||||||
|
<ClInclude Include="aviout.h" />
|
||||||
|
<ClInclude Include="cheatsWin.h" />
|
||||||
|
<ClInclude Include="colorctrl.h" />
|
||||||
|
<ClInclude Include="console.h" />
|
||||||
|
<ClInclude Include="CWindow.h" />
|
||||||
|
<ClInclude Include="FirmConfig.h" />
|
||||||
|
<ClInclude Include="gbaslot_config.h" />
|
||||||
|
<ClInclude Include="hotkey.h" />
|
||||||
|
<ClInclude Include="importSave.h" />
|
||||||
|
<ClInclude Include="inputdx.h" />
|
||||||
|
<ClInclude Include="main.h" />
|
||||||
|
<ClInclude Include="OpenArchive.h" />
|
||||||
|
<ClInclude Include="pathsettings.h" />
|
||||||
|
<ClInclude Include="recentroms.h" />
|
||||||
|
<ClInclude Include="replay.h" />
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
|
<ClInclude Include="slot1_config.h" />
|
||||||
|
<ClInclude Include="snddx.h" />
|
||||||
|
<ClInclude Include="throttle.h" />
|
||||||
|
<ClInclude Include="winpcap.h" />
|
||||||
|
<ClInclude Include="winutil.h" />
|
||||||
|
<ClInclude Include="userconfig\userconfig.h" />
|
||||||
|
<ClInclude Include="disView.h" />
|
||||||
|
<ClInclude Include="ginfo.h" />
|
||||||
|
<ClInclude Include="IORegView.h" />
|
||||||
|
<ClInclude Include="lightView.h" />
|
||||||
|
<ClInclude Include="mapView.h" />
|
||||||
|
<ClInclude Include="matrixView.h" />
|
||||||
|
<ClInclude Include="memView.h" />
|
||||||
|
<ClInclude Include="oamView.h" />
|
||||||
|
<ClInclude Include="palView.h" />
|
||||||
|
<ClInclude Include="ram_search.h" />
|
||||||
|
<ClInclude Include="ramwatch.h" />
|
||||||
|
<ClInclude Include="soundView.h" />
|
||||||
|
<ClInclude Include="tileView.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\instruction_tabdef.inc" />
|
||||||
|
<None Include="..\thumb_tabdef.inc" />
|
||||||
|
<None Include="..\filter\hq4x.dat" />
|
||||||
|
<CustomBuild Include="directx\directx.7z">
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">un7z_and_touch.bat directx\directx.7z .libs\directx*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.libs\directx.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">un7z_and_touch.bat directx\directx.7z .libs\directx*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.libs\directx.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">un7z_and_touch.bat directx\directx.7z .libs\directx*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">.libs\directx.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">un7z_and_touch.bat directx\directx.7z .libs\directx*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.libs\directx.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">un7z_and_touch.bat directx\directx.7z .libs\directx*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.libs\directx.tag;%(Outputs)</Outputs>
|
||||||
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="glib-2.20.1\glib-2.20.1.7z">
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">un7z_and_touch.bat glib-2.20.1\glib-2.20.1.7z .libs\glib*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.libs\glib-vc8.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">un7z_and_touch.bat glib-2.20.1\glib-2.20.1.7z .libs\glib*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.libs\glib-vc8.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">un7z_and_touch.bat glib-2.20.1\glib-2.20.1.7z .libs\glib*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">.libs\glib-vc8.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">un7z_and_touch.bat glib-2.20.1\glib-2.20.1.7z .libs\glib*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.libs\glib-vc8.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">un7z_and_touch.bat glib-2.20.1\glib-2.20.1.7z .libs\glib*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.libs\glib-vc8.tag;%(Outputs)</Outputs>
|
||||||
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="libelf_libdwarf\libelf_libdwarf.7z">
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">un7z_and_touch.bat libelf_libdwarf\libelf_libdwarf.7z .libs\libelf_libdwarf*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.libs\libelf_libdwarf.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">un7z_and_touch.bat libelf_libdwarf\libelf_libdwarf.7z .libs\libelf_libdwarf*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.libs\libelf_libdwarf.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">un7z_and_touch.bat libelf_libdwarf\libelf_libdwarf.7z .libs\libelf_libdwarf*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">.libs\libelf_libdwarf.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Dev+|x64'">un7z_and_touch.bat libelf_libdwarf\libelf_libdwarf.7z .libs\libelf_libdwarf*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Dev+|x64'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Dev+|x64'">.libs\libelf_libdwarf.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">un7z_and_touch.bat libelf_libdwarf\libelf_libdwarf.7z .libs\libelf_libdwarf*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.libs\libelf_libdwarf.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">un7z_and_touch.bat libelf_libdwarf\libelf_libdwarf.7z .libs\libelf_libdwarf*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.libs\libelf_libdwarf.tag;%(Outputs)</Outputs>
|
||||||
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="lua\lua.7z">
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.libs\lua.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.libs\lua.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">.libs\lua.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Dev+|x64'">un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag
|
||||||
|
</Command>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Dev+|x64'">.libs\lua.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.libs\lua.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.libs\lua.tag;%(Outputs)</Outputs>
|
||||||
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="wx\wx.7z">
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">un7z_and_touch.bat wx\wx.7z .libs\wx*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.libs\wx.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">un7z_and_touch.bat wx\wx.7z .libs\wx*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.libs\wx.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">un7z_and_touch.bat wx\wx.7z .libs\wx*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Dev+|Win32'">.libs\wx.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">un7z_and_touch.bat wx\wx.7z .libs\wx*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.libs\wx.tag;%(Outputs)</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">un7z_and_touch.bat wx\wx.7z .libs\wx*
|
||||||
|
</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">7z.exe;un7z_and_touch.bat;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.libs\wx.tag;%(Outputs)</Outputs>
|
||||||
|
</CustomBuild>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Text Include="..\utils\AsmJit\COPYING.txt" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Image Include="bitmap1.bmp" />
|
||||||
|
<Image Include="DeSmuME.ico" />
|
||||||
|
<Image Include="bitmaps\IDB_FRAMEADVANCE.bmp" />
|
||||||
|
<Image Include="bitmaps\IDB_OPEN.bmp" />
|
||||||
|
<Image Include="bitmaps\IDB_PAUSE.bmp" />
|
||||||
|
<Image Include="bitmaps\IDB_PLAY.bmp" />
|
||||||
|
<Image Include="bitmaps\IDB_RESET.bmp" />
|
||||||
|
<Image Include="bitmaps\IDB_ROTATECCW.bmp" />
|
||||||
|
<Image Include="bitmaps\IDB_ROTATECW.bmp" />
|
||||||
|
<Image Include="bitmaps\IDB_STOP.bmp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="resources.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ProjectExtensions>
|
||||||
|
<VisualStudio>
|
||||||
|
<UserProperties RESOURCE_FILE="resources.rc" />
|
||||||
|
</VisualStudio>
|
||||||
|
</ProjectExtensions>
|
||||||
|
</Project>
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue