diff --git a/src/asmjit/base/codecompiler.cpp b/src/asmjit/base/codecompiler.cpp index a9176be..78b4bd7 100644 --- a/src/asmjit/base/codecompiler.cpp +++ b/src/asmjit/base/codecompiler.cpp @@ -116,9 +116,11 @@ CCFunc* CodeCompiler::newFunc(const FuncSignature& sign) noexcept { } // Create helper nodes. - func->_end = newNodeT(); func->_exitNode = newLabelNode(); - if (!func->_exitNode || !func->_end) goto _NoMemory; + func->_end = newNodeT(); + + if (!func->_exitNode || !func->_end) + goto _NoMemory; // Function prototype. 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). - setCursor(func->getExitNode()); - if (_localConstPool) { + setCursor(func->getEnd()->getPrev()); addNode(_localConstPool); _localConstPool = nullptr; } @@ -190,8 +191,9 @@ CBSentinel* CodeCompiler::endFunc() { func->_isFinished = true; _func = nullptr; - setCursor(func->getEnd()); - return func->getEnd(); + CBSentinel* end = func->getEnd(); + setCursor(end); + return end; } // ============================================================================ diff --git a/src/asmjit/base/codecompiler.h b/src/asmjit/base/codecompiler.h index e149f2b..5ff263c 100644 --- a/src/asmjit/base/codecompiler.h +++ b/src/asmjit/base/codecompiler.h @@ -292,7 +292,7 @@ public: //! Get function exit label. 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; } //! Get function declaration. diff --git a/src/asmjit/base/regalloc.cpp b/src/asmjit/base/regalloc.cpp index 37a46fa..ed89a3e 100644 --- a/src/asmjit/base/regalloc.cpp +++ b/src/asmjit/base/regalloc.cpp @@ -100,7 +100,6 @@ Error RAPass::prepare(CCFunc* func) noexcept { _func = func; _stop = end->getNext(); - _extraBlock = end; _unreachableList.reset(); _returningList.reset(); @@ -139,7 +138,6 @@ void RAPass::cleanup() noexcept { } _contextVd.reset(); - _extraBlock = nullptr; } // ============================================================================ diff --git a/src/asmjit/base/regalloc_p.h b/src/asmjit/base/regalloc_p.h index d953bf4..53c7aeb 100644 --- a/src/asmjit/base/regalloc_p.h +++ b/src/asmjit/base/regalloc_p.h @@ -360,11 +360,6 @@ public: //! Get stop node. 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] // -------------------------------------------------------------------------- @@ -524,7 +519,6 @@ public: CCFunc* _func; //!< Function being processed. CBNode* _stop; //!< Stop node. - CBNode* _extraBlock; //!< Node that is used to insert extra code after the function body. //! \internal //! diff --git a/src/asmjit/x86/x86regalloc.cpp b/src/asmjit/x86/x86regalloc.cpp index 6a89b6c..bb1c996 100644 --- a/src/asmjit/x86/x86regalloc.cpp +++ b/src/asmjit/x86/x86regalloc.cpp @@ -2072,7 +2072,7 @@ _NextGroup: _Done: // 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(); if (!node_->hasPassData()) { CBLabel* fExit = func->getExitNode(); @@ -2107,7 +2107,7 @@ Error X86RAPass::annotate() { StringBuilderTmp<256> sb; uint32_t maxLen = 0; - while (node_ != end) { + while (node_ && node_ != end) { if (!node_->hasInlineComment()) { if (node_->getType() == CBNode::kNodeInst) { CBInst* node = static_cast(node_); @@ -3727,32 +3727,33 @@ static Error X86RAPass_patchFuncMem(X86RAPass* self, CCFunc* func, CBNode* stop, //! \internal static void X86RAPass_translateJump(X86RAPass* self, CBJump* jNode, CBLabel* jTarget) { 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()->state); - // If one or more instruction has been added during switchState() it will be - // moved at the end of the function body. - if (cc->getCursor() != extNode) { + // Any code necessary to `switchState()` will be added at the end of the function. + if (cc->getCursor() != injectRef) { // TODO: Can fail. - CBLabel* jTrampolineTarget = cc->newLabelNode(); + CBLabel* injectLabel = cc->newLabelNode(); // Add the jump to the target. cc->jmp(jTarget->getLabel()); - // Add the trampoline-label we jump to change the state. - extNode = cc->setCursor(extNode); - cc->addNode(jTrampolineTarget); + // Inject the label. + cc->_setCursor(injectRef); + cc->addNode(injectLabel); - // Finally, patch the jump target. + // Finally, patch `jNode` target. ASMJIT_ASSERT(jNode->getOpCount() > 0); - jNode->_opArray[0] = jTrampolineTarget->getLabel(); - jNode->_target = jTrampolineTarget; + jNode->_opArray[jNode->getOpCount() - 1] = injectLabel->getLabel(); + 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. - self->setExtraBlock(extNode); + cc->_setCursor(prevCursor); self->loadState(jNode->getPassData()->state); } @@ -3904,6 +3905,9 @@ _NextGroup: CBLabel* node = static_cast(node_); ASMJIT_ASSERT(node->getPassData()->state == nullptr); node->getPassData()->state = saveState(); + + if (node == func->getExitNode()) + goto _NextGroup; break; }