Fixed some bugs described in Issue #3

Added more test cases based on Issue #3
Minor changes.
This commit is contained in:
kobalicekp
2014-03-01 17:01:54 +01:00
parent 5072395ceb
commit 5fe81c40c7
11 changed files with 181 additions and 26 deletions

View File

@@ -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);

View File

@@ -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 = &current->_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;

View File

@@ -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]

View File

@@ -13,7 +13,6 @@
// [Api-Begin]
#include "../base/apibegin.h"
// helpers
namespace asmjit {
// ============================================================================

View File

@@ -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,

View File

@@ -113,4 +113,5 @@ struct PodList {
// [Api-End]
#include "../base/apiend.h"
// [Guard]
#endif // _ASMJIT_BASE_PODLIST_H

View File

@@ -259,4 +259,5 @@ struct PodVector : PodVectorBase {
// [Api-End]
#include "../base/apiend.h"
// [Guard]
#endif // _ASMJIT_BASE_PODVECTOR_H

View File

@@ -347,4 +347,5 @@ struct StringBuilderT : public StringBuilder {
// [Api-End]
#include "../base/apiend.h"
// [Guard]
#endif // _ASMJIT_BASE_STRING_H

View File

@@ -188,4 +188,5 @@ struct Zone {
// [Api-End]
#include "../base/apiend.h"
// [Guard]
#endif // _ASMJIT_BASE_ZONE_H

View File

@@ -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;
}
}

View File

@@ -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"),
"(",