add x86 asmjit

This commit is contained in:
_or_75
2026-05-20 01:20:35 +03:00
parent 42996fba47
commit e9d13a3364
8 changed files with 17539 additions and 1 deletions
-1
View File
@@ -22,7 +22,6 @@ mono_crash.*
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,523 @@
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Guard]
#ifndef _ASMJIT_X86_X86CONTEXT_P_H
#define _ASMJIT_X86_X86CONTEXT_P_H
#include "../build.h"
#if !defined(ASMJIT_DISABLE_COMPILER)
// [Dependencies - AsmJit]
#include "../base/compiler.h"
#include "../base/context_p.h"
#include "../base/intutil.h"
#include "../x86/x86assembler.h"
#include "../x86/x86compiler.h"
// [Api-Begin]
#include "../apibegin.h"
namespace asmjit {
//! \addtogroup asmjit_x86_compiler
//! \{
// ============================================================================
// [asmjit::X86Context]
// ============================================================================
#if defined(ASMJIT_DEBUG)
# define ASMJIT_X86_CHECK_STATE _checkState();
#else
# define ASMJIT_X86_CHECK_STATE
#endif // ASMJIT_DEBUG
//! \internal
//!
//! Compiler context is used by `X86Compiler`.
//!
//! Compiler 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 X86Context : public Context {
ASMJIT_NO_COPY(X86Context)
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
//! Create a new `X86Context` instance.
X86Context(X86Compiler* compiler);
//! Destroy the `X86Context` instance.
virtual ~X86Context();
// --------------------------------------------------------------------------
// [Reset]
// --------------------------------------------------------------------------
virtual void reset(bool releaseMemory = false);
// --------------------------------------------------------------------------
// [Arch]
// --------------------------------------------------------------------------
ASMJIT_INLINE bool isX64() const {
return _zsp.getSize() == 16;
}
// --------------------------------------------------------------------------
// [Accessors]
// --------------------------------------------------------------------------
//! Get compiler as `X86Compiler`.
ASMJIT_INLINE X86Compiler* getCompiler() const {
return static_cast<X86Compiler*>(_compiler);
}
//! Get function as `X86FuncNode`.
ASMJIT_INLINE X86FuncNode* getFunc() const {
return reinterpret_cast<X86FuncNode*>(_func);
}
//! Get clobbered registers (global).
ASMJIT_INLINE uint32_t getClobberedRegs(uint32_t c) {
return _clobberedRegs.get(c);
}
// --------------------------------------------------------------------------
// [Helpers]
// --------------------------------------------------------------------------
ASMJIT_INLINE X86VarMap* newVarMap(uint32_t vaCount) {
return static_cast<X86VarMap*>(
_baseZone.alloc(sizeof(X86VarMap) + vaCount * sizeof(VarAttr)));
}
// --------------------------------------------------------------------------
// [Emit]
// --------------------------------------------------------------------------
void emitLoad(VarData* vd, uint32_t regIndex, const char* reason);
void emitSave(VarData* vd, uint32_t regIndex, const char* reason);
void emitMove(VarData* vd, uint32_t toRegIndex, uint32_t fromRegIndex, const char* reason);
void emitSwapGp(VarData* aVd, VarData* bVd, uint32_t aIndex, uint32_t bIndex, const char* reason);
void emitPushSequence(uint32_t regs);
void emitPopSequence(uint32_t regs);
void emitConvertVarToVar(uint32_t dstType, uint32_t dstIndex, uint32_t srcType, uint32_t srcIndex);
void emitMoveVarOnStack(uint32_t dstType, const X86Mem* dst, uint32_t srcType, uint32_t srcIndex);
void emitMoveImmOnStack(uint32_t dstType, const X86Mem* dst, const Imm* src);
void emitMoveImmToReg(uint32_t dstType, uint32_t dstIndex, const Imm* src);
// --------------------------------------------------------------------------
// [Register Management]
// --------------------------------------------------------------------------
void _checkState();
ASMJIT_INLINE uint32_t getRegSize() const {
return _zsp.getSize();
}
// --------------------------------------------------------------------------
// [Attach / Detach]
// --------------------------------------------------------------------------
//! Attach.
//!
//! Attach a register to the 'VarData', changing 'VarData' members to show
//! that the variable is currently alive and linking variable with the
//! current 'X86VarState'.
template<int C>
ASMJIT_INLINE void attach(VarData* vd, uint32_t regIndex, bool modified) {
ASMJIT_ASSERT(vd->getClass() == C);
ASMJIT_ASSERT(regIndex != kInvalidReg);
// Prevent Esp allocation if C==Gp.
ASMJIT_ASSERT(C != kX86RegClassGp || regIndex != kX86RegIndexSp);
uint32_t regMask = IntUtil::mask(regIndex);
vd->setState(kVarStateReg);
vd->setRegIndex(regIndex);
vd->addHomeIndex(regIndex);
vd->setModified(modified);
_x86State.getListByClass(C)[regIndex] = vd;
_x86State._occupied.or_(C, regMask);
_x86State._modified.or_(C, static_cast<uint32_t>(modified) << regIndex);
ASMJIT_X86_CHECK_STATE
}
//! Detach.
//!
//! The opposite of 'Attach'. Detach resets the members in 'VarData'
//! (regIndex, state and changed flags) and unlinks the variable with the
//! current 'X86VarState'.
template<int C>
ASMJIT_INLINE void detach(VarData* vd, uint32_t regIndex, uint32_t vState) {
ASMJIT_ASSERT(vd->getClass() == C);
ASMJIT_ASSERT(vd->getRegIndex() == regIndex);
ASMJIT_ASSERT(vState != kVarStateReg);
uint32_t regMask = IntUtil::mask(regIndex);
vd->setState(vState);
vd->resetRegIndex();
vd->setModified(false);
_x86State.getListByClass(C)[regIndex] = NULL;
_x86State._occupied.andNot(C, regMask);
_x86State._modified.andNot(C, regMask);
ASMJIT_X86_CHECK_STATE
}
// --------------------------------------------------------------------------
// [Rebase]
// --------------------------------------------------------------------------
//! Rebase.
//!
//! Change the register of the 'VarData' changing also the current 'X86VarState'.
//! Rebase is nearly identical to 'Detach' and 'Attach' sequence, but doesn't
// change the 'VarData' modified flag.
template<int C>
ASMJIT_INLINE void rebase(VarData* vd, uint32_t newRegIndex, uint32_t oldRegIndex) {
ASMJIT_ASSERT(vd->getClass() == C);
uint32_t newRegMask = IntUtil::mask(newRegIndex);
uint32_t oldRegMask = IntUtil::mask(oldRegIndex);
uint32_t bothRegMask = newRegMask ^ oldRegMask;
vd->setRegIndex(newRegIndex);
_x86State.getListByClass(C)[oldRegIndex] = NULL;
_x86State.getListByClass(C)[newRegIndex] = vd;
_x86State._occupied.xor_(C, bothRegMask);
_x86State._modified.xor_(C, bothRegMask & -static_cast<int32_t>(vd->isModified()));
ASMJIT_X86_CHECK_STATE
}
// --------------------------------------------------------------------------
// [Load / Save]
// --------------------------------------------------------------------------
//! Load.
//!
//! Load variable from its memory slot to a register, emitting 'Load'
//! instruction and changing the variable state to allocated.
template<int C>
ASMJIT_INLINE void load(VarData* vd, uint32_t regIndex) {
// Can be only called if variable is not allocated.
ASMJIT_ASSERT(vd->getClass() == C);
ASMJIT_ASSERT(vd->getState() != kVarStateReg);
ASMJIT_ASSERT(vd->getRegIndex() == kInvalidReg);
emitLoad(vd, regIndex, "Load");
attach<C>(vd, regIndex, false);
ASMJIT_X86_CHECK_STATE
}
//! Save.
//!
//! Save the variable into its home location, but keep it as allocated.
template<int C>
ASMJIT_INLINE void save(VarData* vd) {
ASMJIT_ASSERT(vd->getClass() == C);
ASMJIT_ASSERT(vd->getState() == kVarStateReg);
ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg);
uint32_t regIndex = vd->getRegIndex();
uint32_t regMask = IntUtil::mask(regIndex);
emitSave(vd, regIndex, "Save");
vd->setModified(false);
_x86State._modified.andNot(C, regMask);
ASMJIT_X86_CHECK_STATE
}
// --------------------------------------------------------------------------
// [Move / Swap]
// --------------------------------------------------------------------------
//! Move a register.
//!
//! Move register from one index to another, emitting 'Move' if needed. This
//! function does nothing if register is already at the given index.
template<int C>
ASMJIT_INLINE void move(VarData* vd, uint32_t regIndex) {
ASMJIT_ASSERT(vd->getClass() == C);
ASMJIT_ASSERT(vd->getState() == kVarStateReg);
ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg);
uint32_t oldIndex = vd->getRegIndex();
if (regIndex != oldIndex) {
emitMove(vd, regIndex, oldIndex, "Move");
rebase<C>(vd, regIndex, oldIndex);
}
ASMJIT_X86_CHECK_STATE
}
//! Swap two registers
//!
//! It's only possible to swap Gp registers.
ASMJIT_INLINE void swapGp(VarData* aVd, VarData* bVd) {
ASMJIT_ASSERT(aVd != bVd);
ASMJIT_ASSERT(aVd->getClass() == kX86RegClassGp);
ASMJIT_ASSERT(aVd->getState() == kVarStateReg);
ASMJIT_ASSERT(aVd->getRegIndex() != kInvalidReg);
ASMJIT_ASSERT(bVd->getClass() == kX86RegClassGp);
ASMJIT_ASSERT(bVd->getState() == kVarStateReg);
ASMJIT_ASSERT(bVd->getRegIndex() != kInvalidReg);
uint32_t aIndex = aVd->getRegIndex();
uint32_t bIndex = bVd->getRegIndex();
emitSwapGp(aVd, bVd, aIndex, bIndex, "Swap");
aVd->setRegIndex(bIndex);
bVd->setRegIndex(aIndex);
_x86State.getListByClass(kX86RegClassGp)[aIndex] = bVd;
_x86State.getListByClass(kX86RegClassGp)[bIndex] = aVd;
uint32_t m = aVd->isModified() ^ bVd->isModified();
_x86State._modified.xor_(kX86RegClassGp, (m << aIndex) | (m << bIndex));
ASMJIT_X86_CHECK_STATE
}
// --------------------------------------------------------------------------
// [Alloc / Spill]
// --------------------------------------------------------------------------
//! Alloc.
template<int C>
ASMJIT_INLINE void alloc(VarData* vd, uint32_t regIndex) {
ASMJIT_ASSERT(vd->getClass() == C);
ASMJIT_ASSERT(regIndex != kInvalidReg);
uint32_t oldRegIndex = vd->getRegIndex();
uint32_t oldState = vd->getState();
uint32_t regMask = IntUtil::mask(regIndex);
ASMJIT_ASSERT(_x86State.getListByClass(C)[regIndex] == NULL || regIndex == oldRegIndex);
if (oldState != kVarStateReg) {
if (oldState == kVarStateMem)
emitLoad(vd, regIndex, "Alloc");
vd->setModified(false);
}
else if (oldRegIndex != regIndex) {
emitMove(vd, regIndex, oldRegIndex, "Alloc");
_x86State.getListByClass(C)[oldRegIndex] = NULL;
regMask ^= IntUtil::mask(oldRegIndex);
}
else {
ASMJIT_X86_CHECK_STATE
return;
}
vd->setState(kVarStateReg);
vd->setRegIndex(regIndex);
_x86State.getListByClass(C)[regIndex] = vd;
_x86State._occupied.xor_(C, regMask);
_x86State._modified.xor_(C, regMask & -static_cast<int32_t>(vd->isModified()));
ASMJIT_X86_CHECK_STATE
}
//! Spill.
//!
//! Spill variable/register, saves the content to the memory-home if modified.
template<int C>
ASMJIT_INLINE void spill(VarData* vd) {
ASMJIT_ASSERT(vd->getClass() == C);
if (vd->getState() != kVarStateReg) {
ASMJIT_X86_CHECK_STATE
return;
}
uint32_t regIndex = vd->getRegIndex();
ASMJIT_ASSERT(regIndex != kInvalidReg);
ASMJIT_ASSERT(_x86State.getListByClass(C)[regIndex] == vd);
if (vd->isModified())
emitSave(vd, regIndex, "Spill");
detach<C>(vd, regIndex, kVarStateMem);
ASMJIT_X86_CHECK_STATE
}
// --------------------------------------------------------------------------
// [Modify]
// --------------------------------------------------------------------------
template<int C>
ASMJIT_INLINE void modify(VarData* vd) {
ASMJIT_ASSERT(vd->getClass() == C);
uint32_t regIndex = vd->getRegIndex();
uint32_t regMask = IntUtil::mask(regIndex);
vd->setModified(true);
_x86State._modified.or_(C, regMask);
ASMJIT_X86_CHECK_STATE
}
// --------------------------------------------------------------------------
// [Unuse]
// --------------------------------------------------------------------------
//! Unuse.
//!
//! Unuse variable, it will be detached it if it's allocated then its state
//! will be changed to kVarStateUnused.
template<int C>
ASMJIT_INLINE void unuse(VarData* vd, uint32_t vState = kVarStateUnused) {
ASMJIT_ASSERT(vd->getClass() == C);
ASMJIT_ASSERT(vState != kVarStateReg);
uint32_t regIndex = vd->getRegIndex();
if (regIndex != kInvalidReg)
detach<C>(vd, regIndex, vState);
else
vd->setState(vState);
ASMJIT_X86_CHECK_STATE
}
// --------------------------------------------------------------------------
// [State]
// --------------------------------------------------------------------------
//! Get state as `X86VarState`.
ASMJIT_INLINE X86VarState* getState() const {
return const_cast<X86VarState*>(&_x86State);
}
virtual void loadState(VarState* src);
virtual VarState* saveState();
virtual void switchState(VarState* src);
virtual void intersectStates(VarState* a, VarState* b);
// --------------------------------------------------------------------------
// [Memory]
// --------------------------------------------------------------------------
ASMJIT_INLINE X86Mem getVarMem(VarData* vd) {
(void)getVarCell(vd);
X86Mem mem(_memSlot);
mem.setBase(vd->getId());
return mem;
}
// --------------------------------------------------------------------------
// [Fetch]
// --------------------------------------------------------------------------
virtual Error fetch();
// --------------------------------------------------------------------------
// [Annotate]
// --------------------------------------------------------------------------
virtual Error annotate();
// --------------------------------------------------------------------------
// [Translate]
// --------------------------------------------------------------------------
virtual Error translate();
// --------------------------------------------------------------------------
// [Schedule]
// --------------------------------------------------------------------------
virtual Error schedule();
// --------------------------------------------------------------------------
// [Serialize]
// --------------------------------------------------------------------------
virtual Error serialize(Assembler* assembler, Node* start, Node* stop);
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
//! Count of X86/X64 registers.
X86RegCount _regCount;
//! X86/X64 stack-pointer (esp or rsp).
X86GpReg _zsp;
//! X86/X64 frame-pointer (ebp or rbp).
X86GpReg _zbp;
//! Temporary memory operand.
X86Mem _memSlot;
//! X86/X64 specific compiler state, linked to `_state`.
X86VarState _x86State;
//! Clobbered registers (for the whole function).
X86RegMask _clobberedRegs;
//! Memory cell where is stored address used to restore manually
//! aligned stack.
MemCell* _stackFrameCell;
//! Global allocable registers mask.
uint32_t _gaRegs[kX86RegClassCount];
//! Function arguments base pointer (register).
uint8_t _argBaseReg;
//! Function variables base pointer (register).
uint8_t _varBaseReg;
//! Whether to emit comments.
uint8_t _emitComments;
//! Function arguments base offset.
int32_t _argBaseOffset;
//! Function variables base offset.
int32_t _varBaseOffset;
//! Function arguments displacement.
int32_t _argActualDisp;
//! Function variables displacement.
int32_t _varActualDisp;
//! Temporary string builder used for logging.
StringBuilderT<256> _stringBuilder;
};
//! \}
} // asmjit namespace
// [Api-End]
#include "../apiend.h"
// [Guard]
#endif // !ASMJIT_DISABLE_COMPILER
#endif // _ASMJIT_X86_X86CONTEXT_P_H
@@ -0,0 +1,263 @@
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Guard]
#ifndef _ASMJIT_X86_X86CPUINFO_H
#define _ASMJIT_X86_X86CPUINFO_H
// [Dependencies - AsmJit]
#include "../base/cpuinfo.h"
// [Api-Begin]
#include "../apibegin.h"
namespace asmjit {
// ============================================================================
// [Forward Declarations]
// ============================================================================
struct X86CpuInfo;
//! \addtogroup asmjit_x86_general
//! \{
// ============================================================================
// [asmjit::kX86CpuFeature]
// ============================================================================
//! X86 CPU features.
ASMJIT_ENUM(kX86CpuFeature) {
//! Cpu has Not-Execute-Bit.
kX86CpuFeatureNX = 0,
//! Cpu has multithreading.
kX86CpuFeatureMT,
//! Cpu has RDTSC.
kX86CpuFeatureRDTSC,
//! Cpu has RDTSCP.
kX86CpuFeatureRDTSCP,
//! Cpu has CMOV.
kX86CpuFeatureCMOV,
//! Cpu has CMPXCHG8B.
kX86CpuFeatureCMPXCHG8B,
//! Cpu has CMPXCHG16B (X64).
kX86CpuFeatureCMPXCHG16B,
//! Cpu has CLFUSH.
kX86CpuFeatureCLFLUSH,
//! Cpu has CLFUSH (Optimized).
kX86CpuFeatureCLFLUSHOpt,
//! Cpu has PREFETCH.
kX86CpuFeaturePREFETCH,
//! Cpu has PREFETCHWT1.
kX86CpuFeaturePREFETCHWT1,
//! Cpu has LAHF/SAHF.
kX86CpuFeatureLahfSahf,
//! Cpu has FXSAVE/FXRSTOR.
kX86CpuFeatureFXSR,
//! Cpu has FXSAVE/FXRSTOR (Optimized).
kX86CpuFeatureFXSROpt,
//! Cpu has MMX.
kX86CpuFeatureMMX,
//! Cpu has extended MMX.
kX86CpuFeatureMMX2,
//! Cpu has 3dNow!
kX86CpuFeature3DNOW,
//! Cpu has enchanced 3dNow!
kX86CpuFeature3DNOW2,
//! Cpu has SSE.
kX86CpuFeatureSSE,
//! Cpu has SSE2.
kX86CpuFeatureSSE2,
//! Cpu has SSE3.
kX86CpuFeatureSSE3,
//! Cpu has SSSE3.
kX86CpuFeatureSSSE3,
//! Cpu has SSE4.A.
kX86CpuFeatureSSE4A,
//! Cpu has SSE4.1.
kX86CpuFeatureSSE4_1,
//! Cpu has SSE4.2.
kX86CpuFeatureSSE4_2,
//! Cpu has Misaligned SSE (MSSE).
kX86CpuFeatureMSSE,
//! Cpu has MONITOR and MWAIT.
kX86CpuFeatureMONITOR,
//! Cpu has MOVBE.
kX86CpuFeatureMOVBE,
//! Cpu has POPCNT.
kX86CpuFeaturePOPCNT,
//! Cpu has LZCNT.
kX86CpuFeatureLZCNT,
//! Cpu has AESNI.
kX86CpuFeatureAESNI,
//! Cpu has PCLMULQDQ.
kX86CpuFeaturePCLMULQDQ,
//! Cpu has RDRAND.
kX86CpuFeatureRDRAND,
//! Cpu has RDSEED.
kX86CpuFeatureRDSEED,
//! Cpu has SHA-1 and SHA-256.
kX86CpuFeatureSHA,
//! Cpu has XSAVE support - XSAVE/XRSTOR, XSETBV/XGETBV, and XCR0.
kX86CpuFeatureXSave,
//! OS has enabled XSAVE, you can call XGETBV to get value of XCR0.
kX86CpuFeatureXSaveOS,
//! Cpu has AVX.
kX86CpuFeatureAVX,
//! Cpu has AVX2.
kX86CpuFeatureAVX2,
//! Cpu has F16C.
kX86CpuFeatureF16C,
//! Cpu has FMA3.
kX86CpuFeatureFMA3,
//! Cpu has FMA4.
kX86CpuFeatureFMA4,
//! Cpu has XOP.
kX86CpuFeatureXOP,
//! Cpu has BMI.
kX86CpuFeatureBMI,
//! Cpu has BMI2.
kX86CpuFeatureBMI2,
//! Cpu has HLE.
kX86CpuFeatureHLE,
//! Cpu has RTM.
kX86CpuFeatureRTM,
//! Cpu has ADX.
kX86CpuFeatureADX,
//! Cpu has MPX (Memory Protection Extensions).
kX86CpuFeatureMPX,
//! Cpu has FSGSBASE.
kX86CpuFeatureFSGSBase,
//! Cpu has optimized REP MOVSB/STOSB.
kX86CpuFeatureMOVSBSTOSBOpt,
//! Cpu has AVX-512F (Foundation).
kX86CpuFeatureAVX512F,
//! Cpu has AVX-512CD (Conflict Detection).
kX86CpuFeatureAVX512CD,
//! Cpu has AVX-512PF (Prefetch Instructions).
kX86CpuFeatureAVX512PF,
//! Cpu has AVX-512ER (Exponential and Reciprocal Instructions).
kX86CpuFeatureAVX512ER,
//! Cpu has AVX-512DQ (DWord/QWord).
kX86CpuFeatureAVX512DQ,
//! Cpu has AVX-512BW (Byte/Word).
kX86CpuFeatureAVX512BW,
//! Cpu has AVX VL (Vector Length Excensions).
kX86CpuFeatureAVX512VL,
//! Count of X86/X64 Cpu features.
kX86CpuFeatureCount
};
// ============================================================================
// [asmjit::X86CpuId]
// ============================================================================
//! X86/X64 CPUID output.
union X86CpuId {
//! EAX/EBX/ECX/EDX output.
uint32_t i[4];
struct {
//! EAX output.
uint32_t eax;
//! EBX output.
uint32_t ebx;
//! ECX output.
uint32_t ecx;
//! EDX output.
uint32_t edx;
};
};
// ============================================================================
// [asmjit::X86CpuUtil]
// ============================================================================
#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
//! CPU utilities available only if the host processor is X86/X64.
struct X86CpuUtil {
//! Get the result of calling CPUID instruction to `out`.
ASMJIT_API static void callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* out);
//! Detect the Host CPU.
ASMJIT_API static void detect(X86CpuInfo* cpuInfo);
};
#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64
// ============================================================================
// [asmjit::X86CpuInfo]
// ============================================================================
struct X86CpuInfo : public CpuInfo {
ASMJIT_NO_COPY(X86CpuInfo)
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
ASMJIT_INLINE X86CpuInfo(uint32_t size = sizeof(X86CpuInfo)) :
CpuInfo(size) {}
// --------------------------------------------------------------------------
// [Accessors]
// --------------------------------------------------------------------------
//! Get processor type.
ASMJIT_INLINE uint32_t getProcessorType() const {
return _processorType;
}
//! Get brand index.
ASMJIT_INLINE uint32_t getBrandIndex() const {
return _brandIndex;
}
//! Get flush cache line size.
ASMJIT_INLINE uint32_t getFlushCacheLineSize() const {
return _flushCacheLineSize;
}
//! Get maximum logical processors count.
ASMJIT_INLINE uint32_t getMaxLogicalProcessors() const {
return _maxLogicalProcessors;
}
// --------------------------------------------------------------------------
// [Statics]
// --------------------------------------------------------------------------
#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64)
//! Get global instance of `X86CpuInfo`.
static ASMJIT_INLINE const X86CpuInfo* getHost() {
return static_cast<const X86CpuInfo*>(CpuInfo::getHost());
}
#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
//! Processor type.
uint32_t _processorType;
//! Brand index.
uint32_t _brandIndex;
//! Flush cache line size in bytes.
uint32_t _flushCacheLineSize;
//! Maximum number of addressable IDs for logical processors.
uint32_t _maxLogicalProcessors;
};
//! \}
} // asmjit namespace
// [Api-End]
#include "../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,63 @@
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Guard]
#ifndef _ASMJIT_X86_X86SCHEDULER_P_H
#define _ASMJIT_X86_X86SCHEDULER_P_H
#include "../build.h"
#if !defined(ASMJIT_DISABLE_COMPILER)
// [Dependencies - AsmJit]
#include "../x86/x86compiler.h"
#include "../x86/x86context_p.h"
#include "../x86/x86cpuinfo.h"
#include "../x86/x86inst.h"
// [Api-Begin]
#include "../apibegin.h"
namespace asmjit {
// ============================================================================
// [asmjit::X86Scheduler]
// ============================================================================
//! \internal
//!
//! X86 scheduler.
struct X86Scheduler {
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
X86Scheduler(X86Compiler* compiler, const X86CpuInfo* cpuInfo);
~X86Scheduler();
// --------------------------------------------------------------------------
// [Run]
// --------------------------------------------------------------------------
Error run(Node* start, Node* stop);
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
//! Attached compiler.
X86Compiler* _compiler;
//! CPU information used for scheduling.
const X86CpuInfo* _cpuInfo;
};
} // asmjit namespace
// [Api-End]
#include "../apiend.h"
// [Guard]
#endif // !ASMJIT_DISABLE_COMPILER
#endif // _ASMJIT_X86_X86SCHEDULER_P_H