mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-16 20:17:05 +03:00
Fixed some bugs described in Issue #3
Added more test cases based on Issue #3 Minor changes.
This commit is contained in:
@@ -851,7 +851,7 @@ struct X86Test_AllocGpLo : public X86Test {
|
||||
// ============================================================================
|
||||
|
||||
struct X86Test_AllocRepMovsb : public X86Test {
|
||||
X86Test_AllocRepMovsb() : X86Test("[Special] Rep Movsb") {}
|
||||
X86Test_AllocRepMovsb() : X86Test("[Alloc] Rep Movsb") {}
|
||||
|
||||
static void add(PodVector<X86Test*>& tests) {
|
||||
tests.append(new X86Test_AllocSetz());
|
||||
@@ -887,6 +887,117 @@ struct X86Test_AllocRepMovsb : public X86Test {
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// [X86Test_AllocIfElse1]
|
||||
// ============================================================================
|
||||
|
||||
struct X86Test_AllocIfElse1 : public X86Test {
|
||||
X86Test_AllocIfElse1() : X86Test("[Alloc] If-Else #1") {}
|
||||
|
||||
static void add(PodVector<X86Test*>& tests) {
|
||||
tests.append(new X86Test_AllocIfElse1());
|
||||
}
|
||||
|
||||
virtual void compile(Compiler& c) {
|
||||
c.addFunc(kFuncConvHost, FuncBuilder2<int,int,int>());
|
||||
|
||||
GpVar v1(c, kVarTypeInt32);
|
||||
GpVar v2(c, kVarTypeInt32);
|
||||
|
||||
Label L_1(c);
|
||||
Label L_2(c);
|
||||
|
||||
c.setArg(0, v1);
|
||||
c.setArg(1, v2);
|
||||
|
||||
c.cmp(v1, v2);
|
||||
c.jg(L_1);
|
||||
|
||||
c.mov(v1, 1);
|
||||
c.jmp(L_2);
|
||||
|
||||
c.bind(L_1);
|
||||
c.mov(v1, 2);
|
||||
|
||||
c.bind(L_2);
|
||||
c.ret(v1);
|
||||
c.endFunc();
|
||||
}
|
||||
|
||||
virtual bool run(void* _func, StringBuilder& result, StringBuilder& expect) {
|
||||
typedef int (*Func)(int, int);
|
||||
Func func = asmjit_cast<Func>(_func);
|
||||
|
||||
int a = func(1, 0);
|
||||
int b = func(0, 1);
|
||||
|
||||
result.appendFormat("ret={%d, %d}", a, b);
|
||||
result.appendFormat("ret={%d, %d}", 2, 1);
|
||||
|
||||
return a == 2 && b == 1;
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// [X86Test_AllocIfElse2]
|
||||
// ============================================================================
|
||||
|
||||
struct X86Test_AllocIfElse2 : public X86Test {
|
||||
X86Test_AllocIfElse2() : X86Test("[Alloc] If-Else #1") {}
|
||||
|
||||
static void add(PodVector<X86Test*>& tests) {
|
||||
tests.append(new X86Test_AllocIfElse2());
|
||||
}
|
||||
|
||||
virtual void compile(Compiler& c) {
|
||||
c.addFunc(kFuncConvHost, FuncBuilder2<int,int,int>());
|
||||
|
||||
GpVar v1(c, kVarTypeInt32);
|
||||
GpVar v2(c, kVarTypeInt32);
|
||||
|
||||
Label L_1(c);
|
||||
Label L_2(c);
|
||||
Label L_3(c);
|
||||
Label L_4(c);
|
||||
|
||||
c.setArg(0, v1);
|
||||
c.setArg(1, v2);
|
||||
|
||||
c.jmp(L_1);
|
||||
c.bind(L_2);
|
||||
c.jmp(L_4);
|
||||
c.bind(L_1);
|
||||
|
||||
c.cmp(v1, v2);
|
||||
c.jg(L_3);
|
||||
|
||||
c.mov(v1, 1);
|
||||
c.jmp(L_2);
|
||||
|
||||
c.bind(L_3);
|
||||
c.mov(v1, 2);
|
||||
c.jmp(L_2);
|
||||
|
||||
c.bind(L_4);
|
||||
|
||||
c.ret(v1);
|
||||
c.endFunc();
|
||||
}
|
||||
|
||||
virtual bool run(void* _func, StringBuilder& result, StringBuilder& expect) {
|
||||
typedef int (*Func)(int, int);
|
||||
Func func = asmjit_cast<Func>(_func);
|
||||
|
||||
int a = func(1, 0);
|
||||
int b = func(0, 1);
|
||||
|
||||
result.appendFormat("ret={%d, %d}", a, b);
|
||||
result.appendFormat("ret={%d, %d}", 2, 1);
|
||||
|
||||
return a == 2 && b == 1;
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// [X86Test_AllocArgs]
|
||||
// ============================================================================
|
||||
@@ -1705,6 +1816,8 @@ X86TestSuite::X86TestSuite() :
|
||||
ADD_TEST(X86Test_AllocShlRor);
|
||||
ADD_TEST(X86Test_AllocGpLo);
|
||||
ADD_TEST(X86Test_AllocRepMovsb);
|
||||
ADD_TEST(X86Test_AllocIfElse1);
|
||||
ADD_TEST(X86Test_AllocIfElse2);
|
||||
ADD_TEST(X86Test_AllocArgs);
|
||||
ADD_TEST(X86Test_AllocStack);
|
||||
ADD_TEST(X86Test_AllocMemcpy);
|
||||
|
||||
@@ -176,6 +176,32 @@ BaseNode* BaseCompiler::addNodeAfter(BaseNode* node, BaseNode* ref) {
|
||||
return node;
|
||||
}
|
||||
|
||||
static ASMJIT_INLINE void BaseCompiler_nodeRemoved(BaseCompiler* self, BaseNode* node_) {
|
||||
if (node_->isJmpOrJcc()) {
|
||||
JumpNode* node = static_cast<JumpNode*>(node_);
|
||||
TargetNode* target = node->getTarget();
|
||||
|
||||
// Disconnect.
|
||||
JumpNode** pPrev = &target->_from;
|
||||
for (;;) {
|
||||
ASMJIT_ASSERT(*pPrev != NULL);
|
||||
JumpNode* current = *pPrev;
|
||||
|
||||
if (current == NULL)
|
||||
break;
|
||||
|
||||
if (current == node) {
|
||||
*pPrev = node->_jumpNext;
|
||||
break;
|
||||
}
|
||||
|
||||
pPrev = ¤t->_jumpNext;
|
||||
}
|
||||
|
||||
target->subNumRefs();
|
||||
}
|
||||
}
|
||||
|
||||
BaseNode* BaseCompiler::removeNode(BaseNode* node) {
|
||||
BaseNode* prev = node->_prev;
|
||||
BaseNode* next = node->_next;
|
||||
@@ -195,6 +221,7 @@ BaseNode* BaseCompiler::removeNode(BaseNode* node) {
|
||||
|
||||
if (_cursor == node)
|
||||
_cursor = prev;
|
||||
BaseCompiler_nodeRemoved(this, node);
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -228,6 +255,7 @@ void BaseCompiler::removeNodes(BaseNode* first, BaseNode* last) {
|
||||
|
||||
if (_cursor == node)
|
||||
_cursor = prev;
|
||||
BaseCompiler_nodeRemoved(this, node);
|
||||
|
||||
if (node == last)
|
||||
break;
|
||||
|
||||
@@ -1063,8 +1063,11 @@ struct TargetNode : public BaseNode {
|
||||
ASMJIT_INLINE uint32_t getNumRefs() const { return _numRefs; }
|
||||
//! @brief Set number of jumps to this target.
|
||||
ASMJIT_INLINE void setNumRefs(uint32_t i) { _numRefs = i; }
|
||||
|
||||
//! @brief Add number of jumps to this target.
|
||||
ASMJIT_INLINE void addNumRefs(uint32_t i = 1) { _numRefs += i; }
|
||||
//! @brief Subtract number of jumps to this target.
|
||||
ASMJIT_INLINE void subNumRefs(uint32_t i = 1) { _numRefs -= i; }
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// [Members]
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
// [Api-Begin]
|
||||
#include "../base/apibegin.h"
|
||||
|
||||
// helpers
|
||||
namespace asmjit {
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -40,7 +40,7 @@ ASMJIT_ENUM(kGlobals) {
|
||||
|
||||
//! @brief Memory grow threshold.
|
||||
//!
|
||||
//! After the grow threshold is reached the capacity won't be doubled
|
||||
//! After the grow threshold is reached the capacity won't be doubled
|
||||
//! anymore.
|
||||
kMemAllocGrowMax = 8192 * 1024,
|
||||
|
||||
|
||||
@@ -113,4 +113,5 @@ struct PodList {
|
||||
// [Api-End]
|
||||
#include "../base/apiend.h"
|
||||
|
||||
// [Guard]
|
||||
#endif // _ASMJIT_BASE_PODLIST_H
|
||||
|
||||
@@ -259,4 +259,5 @@ struct PodVector : PodVectorBase {
|
||||
// [Api-End]
|
||||
#include "../base/apiend.h"
|
||||
|
||||
// [Guard]
|
||||
#endif // _ASMJIT_BASE_PODVECTOR_H
|
||||
|
||||
@@ -347,4 +347,5 @@ struct StringBuilderT : public StringBuilder {
|
||||
// [Api-End]
|
||||
#include "../base/apiend.h"
|
||||
|
||||
// [Guard]
|
||||
#endif // _ASMJIT_BASE_STRING_H
|
||||
|
||||
@@ -188,4 +188,5 @@ struct Zone {
|
||||
// [Api-End]
|
||||
#include "../base/apiend.h"
|
||||
|
||||
// [Guard]
|
||||
#endif // _ASMJIT_BASE_ZONE_H
|
||||
|
||||
@@ -1367,6 +1367,8 @@ static ASMJIT_INLINE void X86X64Context_switchStateVars(X86X64Context* self, Var
|
||||
}
|
||||
|
||||
void X86X64Context::switchState(BaseVarState* src_) {
|
||||
ASMJIT_ASSERT(src_ != NULL);
|
||||
|
||||
VarState* cur = getState();
|
||||
VarState* src = static_cast<VarState*>(src_);
|
||||
|
||||
@@ -1476,7 +1478,7 @@ static void X86X64Context_prepareSingleVarInst(uint32_t code, VarAttr* va) {
|
||||
//! @internal
|
||||
//!
|
||||
//! @brief Add unreachable-flow data to the unreachable flow list.
|
||||
static ASMJIT_INLINE Error X86X64Context_prepareAddUnreachableNode(X86X64Context* self, BaseNode* node) {
|
||||
static ASMJIT_INLINE Error X86X64Context_addUnreachableNode(X86X64Context* self, BaseNode* node) {
|
||||
PodList<BaseNode*>::Link* link = self->_zoneAllocator.allocT<PodList<BaseNode*>::Link>();
|
||||
if (link == NULL)
|
||||
return self->setError(kErrorNoHeapMemory);
|
||||
@@ -1490,7 +1492,7 @@ static ASMJIT_INLINE Error X86X64Context_prepareAddUnreachableNode(X86X64Context
|
||||
//! @internal
|
||||
//!
|
||||
//! @brief Add jump-flow data to the jcc flow list.
|
||||
static ASMJIT_INLINE Error X86X64Context_prepareAddJccNode(X86X64Context* self, BaseNode* node) {
|
||||
static ASMJIT_INLINE Error X86X64Context_addJccNode(X86X64Context* self, BaseNode* node) {
|
||||
PodList<BaseNode*>::Link* link = self->_zoneAllocator.allocT<PodList<BaseNode*>::Link>();
|
||||
|
||||
if (link == NULL)
|
||||
@@ -2059,7 +2061,7 @@ _NextGroup:
|
||||
// natural flow of the function.
|
||||
if (jNode->isJmp()) {
|
||||
if (!jNext->isFetched())
|
||||
ASMJIT_PROPAGATE_ERROR(X86X64Context_prepareAddUnreachableNode(this, jNext));
|
||||
ASMJIT_PROPAGATE_ERROR(X86X64Context_addUnreachableNode(this, jNext));
|
||||
|
||||
node_ = jTarget;
|
||||
goto _Do;
|
||||
@@ -2080,7 +2082,7 @@ _NextGroup:
|
||||
goto _Do;
|
||||
}
|
||||
else {
|
||||
ASMJIT_PROPAGATE_ERROR(X86X64Context_prepareAddJccNode(this, jNode));
|
||||
ASMJIT_PROPAGATE_ERROR(X86X64Context_addJccNode(this, jNode));
|
||||
|
||||
node_ = X86X64Context_getJccFlow(jNode);
|
||||
goto _Do;
|
||||
@@ -2409,6 +2411,8 @@ _OnVisit:
|
||||
|
||||
if (node == func)
|
||||
goto _OnDone;
|
||||
|
||||
ASMJIT_ASSERT(node->getPrev());
|
||||
node = node->getPrev();
|
||||
}
|
||||
|
||||
@@ -4671,22 +4675,26 @@ _NextGroup:
|
||||
goto _Done;
|
||||
}
|
||||
else {
|
||||
JumpNode* jNode = static_cast<JumpNode*>(jLink->getValue());
|
||||
node_ = jLink->getValue();
|
||||
jLink = jLink->getNext();
|
||||
|
||||
BaseNode* jFlow = X86X64Context_getOppositeJccFlow(jNode);
|
||||
loadState(jNode->getState());
|
||||
BaseNode* jFlow = X86X64Context_getOppositeJccFlow(static_cast<JumpNode*>(node_));
|
||||
loadState(node_->getState());
|
||||
|
||||
// TODO:
|
||||
if (jNode->getNext() == jFlow) {
|
||||
if (jFlow->getState()) {
|
||||
X86X64Context_translateJump(this,
|
||||
static_cast<JumpNode*>(node_),
|
||||
static_cast<TargetNode*>(jFlow));
|
||||
|
||||
node_ = jFlow;
|
||||
if (node_->isTranslated())
|
||||
goto _NextGroup;
|
||||
}
|
||||
else {
|
||||
X86X64Context_translateJump(this, jNode, static_cast<TargetNode*>(jFlow));
|
||||
node_ = jFlow;
|
||||
}
|
||||
|
||||
node_ = jFlow;
|
||||
if (node_->isTranslated())
|
||||
goto _NextGroup;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,14 +62,14 @@
|
||||
@define asmjit::kNodeTypeAlign (0x1)
|
||||
@define asmjit::kNodeTypeEmbed (0x2)
|
||||
@define asmjit::kNodeTypeComment (0x3)
|
||||
@define asmjit::kNodeTypeMark (0x4)
|
||||
@define asmjit::kNodeTypeHint (0x5)
|
||||
@define asmjit::kNodeTypeTarget (0x6)
|
||||
@define asmjit::kNodeTypeInst (0x7)
|
||||
@define asmjit::kNodeTypeFunc (0x8)
|
||||
@define asmjit::kNodeTypeEnd (0x9)
|
||||
@define asmjit::kNodeTypeRet (0xA)
|
||||
@define asmjit::kNodeTypeCall (0xB)
|
||||
@define asmjit::kNodeTypeHint (0x4)
|
||||
@define asmjit::kNodeTypeTarget (0x5)
|
||||
@define asmjit::kNodeTypeInst (0x6)
|
||||
@define asmjit::kNodeTypeFunc (0x7)
|
||||
@define asmjit::kNodeTypeEnd (0x8)
|
||||
@define asmjit::kNodeTypeRet (0x9)
|
||||
@define asmjit::kNodeTypeCall (0xA)
|
||||
@define asmjit::kNodeTypeSArg (0xB)
|
||||
@
|
||||
@define asmjit::kNodeFlagIsTranslated (0x0001)
|
||||
@define asmjit::kNodeFlagIsJmp (0x0002)
|
||||
@@ -801,13 +801,12 @@ asmjit::BaseVarInst|asmjit::x86x64::VarInst {
|
||||
; [asmjit::X86 - Compiler - BaseNode]
|
||||
; =============================================================================
|
||||
|
||||
asmjit::BaseNode|asmjit::AlignNode|asmjit::EmbedNode|asmjit::CommentNode|asmjit::MarkNode|asmjit::HintNode|asmjit::TargetNode|asmjit::InstNode|asmjit::JumpNode::asmjit::FuncNode|asmjit::EndNode|asmjit::RetNode|asmjit::x86x64::X86X64FuncNode|asmjit::x86x64::X86X64CallNode {
|
||||
asmjit::BaseNode|asmjit::AlignNode|asmjit::EmbedNode|asmjit::CommentNode|asmjit::HintNode|asmjit::TargetNode|asmjit::InstNode|asmjit::JumpNode::asmjit::FuncNode|asmjit::EndNode|asmjit::RetNode|asmjit::x86x64::X86X64FuncNode|asmjit::x86x64::X86X64CallNode|asmjit::SArgNode {
|
||||
preview(
|
||||
#(
|
||||
#if ($e._type == asmjit::kNodeTypeAlign) ("AlignNode")
|
||||
#elif ($e._type == asmjit::kNodeTypeEmbed) ("EmbedNode")
|
||||
#elif ($e._type == asmjit::kNodeTypeComment) ("CommentNode")
|
||||
#elif ($e._type == asmjit::kNodeTypeMark) ("MarkNode")
|
||||
#elif ($e._type == asmjit::kNodeTypeHint) ("HintNode")
|
||||
#elif ($e._type == asmjit::kNodeTypeTarget) ("TargetNode")
|
||||
#elif ($e._type == asmjit::kNodeTypeInst) ("InstNode")
|
||||
@@ -815,6 +814,7 @@ asmjit::BaseNode|asmjit::AlignNode|asmjit::EmbedNode|asmjit::CommentNode|asmjit:
|
||||
#elif ($e._type == asmjit::kNodeTypeEnd) ("EndNode")
|
||||
#elif ($e._type == asmjit::kNodeTypeRet) ("RetNode")
|
||||
#elif ($e._type == asmjit::kNodeTypeCall) ("CallNode")
|
||||
#elif ($e._type == asmjit::kNodeTypeSArg) ("SArgNode")
|
||||
#else ("BaseNode"),
|
||||
|
||||
"(",
|
||||
|
||||
Reference in New Issue
Block a user