mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-18 21:14:35 +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)
|
If(WIN32)
|
||||||
List(APPEND ASMJIT_CFLAGS /D_UNICODE)
|
List(APPEND ASMJIT_CFLAGS /D_UNICODE)
|
||||||
EndIf()
|
EndIf()
|
||||||
|
If(ASMJIT_STATIC)
|
||||||
|
List(APPEND ASMJIT_CFLAGS /DASMJIT_STATIC)
|
||||||
|
EndIf(ASMJIT_STATIC)
|
||||||
EndIf()
|
EndIf()
|
||||||
|
|
||||||
# GCC.
|
# GCC.
|
||||||
@@ -97,6 +100,9 @@ If(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
|||||||
If(WIN32)
|
If(WIN32)
|
||||||
List(APPEND ASMJIT_CFLAGS -D_UNICODE)
|
List(APPEND ASMJIT_CFLAGS -D_UNICODE)
|
||||||
EndIf()
|
EndIf()
|
||||||
|
If(ASMJIT_STATIC)
|
||||||
|
List(APPEND ASMJIT_CFLAGS -DASMJIT_STATIC)
|
||||||
|
EndIf(ASMJIT_STATIC)
|
||||||
EndIf()
|
EndIf()
|
||||||
|
|
||||||
# Dependencies - Base.
|
# Dependencies - Base.
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ void BaseContext::reset() {
|
|||||||
_memVarTotal = 0;
|
_memVarTotal = 0;
|
||||||
_memStackTotal = 0;
|
_memStackTotal = 0;
|
||||||
_memAllTotal = 0;
|
_memAllTotal = 0;
|
||||||
|
_annotationLength = 12;
|
||||||
|
|
||||||
_state = NULL;
|
_state = NULL;
|
||||||
}
|
}
|
||||||
@@ -327,6 +328,10 @@ Error BaseContext::compile(FuncNode* func) {
|
|||||||
ASMJIT_PROPAGATE_ERROR(fetch());
|
ASMJIT_PROPAGATE_ERROR(fetch());
|
||||||
ASMJIT_PROPAGATE_ERROR(removeUnreachableCode());
|
ASMJIT_PROPAGATE_ERROR(removeUnreachableCode());
|
||||||
ASMJIT_PROPAGATE_ERROR(analyze());
|
ASMJIT_PROPAGATE_ERROR(analyze());
|
||||||
|
|
||||||
|
if (_compiler->hasLogger())
|
||||||
|
ASMJIT_PROPAGATE_ERROR(annotate());
|
||||||
|
|
||||||
ASMJIT_PROPAGATE_ERROR(translate());
|
ASMJIT_PROPAGATE_ERROR(translate());
|
||||||
|
|
||||||
// We alter the compiler cursor, because it doesn't make sense to reference
|
// 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.
|
//! repeats until all variables are resolved.
|
||||||
virtual Error analyze() = 0;
|
virtual Error analyze() = 0;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Annotate]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
virtual Error annotate() = 0;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Translate]
|
// [Translate]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@@ -256,6 +262,9 @@ struct BaseContext {
|
|||||||
//! @brief Count of bytes used by variables and stack after alignment.
|
//! @brief Count of bytes used by variables and stack after alignment.
|
||||||
uint32_t _memAllTotal;
|
uint32_t _memAllTotal;
|
||||||
|
|
||||||
|
//! @brief Default lenght of annotated instruction.
|
||||||
|
uint32_t _annotationLength;
|
||||||
|
|
||||||
//! @brief Current state (used by register allocator).
|
//! @brief Current state (used by register allocator).
|
||||||
BaseVarState* _state;
|
BaseVarState* _state;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -500,16 +500,19 @@ struct FuncBuilderX : public FuncPrototype {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ASMJIT_INLINE void setRetT()
|
ASMJIT_INLINE void setRetT() {
|
||||||
{ setRet(TypeId<T>::kId); }
|
setRet(TypeId<T>::kId);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ASMJIT_INLINE void setArgT(uint32_t id)
|
ASMJIT_INLINE void setArgT(uint32_t id) {
|
||||||
{ setArg(id, TypeId<T>::kId); }
|
setArg(id, TypeId<T>::kId);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ASMJIT_INLINE void addArgT()
|
ASMJIT_INLINE void addArgT() {
|
||||||
{ addArg(TypeId<T>::kId); }
|
addArg(TypeId<T>::kId);
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Members]
|
// [Members]
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ struct VirtualMemoryManager : public MemoryManager {
|
|||||||
//!
|
//!
|
||||||
//! 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.
|
||||||
ASMJIT_API VirtualMemoryManager(HANDLE hProcess);
|
explicit ASMJIT_API VirtualMemoryManager(HANDLE hProcess);
|
||||||
#endif // ASMJIT_OS_WINDOWS
|
#endif // ASMJIT_OS_WINDOWS
|
||||||
|
|
||||||
//! @brief Destroy the @c VirtualMemoryManager instance, this means also to
|
//! @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.
|
// Logging helpers.
|
||||||
@@ -578,9 +578,9 @@ static const char X86Assembler_segName[] =
|
|||||||
"\0\0\0\0";
|
"\0\0\0\0";
|
||||||
|
|
||||||
static void X86Assembler_dumpRegister(StringBuilder& sb, uint32_t type, uint32_t index) {
|
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 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";
|
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';
|
char suffix = '\0';
|
||||||
@@ -606,11 +606,12 @@ static void X86Assembler_dumpRegister(StringBuilder& sb, uint32_t type, uint32_t
|
|||||||
case kRegTypeGpbHi:
|
case kRegTypeGpbHi:
|
||||||
if (index >= 4)
|
if (index >= 4)
|
||||||
goto _EmitNE;
|
goto _EmitNE;
|
||||||
|
|
||||||
sb._appendString(®8h[index * 4]);
|
sb._appendString(®8h[index * 4]);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_EmitNE:
|
_EmitNE:
|
||||||
sb._appendString("NE", 2);
|
sb._appendString("--", 2);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case kRegTypeGpw:
|
case kRegTypeGpw:
|
||||||
@@ -671,6 +672,7 @@ _EmitNE:
|
|||||||
|
|
||||||
_EmitID:
|
_EmitID:
|
||||||
sb._appendUInt32(index);
|
sb._appendUInt32(index);
|
||||||
|
|
||||||
if (suffix)
|
if (suffix)
|
||||||
sb._appendChar(suffix);
|
sb._appendChar(suffix);
|
||||||
}
|
}
|
||||||
@@ -729,11 +731,11 @@ static void X86Assembler_dumpOperand(StringBuilder& sb, uint32_t arch, const Ope
|
|||||||
case kMemVSibYmm: type = kRegTypeYmm; break;
|
case kMemVSibYmm: type = kRegTypeYmm; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sb._appendString(" + ", 3);
|
sb._appendChar('+');
|
||||||
X86Assembler_dumpRegister(sb, type, m->getIndex());
|
X86Assembler_dumpRegister(sb, type, m->getIndex());
|
||||||
|
|
||||||
if (m->getShift()) {
|
if (m->getShift()) {
|
||||||
sb._appendString(" * ", 3);
|
sb._appendChar('*');
|
||||||
sb._appendChar("1248"[m->getShift() & 3]);
|
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;
|
uint32_t base = 10;
|
||||||
int32_t dispOffset = m->getDisplacement();
|
int32_t dispOffset = m->getDisplacement();
|
||||||
|
|
||||||
const char* prefix = " + ";
|
char prefix = '+';
|
||||||
if (dispOffset < 0) {
|
if (dispOffset < 0) {
|
||||||
dispOffset = -dispOffset;
|
dispOffset = -dispOffset;
|
||||||
prefix = " - ";
|
prefix = '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
sb._appendString(prefix, 3);
|
sb._appendChar(prefix);
|
||||||
if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) {
|
if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) {
|
||||||
sb._appendString("0x", 2);
|
sb._appendString("0x", 2);
|
||||||
base = 16;
|
base = 16;
|
||||||
@@ -781,8 +783,9 @@ static bool X86Assembler_dumpInstruction(StringBuilder& sb,
|
|||||||
const Operand* o0,
|
const Operand* o0,
|
||||||
const Operand* o1,
|
const Operand* o1,
|
||||||
const Operand* o2,
|
const Operand* o2,
|
||||||
uint32_t loggerOptions)
|
const Operand* o3,
|
||||||
{
|
uint32_t loggerOptions) {
|
||||||
|
|
||||||
if (!sb.reserve(sb.getLength() + 128))
|
if (!sb.reserve(sb.getLength() + 128))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -815,6 +818,11 @@ static bool X86Assembler_dumpInstruction(StringBuilder& sb,
|
|||||||
X86Assembler_dumpOperand(sb, arch, o2, loggerOptions);
|
X86Assembler_dumpOperand(sb, arch, o2, loggerOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!o3->isNone()) {
|
||||||
|
sb._appendString(", ", 3);
|
||||||
|
X86Assembler_dumpOperand(sb, arch, o3, loggerOptions);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
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.
|
//! @brief Encode MODR/M.
|
||||||
@@ -3641,7 +3649,7 @@ _EmitDone:
|
|||||||
loggerOptions = self->_logger->getOptions();
|
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)
|
if ((loggerOptions & (1 << kLoggerOptionBinaryForm)) != 0)
|
||||||
X86Assembler_dumpComment(sb, sb.getLength(), self->_cursor, (intptr_t)(cursor - self->_cursor), dispSize, self->_comment);
|
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
|
//! @internal
|
||||||
@@ -2768,6 +2768,150 @@ _NoMemory:
|
|||||||
return setError(kErrorNoHeapMemory);
|
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]
|
// [asmjit::x86x64::X86X64BaseAlloc]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -4784,7 +4928,7 @@ static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64Func
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [asmjit::x86x64::X86X64Context - TranslateJump]
|
// [asmjit::x86x64::X86X64Context - Translate - Jump]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @internal
|
//! @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) {
|
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;
|
StringBuilder& sb = self->_stringBuilder;
|
||||||
|
|
||||||
BaseLogger* logger;
|
BaseLogger* logger;
|
||||||
const char* comment;
|
uint32_t vdCount;
|
||||||
|
uint32_t annotationLength;
|
||||||
|
|
||||||
if (LoggingEnabled) {
|
if (LoggingEnabled) {
|
||||||
logger = assembler->getLogger();
|
logger = assembler->getLogger();
|
||||||
|
|
||||||
|
vdCount = static_cast<uint32_t>(self->_contextVd.getLength());
|
||||||
|
annotationLength = self->_annotationLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create labels on Assembler side.
|
// Create labels on Assembler side.
|
||||||
@@ -5132,21 +5280,26 @@ static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64As
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
if (LoggingEnabled) {
|
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()) {
|
if (node_->hasLiveness()) {
|
||||||
uint32_t i;
|
|
||||||
uint32_t vdCount = static_cast<uint32_t>(self->_contextVd.getLength());
|
|
||||||
|
|
||||||
VarBits* liveness = node_->getLiveness();
|
VarBits* liveness = node_->getLiveness();
|
||||||
VarInst* vi = static_cast<VarInst*>(node_->getVarInst());
|
VarInst* vi = static_cast<VarInst*>(node_->getVarInst());
|
||||||
|
|
||||||
sb.clear();
|
uint32_t i;
|
||||||
sb.appendChars(' ', vdCount);
|
|
||||||
|
|
||||||
for (i = 0; i < vdCount; i++) {
|
for (i = 0; i < vdCount; i++) {
|
||||||
if (liveness->getBit(i))
|
if (liveness->getBit(i))
|
||||||
sb.getData()[i] = '.';
|
sb.getData()[offset + i] = '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vi != NULL) {
|
if (vi != NULL) {
|
||||||
@@ -5166,16 +5319,13 @@ static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64As
|
|||||||
if ((flags & kVarAttrUnuse))
|
if ((flags & kVarAttrUnuse))
|
||||||
c -= 'a' - 'A';
|
c -= 'a' - 'A';
|
||||||
|
|
||||||
sb.getData()[vd->getContextId()] = c;
|
sb.getData()[offset + vd->getContextId()] = c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assembler->_comment = sb.getData();
|
assembler->_comment = sb.getData();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
assembler->_comment = comment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (node_->getType()) {
|
switch (node_->getType()) {
|
||||||
case kNodeTypeAlign: {
|
case kNodeTypeAlign: {
|
||||||
|
|||||||
@@ -443,6 +443,12 @@ struct X86X64Context : public BaseContext {
|
|||||||
virtual Error fetch();
|
virtual Error fetch();
|
||||||
virtual Error analyze();
|
virtual Error analyze();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// [Annotate]
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
virtual Error annotate();
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [Translate]
|
// [Translate]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ ASMJIT_VAR const VarInfo _varInfo[];
|
|||||||
// [asmjit::x86x64::kRegClass]
|
// [asmjit::x86x64::kRegClass]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief X86 variable class.
|
//! @brief X86/X64 variable class.
|
||||||
ASMJIT_ENUM(kRegClass) {
|
ASMJIT_ENUM(kRegClass) {
|
||||||
// kRegClassGp defined in base/defs.h; it's used by all implementations.
|
// kRegClassGp defined in base/defs.h; it's used by all implementations.
|
||||||
|
|
||||||
@@ -118,6 +118,7 @@ ASMJIT_ENUM(kRegClass) {
|
|||||||
// [asmjit::x86x64::kRegCount]
|
// [asmjit::x86x64::kRegCount]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
|
//! @brief X86/X64 registers count.
|
||||||
ASMJIT_ENUM(kRegCount) {
|
ASMJIT_ENUM(kRegCount) {
|
||||||
//! @brief Count of Fp registers (8).
|
//! @brief Count of Fp registers (8).
|
||||||
kRegCountFp = 8,
|
kRegCountFp = 8,
|
||||||
@@ -131,7 +132,7 @@ ASMJIT_ENUM(kRegCount) {
|
|||||||
// [asmjit::x86x64::kRegType]
|
// [asmjit::x86x64::kRegType]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief X86 register types.
|
//! @brief X86/X64 register types.
|
||||||
ASMJIT_ENUM(kRegType) {
|
ASMJIT_ENUM(kRegType) {
|
||||||
//! @brief Gpb-lo register (AL, BL, CL, DL, ...).
|
//! @brief Gpb-lo register (AL, BL, CL, DL, ...).
|
||||||
kRegTypeGpbLo = 0x01,
|
kRegTypeGpbLo = 0x01,
|
||||||
@@ -170,7 +171,7 @@ ASMJIT_ENUM(kRegType) {
|
|||||||
// [asmjit::x86x64::kRegIndex]
|
// [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
|
//! These codes are real, don't miss with @c REG enum! and don't use these
|
||||||
//! values if you are not writing AsmJit code.
|
//! values if you are not writing AsmJit code.
|
||||||
@@ -313,7 +314,7 @@ ASMJIT_ENUM(kRegIndex) {
|
|||||||
// [asmjit::x86x64::kSeg]
|
// [asmjit::x86x64::kSeg]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief X86 segment codes.
|
//! @brief X86/X64 segment codes.
|
||||||
ASMJIT_ENUM(kSeg) {
|
ASMJIT_ENUM(kSeg) {
|
||||||
//! @brief No segment.
|
//! @brief No segment.
|
||||||
kSegDefault = 0,
|
kSegDefault = 0,
|
||||||
@@ -335,7 +336,7 @@ ASMJIT_ENUM(kSeg) {
|
|||||||
// [asmjit::x86x64::kMemVSib]
|
// [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) {
|
ASMJIT_ENUM(kMemVSib) {
|
||||||
//! @brief Memory operand uses Gp or no index register.
|
//! @brief Memory operand uses Gp or no index register.
|
||||||
kMemVSibGpz = 0,
|
kMemVSibGpz = 0,
|
||||||
@@ -351,7 +352,7 @@ ASMJIT_ENUM(kMemVSib) {
|
|||||||
|
|
||||||
//! @internal
|
//! @internal
|
||||||
//!
|
//!
|
||||||
//! @brief X86 specific memory flags.
|
//! @brief X86/X64 specific memory flags.
|
||||||
ASMJIT_ENUM(kMemFlags) {
|
ASMJIT_ENUM(kMemFlags) {
|
||||||
kMemSegBits = 0x7,
|
kMemSegBits = 0x7,
|
||||||
kMemSegIndex = 0,
|
kMemSegIndex = 0,
|
||||||
@@ -374,7 +375,7 @@ ASMJIT_ENUM(kMemFlags) {
|
|||||||
// [asmjit::x86x64::kPrefetchHint]
|
// [asmjit::x86x64::kPrefetchHint]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief X86 Prefetch hints.
|
//! @brief X86/X64 Prefetch hints.
|
||||||
ASMJIT_ENUM(kPrefetchHint) {
|
ASMJIT_ENUM(kPrefetchHint) {
|
||||||
//! @brief Prefetch using NT hint.
|
//! @brief Prefetch using NT hint.
|
||||||
kPrefetchNta = 0,
|
kPrefetchNta = 0,
|
||||||
@@ -390,7 +391,7 @@ ASMJIT_ENUM(kPrefetchHint) {
|
|||||||
// [asmjit::x86x64::kFPSW]
|
// [asmjit::x86x64::kFPSW]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief X86 FPU status Word.
|
//! @brief X86/X64 FPU status Word.
|
||||||
ASMJIT_ENUM(kFPSW) {
|
ASMJIT_ENUM(kFPSW) {
|
||||||
kFPSW_Invalid = 0x0001,
|
kFPSW_Invalid = 0x0001,
|
||||||
kFPSW_Denormalized = 0x0002,
|
kFPSW_Denormalized = 0x0002,
|
||||||
@@ -412,7 +413,7 @@ ASMJIT_ENUM(kFPSW) {
|
|||||||
// [asmjit::x86x64::kFPCW]
|
// [asmjit::x86x64::kFPCW]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief X86 FPU control Word.
|
//! @brief X86/X64 FPU control Word.
|
||||||
ASMJIT_ENUM(kFPCW) {
|
ASMJIT_ENUM(kFPCW) {
|
||||||
kFPCW_EM_Mask = 0x003F, // Bits 0-5.
|
kFPCW_EM_Mask = 0x003F, // Bits 0-5.
|
||||||
kFPCW_EM_Invalid = 0x0001,
|
kFPCW_EM_Invalid = 0x0001,
|
||||||
@@ -443,7 +444,7 @@ ASMJIT_ENUM(kFPCW) {
|
|||||||
// [asmjit::x86x64::kInstCode]
|
// [asmjit::x86x64::kInstCode]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief X86 instruction codes.
|
//! @brief X86/X64 instruction codes.
|
||||||
//!
|
//!
|
||||||
//! Note that these instruction codes are AsmJit specific. Each instruction has
|
//! Note that these instruction codes are AsmJit specific. Each instruction has
|
||||||
//! a unique ID that is used as an index to AsmJit instruction table.
|
//! a unique ID that is used as an index to AsmJit instruction table.
|
||||||
@@ -1415,7 +1416,7 @@ ASMJIT_ENUM(kInstCode) {
|
|||||||
// [asmjit::x86x64::kInstOptions]
|
// [asmjit::x86x64::kInstOptions]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief Instruction emit options, mainly for internal purposes.
|
//! @brief X86/X64 instruction emit options, mainly for internal purposes.
|
||||||
ASMJIT_ENUM(kInstOptions) {
|
ASMJIT_ENUM(kInstOptions) {
|
||||||
//! @brief Emit instruction with LOCK prefix.
|
//! @brief Emit instruction with LOCK prefix.
|
||||||
//!
|
//!
|
||||||
@@ -1443,7 +1444,7 @@ ASMJIT_ENUM(kInstOptions) {
|
|||||||
// [asmjit::x86x64::kInstGroup]
|
// [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
|
//! This should be only used by assembler, because it's @c asmjit::Assembler
|
||||||
//! specific grouping. Each group represents one 'case' in the Assembler's
|
//! specific grouping. Each group represents one 'case' in the Assembler's
|
||||||
@@ -1676,7 +1677,7 @@ ASMJIT_ENUM(kInstOpCode) {
|
|||||||
// [asmjit::x86x64::kInstFlags]
|
// [asmjit::x86x64::kInstFlags]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief X86 instruction type flags.
|
//! @brief X86/X64 instruction type flags.
|
||||||
ASMJIT_ENUM(kInstFlags) {
|
ASMJIT_ENUM(kInstFlags) {
|
||||||
//! @brief No flags.
|
//! @brief No flags.
|
||||||
kInstFlagNone = 0x0000,
|
kInstFlagNone = 0x0000,
|
||||||
@@ -1748,7 +1749,7 @@ ASMJIT_ENUM(kInstFlags) {
|
|||||||
// [asmjit::x86x64::kInstOp]
|
// [asmjit::x86x64::kInstOp]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief X86 instruction operand flags.
|
//! @brief X86/X64 instruction operand flags.
|
||||||
ASMJIT_ENUM(kInstOp) {
|
ASMJIT_ENUM(kInstOp) {
|
||||||
// Gp, Fp, Mm, Xmm, Ymm, Zmm.
|
// Gp, Fp, Mm, Xmm, Ymm, Zmm.
|
||||||
kInstOpGb = 0x0001,
|
kInstOpGb = 0x0001,
|
||||||
@@ -1796,29 +1797,29 @@ ASMJIT_ENUM(kInstOp) {
|
|||||||
// [asmjit::x86x64::kCond]
|
// [asmjit::x86x64::kCond]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief X86 Condition codes.
|
//! @brief X86/X64 Condition codes.
|
||||||
ASMJIT_ENUM(kCond) {
|
ASMJIT_ENUM(kCond) {
|
||||||
// Condition codes from processor manuals.
|
// Condition codes from processor manuals.
|
||||||
kCondA = 0x07, // CF==0 & ZF==0
|
kCondA = 0x07, // CF==0 & ZF==0 (unsigned)
|
||||||
kCondAE = 0x03, // CF==0
|
kCondAE = 0x03, // CF==0 (unsigned)
|
||||||
kCondB = 0x02, // CF==1
|
kCondB = 0x02, // CF==1 (unsigned)
|
||||||
kCondBE = 0x06, // CF==1 | ZF==1
|
kCondBE = 0x06, // CF==1 | ZF==1 (unsigned)
|
||||||
kCondC = 0x02, // CF==1
|
kCondC = 0x02, // CF==1
|
||||||
kCondE = 0x04, // ZF==1
|
kCondE = 0x04, // ZF==1 (signed/unsigned)
|
||||||
kCondG = 0x0F, // ZF==0 & SF==OF
|
kCondG = 0x0F, // ZF==0 & SF==OF (signed)
|
||||||
kCondGE = 0x0D, // SF==OF
|
kCondGE = 0x0D, // SF==OF (signed)
|
||||||
kCondL = 0x0C, // SF!=OF
|
kCondL = 0x0C, // SF!=OF (signed)
|
||||||
kCondLE = 0x0E, // ZF==1 | SF!=OF
|
kCondLE = 0x0E, // ZF==1 | SF!=OF (signed)
|
||||||
kCondNA = 0x06, // CF==1 | ZF==1
|
kCondNA = 0x06, // CF==1 | ZF==1 (unsigned)
|
||||||
kCondNAE = 0x02, // CF==1
|
kCondNAE = 0x02, // CF==1 (unsigned)
|
||||||
kCondNB = 0x03, // CF==0
|
kCondNB = 0x03, // CF==0 (unsigned)
|
||||||
kCondNBE = 0x07, // CF==0 & ZF==0
|
kCondNBE = 0x07, // CF==0 & ZF==0 (unsigned)
|
||||||
kCondNC = 0x03, // CF==0
|
kCondNC = 0x03, // CF==0
|
||||||
kCondNE = 0x05, // ZF==0
|
kCondNE = 0x05, // ZF==0 (signed/unsigned)
|
||||||
kCondNG = 0x0E, // ZF==1 | SF!=OF
|
kCondNG = 0x0E, // ZF==1 | SF!=OF (signed)
|
||||||
kCondNGE = 0x0C, // SF!=OF
|
kCondNGE = 0x0C, // SF!=OF (signed)
|
||||||
kCondNL = 0x0D, // SF==OF
|
kCondNL = 0x0D, // SF==OF (signed)
|
||||||
kCondNLE = 0x0F, // ZF==0 & SF==OF
|
kCondNLE = 0x0F, // ZF==0 & SF==OF (signed)
|
||||||
kCondNO = 0x01, // OF==0
|
kCondNO = 0x01, // OF==0
|
||||||
kCondNP = 0x0B, // PF==0
|
kCondNP = 0x0B, // PF==0
|
||||||
kCondNS = 0x09, // SF==0
|
kCondNS = 0x09, // SF==0
|
||||||
@@ -1866,7 +1867,7 @@ ASMJIT_ENUM(kCond) {
|
|||||||
// [asmjit::x86x64::kVarType]
|
// [asmjit::x86x64::kVarType]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief X86 variable type.
|
//! @brief X86/X64 variable type.
|
||||||
ASMJIT_ENUM(kVarType) {
|
ASMJIT_ENUM(kVarType) {
|
||||||
//! @brief Variable is Mm (MMX).
|
//! @brief Variable is Mm (MMX).
|
||||||
kVarTypeMm = 12,
|
kVarTypeMm = 12,
|
||||||
@@ -1912,7 +1913,7 @@ ASMJIT_ENUM(kVarType) {
|
|||||||
// [asmjit::x86x64::kVarDesc]
|
// [asmjit::x86x64::kVarDesc]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
//! @brief X86 variable description.
|
//! @brief X86/X64 variable description.
|
||||||
ASMJIT_ENUM(kVarDesc) {
|
ASMJIT_ENUM(kVarDesc) {
|
||||||
//! @brief Variable contains single-precision floating-point(s).
|
//! @brief Variable contains single-precision floating-point(s).
|
||||||
kVarDescSp = 0x10,
|
kVarDescSp = 0x10,
|
||||||
|
|||||||
Reference in New Issue
Block a user