mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-18 13:04:36 +03:00
Added possibility to annotate a code compiled by compiler so it's easier to see which variables were translated to which registers.
This commit is contained in:
@@ -78,6 +78,9 @@ If(MSVC)
|
||||
If(WIN32)
|
||||
List(APPEND ASMJIT_CFLAGS /D_UNICODE)
|
||||
EndIf()
|
||||
If(ASMJIT_STATIC)
|
||||
List(APPEND ASMJIT_CFLAGS /DASMJIT_STATIC)
|
||||
EndIf(ASMJIT_STATIC)
|
||||
EndIf()
|
||||
|
||||
# GCC.
|
||||
@@ -97,6 +100,9 @@ If(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
If(WIN32)
|
||||
List(APPEND ASMJIT_CFLAGS -D_UNICODE)
|
||||
EndIf()
|
||||
If(ASMJIT_STATIC)
|
||||
List(APPEND ASMJIT_CFLAGS -DASMJIT_STATIC)
|
||||
EndIf(ASMJIT_STATIC)
|
||||
EndIf()
|
||||
|
||||
# Dependencies - Base.
|
||||
|
||||
@@ -62,6 +62,7 @@ void BaseContext::reset() {
|
||||
_memVarTotal = 0;
|
||||
_memStackTotal = 0;
|
||||
_memAllTotal = 0;
|
||||
_annotationLength = 12;
|
||||
|
||||
_state = NULL;
|
||||
}
|
||||
@@ -327,6 +328,10 @@ Error BaseContext::compile(FuncNode* func) {
|
||||
ASMJIT_PROPAGATE_ERROR(fetch());
|
||||
ASMJIT_PROPAGATE_ERROR(removeUnreachableCode());
|
||||
ASMJIT_PROPAGATE_ERROR(analyze());
|
||||
|
||||
if (_compiler->hasLogger())
|
||||
ASMJIT_PROPAGATE_ERROR(annotate());
|
||||
|
||||
ASMJIT_PROPAGATE_ERROR(translate());
|
||||
|
||||
// We alter the compiler cursor, because it doesn't make sense to reference
|
||||
|
||||
@@ -170,6 +170,12 @@ struct BaseContext {
|
||||
//! repeats until all variables are resolved.
|
||||
virtual Error analyze() = 0;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// [Annotate]
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
virtual Error annotate() = 0;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// [Translate]
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -256,6 +262,9 @@ struct BaseContext {
|
||||
//! @brief Count of bytes used by variables and stack after alignment.
|
||||
uint32_t _memAllTotal;
|
||||
|
||||
//! @brief Default lenght of annotated instruction.
|
||||
uint32_t _annotationLength;
|
||||
|
||||
//! @brief Current state (used by register allocator).
|
||||
BaseVarState* _state;
|
||||
};
|
||||
|
||||
@@ -500,16 +500,19 @@ struct FuncBuilderX : public FuncPrototype {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ASMJIT_INLINE void setRetT()
|
||||
{ setRet(TypeId<T>::kId); }
|
||||
ASMJIT_INLINE void setRetT() {
|
||||
setRet(TypeId<T>::kId);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ASMJIT_INLINE void setArgT(uint32_t id)
|
||||
{ setArg(id, TypeId<T>::kId); }
|
||||
ASMJIT_INLINE void setArgT(uint32_t id) {
|
||||
setArg(id, TypeId<T>::kId);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ASMJIT_INLINE void addArgT()
|
||||
{ addArg(TypeId<T>::kId); }
|
||||
ASMJIT_INLINE void addArgT() {
|
||||
addArg(TypeId<T>::kId);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// [Members]
|
||||
|
||||
@@ -107,7 +107,7 @@ struct VirtualMemoryManager : public MemoryManager {
|
||||
//!
|
||||
//! This is specialized version of constructor available only for windows and
|
||||
//! usable to alloc/free memory of different process.
|
||||
ASMJIT_API VirtualMemoryManager(HANDLE hProcess);
|
||||
explicit ASMJIT_API VirtualMemoryManager(HANDLE hProcess);
|
||||
#endif // ASMJIT_OS_WINDOWS
|
||||
|
||||
//! @brief Destroy the @c VirtualMemoryManager instance, this means also to
|
||||
|
||||
@@ -543,7 +543,7 @@ static ASMJIT_INLINE size_t X86X64Assembler_relocCode(const X86X64Assembler* sel
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// [asmjit::Assembler - Logging]
|
||||
// [asmjit::x86x64::Assembler - Logging]
|
||||
// ============================================================================
|
||||
|
||||
// Logging helpers.
|
||||
@@ -578,9 +578,9 @@ static const char X86Assembler_segName[] =
|
||||
"\0\0\0\0";
|
||||
|
||||
static void X86Assembler_dumpRegister(StringBuilder& sb, uint32_t type, uint32_t index) {
|
||||
// NE == Not-Encodable.
|
||||
// -- (Not-Encodable).
|
||||
static const char reg8l[] = "al\0\0" "cl\0\0" "dl\0\0" "bl\0\0" "spl\0" "bpl\0" "sil\0" "dil\0" ;
|
||||
static const char reg8h[] = "ah\0\0" "ch\0\0" "dh\0\0" "bh\0\0" "NE\0\0" "NE\0\0" "NE\0\0" "NE\0\0";
|
||||
static const char reg8h[] = "ah\0\0" "ch\0\0" "dh\0\0" "bh\0\0" "--\0\0" "--\0\0" "--\0\0" "--\0\0";
|
||||
static const char reg16[] = "ax\0\0" "cx\0\0" "dx\0\0" "bx\0\0" "sp\0\0" "bp\0\0" "si\0\0" "di\0\0";
|
||||
|
||||
char suffix = '\0';
|
||||
@@ -606,11 +606,12 @@ static void X86Assembler_dumpRegister(StringBuilder& sb, uint32_t type, uint32_t
|
||||
case kRegTypeGpbHi:
|
||||
if (index >= 4)
|
||||
goto _EmitNE;
|
||||
|
||||
sb._appendString(®8h[index * 4]);
|
||||
return;
|
||||
|
||||
_EmitNE:
|
||||
sb._appendString("NE", 2);
|
||||
sb._appendString("--", 2);
|
||||
return;
|
||||
|
||||
case kRegTypeGpw:
|
||||
@@ -671,6 +672,7 @@ _EmitNE:
|
||||
|
||||
_EmitID:
|
||||
sb._appendUInt32(index);
|
||||
|
||||
if (suffix)
|
||||
sb._appendChar(suffix);
|
||||
}
|
||||
@@ -729,11 +731,11 @@ static void X86Assembler_dumpOperand(StringBuilder& sb, uint32_t arch, const Ope
|
||||
case kMemVSibYmm: type = kRegTypeYmm; break;
|
||||
}
|
||||
|
||||
sb._appendString(" + ", 3);
|
||||
sb._appendChar('+');
|
||||
X86Assembler_dumpRegister(sb, type, m->getIndex());
|
||||
|
||||
if (m->getShift()) {
|
||||
sb._appendString(" * ", 3);
|
||||
sb._appendChar('*');
|
||||
sb._appendChar("1248"[m->getShift() & 3]);
|
||||
}
|
||||
}
|
||||
@@ -742,13 +744,13 @@ static void X86Assembler_dumpOperand(StringBuilder& sb, uint32_t arch, const Ope
|
||||
uint32_t base = 10;
|
||||
int32_t dispOffset = m->getDisplacement();
|
||||
|
||||
const char* prefix = " + ";
|
||||
char prefix = '+';
|
||||
if (dispOffset < 0) {
|
||||
dispOffset = -dispOffset;
|
||||
prefix = " - ";
|
||||
prefix = '-';
|
||||
}
|
||||
|
||||
sb._appendString(prefix, 3);
|
||||
sb._appendChar(prefix);
|
||||
if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) {
|
||||
sb._appendString("0x", 2);
|
||||
base = 16;
|
||||
@@ -781,8 +783,9 @@ static bool X86Assembler_dumpInstruction(StringBuilder& sb,
|
||||
const Operand* o0,
|
||||
const Operand* o1,
|
||||
const Operand* o2,
|
||||
uint32_t loggerOptions)
|
||||
{
|
||||
const Operand* o3,
|
||||
uint32_t loggerOptions) {
|
||||
|
||||
if (!sb.reserve(sb.getLength() + 128))
|
||||
return false;
|
||||
|
||||
@@ -815,6 +818,11 @@ static bool X86Assembler_dumpInstruction(StringBuilder& sb,
|
||||
X86Assembler_dumpOperand(sb, arch, o2, loggerOptions);
|
||||
}
|
||||
|
||||
if (!o3->isNone()) {
|
||||
sb._appendString(", ", 3);
|
||||
X86Assembler_dumpOperand(sb, arch, o3, loggerOptions);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -867,7 +875,7 @@ static bool X86Assembler_dumpComment(StringBuilder& sb, size_t len, const uint8_
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// [asmjit::Assembler - Emit]
|
||||
// [asmjit::x86x64::Assembler - Emit]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief Encode MODR/M.
|
||||
@@ -3641,7 +3649,7 @@ _EmitDone:
|
||||
loggerOptions = self->_logger->getOptions();
|
||||
}
|
||||
|
||||
X86Assembler_dumpInstruction(sb, Arch, code, options, o0, o1, o2, loggerOptions);
|
||||
X86Assembler_dumpInstruction(sb, Arch, code, options, o0, o1, o2, o3, loggerOptions);
|
||||
|
||||
if ((loggerOptions & (1 << kLoggerOptionBinaryForm)) != 0)
|
||||
X86Assembler_dumpComment(sb, sb.getLength(), self->_cursor, (intptr_t)(cursor - self->_cursor), dispSize, self->_comment);
|
||||
|
||||
@@ -2584,7 +2584,7 @@ _NoMemory:
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// [asmjit::x86x64::X86X64Context - AnalyzeFunc]
|
||||
// [asmjit::x86x64::X86X64Context - Analyze]
|
||||
// ============================================================================
|
||||
|
||||
//! @internal
|
||||
@@ -2768,6 +2768,150 @@ _NoMemory:
|
||||
return setError(kErrorNoHeapMemory);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// [asmjit::x86x64::X86X64Context - Annotate]
|
||||
// ============================================================================
|
||||
|
||||
static void X86X64Context_annotateVariable(X86X64Context* self,
|
||||
StringBuilder& sb, const VarData* vd) {
|
||||
|
||||
const char* name = vd->getName();
|
||||
if (name != NULL && name[0] != '\0') {
|
||||
sb._appendString(name);
|
||||
}
|
||||
else {
|
||||
sb._appendChar('v');
|
||||
sb._appendUInt32(vd->getId() & kOperandIdNum);
|
||||
}
|
||||
}
|
||||
|
||||
static void X86X64Context_annotateOperand(X86X64Context* self,
|
||||
StringBuilder& sb, const Operand* op) {
|
||||
|
||||
if (op->isVar()) {
|
||||
X86X64Context_annotateVariable(self, sb, self->_compiler->getVdById(op->getId()));
|
||||
}
|
||||
else if (op->isMem()) {
|
||||
const Mem* m = static_cast<const Mem*>(op);
|
||||
bool isAbsolute = false;
|
||||
|
||||
sb._appendChar('[');
|
||||
switch (m->getMemType()) {
|
||||
case kMemTypeBaseIndex:
|
||||
case kMemTypeStackIndex:
|
||||
// [base + index << shift + displacement]
|
||||
X86X64Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getBase()));
|
||||
break;
|
||||
|
||||
case kMemTypeLabel:
|
||||
// [label + index << shift + displacement]
|
||||
sb.appendFormat("L%u", m->getBase());
|
||||
break;
|
||||
|
||||
case kMemTypeAbsolute:
|
||||
// [absolute]
|
||||
isAbsolute = true;
|
||||
sb.appendUInt(static_cast<uint32_t>(m->getDisplacement()), 16);
|
||||
break;
|
||||
}
|
||||
|
||||
if (m->hasIndex()) {
|
||||
sb._appendChar('+');
|
||||
X86X64Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getIndex()));
|
||||
|
||||
if (m->getShift()) {
|
||||
sb._appendChar('*');
|
||||
sb._appendChar("1248"[m->getShift() & 3]);
|
||||
}
|
||||
}
|
||||
|
||||
if (m->getDisplacement() && !isAbsolute) {
|
||||
uint32_t base = 10;
|
||||
int32_t dispOffset = m->getDisplacement();
|
||||
|
||||
char prefix = '+';
|
||||
if (dispOffset < 0) {
|
||||
dispOffset = -dispOffset;
|
||||
prefix = '-';
|
||||
}
|
||||
|
||||
sb._appendChar(prefix);
|
||||
/*
|
||||
if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) {
|
||||
sb._appendString("0x", 2);
|
||||
base = 16;
|
||||
}
|
||||
*/
|
||||
sb.appendUInt(static_cast<uint32_t>(dispOffset), base);
|
||||
}
|
||||
|
||||
sb._appendChar(']');
|
||||
}
|
||||
else if (op->isImm()) {
|
||||
const Imm* i = static_cast<const Imm*>(op);
|
||||
int64_t val = i->getInt64();
|
||||
|
||||
/*
|
||||
if ((loggerOptions & (1 << kLoggerOptionHexImmediate)) && static_cast<uint64_t>(val) > 9)
|
||||
sb.appendUInt(static_cast<uint64_t>(val), 16);
|
||||
else*/
|
||||
sb.appendInt(val, 10);
|
||||
}
|
||||
else if (op->isLabel()) {
|
||||
sb.appendFormat("L%u", op->getId());
|
||||
}
|
||||
else {
|
||||
sb._appendString("None", 4);
|
||||
}
|
||||
}
|
||||
|
||||
static bool X86X64Context_annotateInstruction(X86X64Context* self,
|
||||
StringBuilder& sb, uint32_t code, const Operand* opList, uint32_t opCount) {
|
||||
|
||||
if (!sb.reserve(sb.getLength() + 128))
|
||||
return false;
|
||||
|
||||
sb._appendString(_instInfo[code].getName());
|
||||
for (uint32_t i = 0; i < opCount; i++) {
|
||||
if (i == 0)
|
||||
sb._appendChar(' ');
|
||||
else
|
||||
sb._appendString(", ", 2);
|
||||
X86X64Context_annotateOperand(self, sb, &opList[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Error X86X64Context::annotate() {
|
||||
FuncNode* func = getFunc();
|
||||
|
||||
BaseNode* node_ = func;
|
||||
BaseNode* end = func->getEnd();
|
||||
|
||||
StringBuilderT<128> sb;
|
||||
Zone& sa = _compiler->_stringAllocator;
|
||||
uint32_t maxLen = 0;
|
||||
|
||||
while (node_ != end) {
|
||||
if (node_->getComment() == NULL) {
|
||||
if (node_->getType() == kNodeTypeInst) {
|
||||
InstNode* node = static_cast<InstNode*>(node_);
|
||||
X86X64Context_annotateInstruction(this, sb, node->getCode(), node->getOpList(), node->getOpCount());
|
||||
|
||||
node_->setComment(static_cast<char*>(sa.dup(sb.getData(), sb.getLength() + 1)));
|
||||
maxLen = IntUtil::iMax<uint32_t>(maxLen, static_cast<uint32_t>(sb.getLength()));
|
||||
|
||||
sb.clear();
|
||||
}
|
||||
}
|
||||
|
||||
node_ = node_->getNext();
|
||||
}
|
||||
|
||||
_annotationLength = maxLen + 1;
|
||||
return kErrorOk;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// [asmjit::x86x64::X86X64BaseAlloc]
|
||||
// ============================================================================
|
||||
@@ -4784,7 +4928,7 @@ static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64Func
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// [asmjit::x86x64::X86X64Context - TranslateJump]
|
||||
// [asmjit::x86x64::X86X64Context - Translate - Jump]
|
||||
// ============================================================================
|
||||
|
||||
//! @internal
|
||||
@@ -4820,7 +4964,7 @@ static void X86X64Context_translateJump(X86X64Context* self, JumpNode* jNode, Ta
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// [asmjit::x86x64::X86X64Context - TranslateRet]
|
||||
// [asmjit::x86x64::X86X64Context - Translate - Ret]
|
||||
// ============================================================================
|
||||
|
||||
static Error X86X64Context_translateRet(X86X64Context* self, RetNode* rNode, TargetNode* exitTarget) {
|
||||
@@ -5120,10 +5264,14 @@ static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64As
|
||||
StringBuilder& sb = self->_stringBuilder;
|
||||
|
||||
BaseLogger* logger;
|
||||
const char* comment;
|
||||
uint32_t vdCount;
|
||||
uint32_t annotationLength;
|
||||
|
||||
if (LoggingEnabled) {
|
||||
logger = assembler->getLogger();
|
||||
|
||||
vdCount = static_cast<uint32_t>(self->_contextVd.getLength());
|
||||
annotationLength = self->_annotationLength;
|
||||
}
|
||||
|
||||
// Create labels on Assembler side.
|
||||
@@ -5132,21 +5280,26 @@ static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64As
|
||||
|
||||
do {
|
||||
if (LoggingEnabled) {
|
||||
comment = node_->getComment();
|
||||
sb.clear();
|
||||
|
||||
if (node_->getComment()) {
|
||||
sb.appendString(node_->getComment());
|
||||
}
|
||||
|
||||
if (sb.getLength() < annotationLength)
|
||||
sb.appendChars(' ', annotationLength - sb.getLength());
|
||||
|
||||
size_t offset = sb.getLength();
|
||||
sb.appendChars(' ', vdCount);
|
||||
|
||||
if (node_->hasLiveness()) {
|
||||
uint32_t i;
|
||||
uint32_t vdCount = static_cast<uint32_t>(self->_contextVd.getLength());
|
||||
|
||||
VarBits* liveness = node_->getLiveness();
|
||||
VarInst* vi = static_cast<VarInst*>(node_->getVarInst());
|
||||
|
||||
sb.clear();
|
||||
sb.appendChars(' ', vdCount);
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0; i < vdCount; i++) {
|
||||
if (liveness->getBit(i))
|
||||
sb.getData()[i] = '.';
|
||||
sb.getData()[offset + i] = '.';
|
||||
}
|
||||
|
||||
if (vi != NULL) {
|
||||
@@ -5166,15 +5319,12 @@ static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64As
|
||||
if ((flags & kVarAttrUnuse))
|
||||
c -= 'a' - 'A';
|
||||
|
||||
sb.getData()[vd->getContextId()] = c;
|
||||
sb.getData()[offset + vd->getContextId()] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assembler->_comment = sb.getData();
|
||||
}
|
||||
else {
|
||||
assembler->_comment = comment;
|
||||
}
|
||||
assembler->_comment = sb.getData();
|
||||
}
|
||||
|
||||
switch (node_->getType()) {
|
||||
|
||||
@@ -443,6 +443,12 @@ struct X86X64Context : public BaseContext {
|
||||
virtual Error fetch();
|
||||
virtual Error analyze();
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// [Annotate]
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
virtual Error annotate();
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// [Translate]
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
@@ -99,7 +99,7 @@ ASMJIT_VAR const VarInfo _varInfo[];
|
||||
// [asmjit::x86x64::kRegClass]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 variable class.
|
||||
//! @brief X86/X64 variable class.
|
||||
ASMJIT_ENUM(kRegClass) {
|
||||
// kRegClassGp defined in base/defs.h; it's used by all implementations.
|
||||
|
||||
@@ -118,6 +118,7 @@ ASMJIT_ENUM(kRegClass) {
|
||||
// [asmjit::x86x64::kRegCount]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86/X64 registers count.
|
||||
ASMJIT_ENUM(kRegCount) {
|
||||
//! @brief Count of Fp registers (8).
|
||||
kRegCountFp = 8,
|
||||
@@ -131,7 +132,7 @@ ASMJIT_ENUM(kRegCount) {
|
||||
// [asmjit::x86x64::kRegType]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 register types.
|
||||
//! @brief X86/X64 register types.
|
||||
ASMJIT_ENUM(kRegType) {
|
||||
//! @brief Gpb-lo register (AL, BL, CL, DL, ...).
|
||||
kRegTypeGpbLo = 0x01,
|
||||
@@ -170,7 +171,7 @@ ASMJIT_ENUM(kRegType) {
|
||||
// [asmjit::x86x64::kRegIndex]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 register indices.
|
||||
//! @brief X86/X64 register indices.
|
||||
//!
|
||||
//! These codes are real, don't miss with @c REG enum! and don't use these
|
||||
//! values if you are not writing AsmJit code.
|
||||
@@ -313,7 +314,7 @@ ASMJIT_ENUM(kRegIndex) {
|
||||
// [asmjit::x86x64::kSeg]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 segment codes.
|
||||
//! @brief X86/X64 segment codes.
|
||||
ASMJIT_ENUM(kSeg) {
|
||||
//! @brief No segment.
|
||||
kSegDefault = 0,
|
||||
@@ -335,7 +336,7 @@ ASMJIT_ENUM(kSeg) {
|
||||
// [asmjit::x86x64::kMemVSib]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 index register legacy and AVX2 (VSIB) support.
|
||||
//! @brief X86/X64 index register legacy and AVX2 (VSIB) support.
|
||||
ASMJIT_ENUM(kMemVSib) {
|
||||
//! @brief Memory operand uses Gp or no index register.
|
||||
kMemVSibGpz = 0,
|
||||
@@ -351,7 +352,7 @@ ASMJIT_ENUM(kMemVSib) {
|
||||
|
||||
//! @internal
|
||||
//!
|
||||
//! @brief X86 specific memory flags.
|
||||
//! @brief X86/X64 specific memory flags.
|
||||
ASMJIT_ENUM(kMemFlags) {
|
||||
kMemSegBits = 0x7,
|
||||
kMemSegIndex = 0,
|
||||
@@ -374,7 +375,7 @@ ASMJIT_ENUM(kMemFlags) {
|
||||
// [asmjit::x86x64::kPrefetchHint]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 Prefetch hints.
|
||||
//! @brief X86/X64 Prefetch hints.
|
||||
ASMJIT_ENUM(kPrefetchHint) {
|
||||
//! @brief Prefetch using NT hint.
|
||||
kPrefetchNta = 0,
|
||||
@@ -390,7 +391,7 @@ ASMJIT_ENUM(kPrefetchHint) {
|
||||
// [asmjit::x86x64::kFPSW]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 FPU status Word.
|
||||
//! @brief X86/X64 FPU status Word.
|
||||
ASMJIT_ENUM(kFPSW) {
|
||||
kFPSW_Invalid = 0x0001,
|
||||
kFPSW_Denormalized = 0x0002,
|
||||
@@ -412,7 +413,7 @@ ASMJIT_ENUM(kFPSW) {
|
||||
// [asmjit::x86x64::kFPCW]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 FPU control Word.
|
||||
//! @brief X86/X64 FPU control Word.
|
||||
ASMJIT_ENUM(kFPCW) {
|
||||
kFPCW_EM_Mask = 0x003F, // Bits 0-5.
|
||||
kFPCW_EM_Invalid = 0x0001,
|
||||
@@ -443,7 +444,7 @@ ASMJIT_ENUM(kFPCW) {
|
||||
// [asmjit::x86x64::kInstCode]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 instruction codes.
|
||||
//! @brief X86/X64 instruction codes.
|
||||
//!
|
||||
//! Note that these instruction codes are AsmJit specific. Each instruction has
|
||||
//! a unique ID that is used as an index to AsmJit instruction table.
|
||||
@@ -1415,7 +1416,7 @@ ASMJIT_ENUM(kInstCode) {
|
||||
// [asmjit::x86x64::kInstOptions]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief Instruction emit options, mainly for internal purposes.
|
||||
//! @brief X86/X64 instruction emit options, mainly for internal purposes.
|
||||
ASMJIT_ENUM(kInstOptions) {
|
||||
//! @brief Emit instruction with LOCK prefix.
|
||||
//!
|
||||
@@ -1443,7 +1444,7 @@ ASMJIT_ENUM(kInstOptions) {
|
||||
// [asmjit::x86x64::kInstGroup]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 instruction groups.
|
||||
//! @brief X86/X64 instruction groups.
|
||||
//!
|
||||
//! This should be only used by assembler, because it's @c asmjit::Assembler
|
||||
//! specific grouping. Each group represents one 'case' in the Assembler's
|
||||
@@ -1676,7 +1677,7 @@ ASMJIT_ENUM(kInstOpCode) {
|
||||
// [asmjit::x86x64::kInstFlags]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 instruction type flags.
|
||||
//! @brief X86/X64 instruction type flags.
|
||||
ASMJIT_ENUM(kInstFlags) {
|
||||
//! @brief No flags.
|
||||
kInstFlagNone = 0x0000,
|
||||
@@ -1748,7 +1749,7 @@ ASMJIT_ENUM(kInstFlags) {
|
||||
// [asmjit::x86x64::kInstOp]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 instruction operand flags.
|
||||
//! @brief X86/X64 instruction operand flags.
|
||||
ASMJIT_ENUM(kInstOp) {
|
||||
// Gp, Fp, Mm, Xmm, Ymm, Zmm.
|
||||
kInstOpGb = 0x0001,
|
||||
@@ -1796,29 +1797,29 @@ ASMJIT_ENUM(kInstOp) {
|
||||
// [asmjit::x86x64::kCond]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 Condition codes.
|
||||
//! @brief X86/X64 Condition codes.
|
||||
ASMJIT_ENUM(kCond) {
|
||||
// Condition codes from processor manuals.
|
||||
kCondA = 0x07, // CF==0 & ZF==0
|
||||
kCondAE = 0x03, // CF==0
|
||||
kCondB = 0x02, // CF==1
|
||||
kCondBE = 0x06, // CF==1 | ZF==1
|
||||
kCondA = 0x07, // CF==0 & ZF==0 (unsigned)
|
||||
kCondAE = 0x03, // CF==0 (unsigned)
|
||||
kCondB = 0x02, // CF==1 (unsigned)
|
||||
kCondBE = 0x06, // CF==1 | ZF==1 (unsigned)
|
||||
kCondC = 0x02, // CF==1
|
||||
kCondE = 0x04, // ZF==1
|
||||
kCondG = 0x0F, // ZF==0 & SF==OF
|
||||
kCondGE = 0x0D, // SF==OF
|
||||
kCondL = 0x0C, // SF!=OF
|
||||
kCondLE = 0x0E, // ZF==1 | SF!=OF
|
||||
kCondNA = 0x06, // CF==1 | ZF==1
|
||||
kCondNAE = 0x02, // CF==1
|
||||
kCondNB = 0x03, // CF==0
|
||||
kCondNBE = 0x07, // CF==0 & ZF==0
|
||||
kCondE = 0x04, // ZF==1 (signed/unsigned)
|
||||
kCondG = 0x0F, // ZF==0 & SF==OF (signed)
|
||||
kCondGE = 0x0D, // SF==OF (signed)
|
||||
kCondL = 0x0C, // SF!=OF (signed)
|
||||
kCondLE = 0x0E, // ZF==1 | SF!=OF (signed)
|
||||
kCondNA = 0x06, // CF==1 | ZF==1 (unsigned)
|
||||
kCondNAE = 0x02, // CF==1 (unsigned)
|
||||
kCondNB = 0x03, // CF==0 (unsigned)
|
||||
kCondNBE = 0x07, // CF==0 & ZF==0 (unsigned)
|
||||
kCondNC = 0x03, // CF==0
|
||||
kCondNE = 0x05, // ZF==0
|
||||
kCondNG = 0x0E, // ZF==1 | SF!=OF
|
||||
kCondNGE = 0x0C, // SF!=OF
|
||||
kCondNL = 0x0D, // SF==OF
|
||||
kCondNLE = 0x0F, // ZF==0 & SF==OF
|
||||
kCondNE = 0x05, // ZF==0 (signed/unsigned)
|
||||
kCondNG = 0x0E, // ZF==1 | SF!=OF (signed)
|
||||
kCondNGE = 0x0C, // SF!=OF (signed)
|
||||
kCondNL = 0x0D, // SF==OF (signed)
|
||||
kCondNLE = 0x0F, // ZF==0 & SF==OF (signed)
|
||||
kCondNO = 0x01, // OF==0
|
||||
kCondNP = 0x0B, // PF==0
|
||||
kCondNS = 0x09, // SF==0
|
||||
@@ -1866,7 +1867,7 @@ ASMJIT_ENUM(kCond) {
|
||||
// [asmjit::x86x64::kVarType]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 variable type.
|
||||
//! @brief X86/X64 variable type.
|
||||
ASMJIT_ENUM(kVarType) {
|
||||
//! @brief Variable is Mm (MMX).
|
||||
kVarTypeMm = 12,
|
||||
@@ -1912,7 +1913,7 @@ ASMJIT_ENUM(kVarType) {
|
||||
// [asmjit::x86x64::kVarDesc]
|
||||
// ============================================================================
|
||||
|
||||
//! @brief X86 variable description.
|
||||
//! @brief X86/X64 variable description.
|
||||
ASMJIT_ENUM(kVarDesc) {
|
||||
//! @brief Variable contains single-precision floating-point(s).
|
||||
kVarDescSp = 0x10,
|
||||
|
||||
Reference in New Issue
Block a user