mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-18 21:14:35 +03:00
Minor improvements of CodeCompiler
This commit is contained in:
@@ -116,9 +116,11 @@ CCFunc* CodeCompiler::newFunc(const FuncSignature& sign) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create helper nodes.
|
// Create helper nodes.
|
||||||
func->_end = newNodeT<CBSentinel>();
|
|
||||||
func->_exitNode = newLabelNode();
|
func->_exitNode = newLabelNode();
|
||||||
if (!func->_exitNode || !func->_end) goto _NoMemory;
|
func->_end = newNodeT<CBSentinel>();
|
||||||
|
|
||||||
|
if (!func->_exitNode || !func->_end)
|
||||||
|
goto _NoMemory;
|
||||||
|
|
||||||
// Function prototype.
|
// Function prototype.
|
||||||
err = func->getDetail().init(sign);
|
err = func->getDetail().init(sign);
|
||||||
@@ -179,9 +181,8 @@ CBSentinel* CodeCompiler::endFunc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the local constant pool at the end of the function (if exists).
|
// Add the local constant pool at the end of the function (if exists).
|
||||||
setCursor(func->getExitNode());
|
|
||||||
|
|
||||||
if (_localConstPool) {
|
if (_localConstPool) {
|
||||||
|
setCursor(func->getEnd()->getPrev());
|
||||||
addNode(_localConstPool);
|
addNode(_localConstPool);
|
||||||
_localConstPool = nullptr;
|
_localConstPool = nullptr;
|
||||||
}
|
}
|
||||||
@@ -190,8 +191,9 @@ CBSentinel* CodeCompiler::endFunc() {
|
|||||||
func->_isFinished = true;
|
func->_isFinished = true;
|
||||||
_func = nullptr;
|
_func = nullptr;
|
||||||
|
|
||||||
setCursor(func->getEnd());
|
CBSentinel* end = func->getEnd();
|
||||||
return func->getEnd();
|
setCursor(end);
|
||||||
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ public:
|
|||||||
//! Get function exit label.
|
//! Get function exit label.
|
||||||
ASMJIT_INLINE Label getExitLabel() const noexcept { return _exitNode->getLabel(); }
|
ASMJIT_INLINE Label getExitLabel() const noexcept { return _exitNode->getLabel(); }
|
||||||
|
|
||||||
//! Get the function end sentinel.
|
//! Get "End of Func" sentinel.
|
||||||
ASMJIT_INLINE CBSentinel* getEnd() const noexcept { return _end; }
|
ASMJIT_INLINE CBSentinel* getEnd() const noexcept { return _end; }
|
||||||
|
|
||||||
//! Get function declaration.
|
//! Get function declaration.
|
||||||
|
|||||||
@@ -100,7 +100,6 @@ Error RAPass::prepare(CCFunc* func) noexcept {
|
|||||||
|
|
||||||
_func = func;
|
_func = func;
|
||||||
_stop = end->getNext();
|
_stop = end->getNext();
|
||||||
_extraBlock = end;
|
|
||||||
|
|
||||||
_unreachableList.reset();
|
_unreachableList.reset();
|
||||||
_returningList.reset();
|
_returningList.reset();
|
||||||
@@ -139,7 +138,6 @@ void RAPass::cleanup() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_contextVd.reset();
|
_contextVd.reset();
|
||||||
_extraBlock = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
@@ -360,11 +360,6 @@ public:
|
|||||||
//! Get stop node.
|
//! Get stop node.
|
||||||
ASMJIT_INLINE CBNode* getStop() const noexcept { return _stop; }
|
ASMJIT_INLINE CBNode* getStop() const noexcept { return _stop; }
|
||||||
|
|
||||||
//! Get extra block.
|
|
||||||
ASMJIT_INLINE CBNode* getExtraBlock() const noexcept { return _extraBlock; }
|
|
||||||
//! Set extra block.
|
|
||||||
ASMJIT_INLINE void setExtraBlock(CBNode* node) noexcept { _extraBlock = node; }
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// [State]
|
// [State]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@@ -524,7 +519,6 @@ public:
|
|||||||
|
|
||||||
CCFunc* _func; //!< Function being processed.
|
CCFunc* _func; //!< Function being processed.
|
||||||
CBNode* _stop; //!< Stop node.
|
CBNode* _stop; //!< Stop node.
|
||||||
CBNode* _extraBlock; //!< Node that is used to insert extra code after the function body.
|
|
||||||
|
|
||||||
//! \internal
|
//! \internal
|
||||||
//!
|
//!
|
||||||
|
|||||||
@@ -2072,7 +2072,7 @@ _NextGroup:
|
|||||||
|
|
||||||
_Done:
|
_Done:
|
||||||
// Mark exit label and end node as fetched, otherwise they can be removed by
|
// Mark exit label and end node as fetched, otherwise they can be removed by
|
||||||
// `removeUnreachableCode()`, which would lead to a crash in some later step.
|
// `removeUnreachableCode()`, which could lead to a crash in some later step.
|
||||||
node_ = func->getEnd();
|
node_ = func->getEnd();
|
||||||
if (!node_->hasPassData()) {
|
if (!node_->hasPassData()) {
|
||||||
CBLabel* fExit = func->getExitNode();
|
CBLabel* fExit = func->getExitNode();
|
||||||
@@ -2107,7 +2107,7 @@ Error X86RAPass::annotate() {
|
|||||||
StringBuilderTmp<256> sb;
|
StringBuilderTmp<256> sb;
|
||||||
|
|
||||||
uint32_t maxLen = 0;
|
uint32_t maxLen = 0;
|
||||||
while (node_ != end) {
|
while (node_ && node_ != end) {
|
||||||
if (!node_->hasInlineComment()) {
|
if (!node_->hasInlineComment()) {
|
||||||
if (node_->getType() == CBNode::kNodeInst) {
|
if (node_->getType() == CBNode::kNodeInst) {
|
||||||
CBInst* node = static_cast<CBInst*>(node_);
|
CBInst* node = static_cast<CBInst*>(node_);
|
||||||
@@ -3727,32 +3727,33 @@ static Error X86RAPass_patchFuncMem(X86RAPass* self, CCFunc* func, CBNode* stop,
|
|||||||
//! \internal
|
//! \internal
|
||||||
static void X86RAPass_translateJump(X86RAPass* self, CBJump* jNode, CBLabel* jTarget) {
|
static void X86RAPass_translateJump(X86RAPass* self, CBJump* jNode, CBLabel* jTarget) {
|
||||||
X86Compiler* cc = self->cc();
|
X86Compiler* cc = self->cc();
|
||||||
CBNode* extNode = self->getExtraBlock();
|
|
||||||
|
|
||||||
cc->_setCursor(extNode);
|
CBNode* injectRef = self->getFunc()->getEnd()->getPrev();
|
||||||
|
CBNode* prevCursor = cc->setCursor(injectRef);
|
||||||
|
|
||||||
self->switchState(jTarget->getPassData<RAData>()->state);
|
self->switchState(jTarget->getPassData<RAData>()->state);
|
||||||
|
|
||||||
// If one or more instruction has been added during switchState() it will be
|
// Any code necessary to `switchState()` will be added at the end of the function.
|
||||||
// moved at the end of the function body.
|
if (cc->getCursor() != injectRef) {
|
||||||
if (cc->getCursor() != extNode) {
|
|
||||||
// TODO: Can fail.
|
// TODO: Can fail.
|
||||||
CBLabel* jTrampolineTarget = cc->newLabelNode();
|
CBLabel* injectLabel = cc->newLabelNode();
|
||||||
|
|
||||||
// Add the jump to the target.
|
// Add the jump to the target.
|
||||||
cc->jmp(jTarget->getLabel());
|
cc->jmp(jTarget->getLabel());
|
||||||
|
|
||||||
// Add the trampoline-label we jump to change the state.
|
// Inject the label.
|
||||||
extNode = cc->setCursor(extNode);
|
cc->_setCursor(injectRef);
|
||||||
cc->addNode(jTrampolineTarget);
|
cc->addNode(injectLabel);
|
||||||
|
|
||||||
// Finally, patch the jump target.
|
// Finally, patch `jNode` target.
|
||||||
ASMJIT_ASSERT(jNode->getOpCount() > 0);
|
ASMJIT_ASSERT(jNode->getOpCount() > 0);
|
||||||
jNode->_opArray[0] = jTrampolineTarget->getLabel();
|
jNode->_opArray[jNode->getOpCount() - 1] = injectLabel->getLabel();
|
||||||
jNode->_target = jTrampolineTarget;
|
jNode->_target = injectLabel;
|
||||||
|
// If we injected any code it may not satisfy short form anymore.
|
||||||
|
jNode->delOptions(X86Inst::kOptionShortForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the `extNode` and load the state back.
|
cc->_setCursor(prevCursor);
|
||||||
self->setExtraBlock(extNode);
|
|
||||||
self->loadState(jNode->getPassData<RAData>()->state);
|
self->loadState(jNode->getPassData<RAData>()->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3904,6 +3905,9 @@ _NextGroup:
|
|||||||
CBLabel* node = static_cast<CBLabel*>(node_);
|
CBLabel* node = static_cast<CBLabel*>(node_);
|
||||||
ASMJIT_ASSERT(node->getPassData<RAData>()->state == nullptr);
|
ASMJIT_ASSERT(node->getPassData<RAData>()->state == nullptr);
|
||||||
node->getPassData<RAData>()->state = saveState();
|
node->getPassData<RAData>()->state = saveState();
|
||||||
|
|
||||||
|
if (node == func->getExitNode())
|
||||||
|
goto _NextGroup;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user