mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 12:34:35 +03:00
[Bug] Jump annotation to entry block fix
This commit is contained in:
@@ -95,12 +95,13 @@ public:
|
|||||||
logNode(_funcNode, kRootIndentation);
|
logNode(_funcNode, kRootIndentation);
|
||||||
logBlock(_curBlock, kRootIndentation);
|
logBlock(_curBlock, kRootIndentation);
|
||||||
|
|
||||||
|
RABlock* entryBlock = _curBlock;
|
||||||
BaseNode* node = _funcNode->next();
|
BaseNode* node = _funcNode->next();
|
||||||
if (ASMJIT_UNLIKELY(!node))
|
if (ASMJIT_UNLIKELY(!node))
|
||||||
return DebugUtils::errored(kErrorInvalidState);
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
|
||||||
_curBlock->setFirst(node);
|
_curBlock->setFirst(_funcNode);
|
||||||
_curBlock->setLast(node);
|
_curBlock->setLast(_funcNode);
|
||||||
|
|
||||||
RAInstBuilder ib;
|
RAInstBuilder ib;
|
||||||
ZoneVector<RABlock*> blocksWithUnknownJumps;
|
ZoneVector<RABlock*> blocksWithUnknownJumps;
|
||||||
@@ -379,9 +380,10 @@ public:
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// First time we see this label.
|
// First time we see this label.
|
||||||
if (_hasCode) {
|
if (_hasCode || _curBlock == entryBlock) {
|
||||||
// Cannot continue the current block if it already contains some
|
// Cannot continue the current block if it already contains some
|
||||||
// code. We need to create a new block and make it a successor.
|
// code or it's a block entry. We need to create a new block and
|
||||||
|
// make it a successor.
|
||||||
ASMJIT_ASSERT(_curBlock->last() != node);
|
ASMJIT_ASSERT(_curBlock->last() != node);
|
||||||
_curBlock->setLast(node->prev());
|
_curBlock->setLast(node->prev());
|
||||||
_curBlock->addFlags(RABlock::kFlagHasConsecutive);
|
_curBlock->addFlags(RABlock::kFlagHasConsecutive);
|
||||||
|
|||||||
@@ -547,15 +547,15 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [X86Test_JumpTable]
|
// [X86Test_JumpTable1]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
class X86Test_JumpTable : public X86TestCase {
|
class X86Test_JumpTable1 : public X86TestCase {
|
||||||
public:
|
public:
|
||||||
bool _annotated;
|
bool _annotated;
|
||||||
|
|
||||||
X86Test_JumpTable(bool annotated)
|
X86Test_JumpTable1(bool annotated)
|
||||||
: X86TestCase("X86Test_JumpTable"),
|
: X86TestCase("X86Test_JumpTable1"),
|
||||||
_annotated(annotated) {
|
_annotated(annotated) {
|
||||||
_name.assignFormat("JumpTable {%s}", annotated ? "Annotated" : "Unknown Reg/Mem");
|
_name.assignFormat("JumpTable {%s}", annotated ? "Annotated" : "Unknown Reg/Mem");
|
||||||
}
|
}
|
||||||
@@ -568,8 +568,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void add(TestApp& app) {
|
static void add(TestApp& app) {
|
||||||
app.add(new X86Test_JumpTable(false));
|
app.add(new X86Test_JumpTable1(false));
|
||||||
app.add(new X86Test_JumpTable(true));
|
app.add(new X86Test_JumpTable1(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(x86::Compiler& cc) {
|
virtual void compile(x86::Compiler& cc) {
|
||||||
@@ -665,6 +665,89 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [X86Test_JumpTable2]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
class X86Test_JumpTable2 : public X86TestCase {
|
||||||
|
public:
|
||||||
|
X86Test_JumpTable2()
|
||||||
|
: X86TestCase("JumpTable {Jumping to Begin}") {}
|
||||||
|
|
||||||
|
static void add(TestApp& app) {
|
||||||
|
app.add(new X86Test_JumpTable2());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void compile(x86::Compiler& cc) {
|
||||||
|
cc.addFunc(FuncSignatureT<int, int>(CallConv::kIdHost));
|
||||||
|
|
||||||
|
x86::Gp result = cc.newUInt32("result");
|
||||||
|
x86::Gp value = cc.newUInt32("value");
|
||||||
|
x86::Gp target = cc.newIntPtr("target");
|
||||||
|
x86::Gp offset = cc.newIntPtr("offset");
|
||||||
|
|
||||||
|
Label L_Table = cc.newLabel();
|
||||||
|
Label L_Begin = cc.newLabel();
|
||||||
|
Label L_Case0 = cc.newLabel();
|
||||||
|
Label L_Case1 = cc.newLabel();
|
||||||
|
Label L_End = cc.newLabel();
|
||||||
|
|
||||||
|
cc.setArg(0, value);
|
||||||
|
|
||||||
|
cc.bind(L_Begin);
|
||||||
|
cc.lea(offset, x86::ptr(L_Table));
|
||||||
|
if (cc.is64Bit())
|
||||||
|
cc.movsxd(target, x86::dword_ptr(offset, value.cloneAs(offset), 2));
|
||||||
|
else
|
||||||
|
cc.mov(target, x86::dword_ptr(offset, value.cloneAs(offset), 2));
|
||||||
|
cc.add(target, offset);
|
||||||
|
|
||||||
|
{
|
||||||
|
JumpAnnotation* annotation = cc.newJumpAnnotation();
|
||||||
|
annotation->addLabel(L_Case0);
|
||||||
|
annotation->addLabel(L_Case1);
|
||||||
|
annotation->addLabel(L_Begin); // Never used, just for the purpose of the test.
|
||||||
|
cc.jmp(target, annotation);
|
||||||
|
|
||||||
|
cc.bind(L_Case0);
|
||||||
|
cc.mov(result, 0);
|
||||||
|
cc.jmp(L_End);
|
||||||
|
|
||||||
|
cc.bind(L_Case1);
|
||||||
|
cc.mov(result, 1);
|
||||||
|
cc.jmp(L_End);
|
||||||
|
}
|
||||||
|
|
||||||
|
cc.bind(L_End);
|
||||||
|
cc.ret(result);
|
||||||
|
|
||||||
|
cc.endFunc();
|
||||||
|
|
||||||
|
cc.bind(L_Table);
|
||||||
|
cc.embedLabelDelta(L_Case0, L_Table, 4);
|
||||||
|
cc.embedLabelDelta(L_Case1, L_Table, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool run(void* _func, String& result, String& expect) {
|
||||||
|
typedef int (*Func)(int);
|
||||||
|
Func func = ptr_as_func<Func>(_func);
|
||||||
|
|
||||||
|
int results[2];
|
||||||
|
int expected[2];
|
||||||
|
|
||||||
|
results[0] = func(0);
|
||||||
|
results[1] = func(1);
|
||||||
|
|
||||||
|
expected[0] = 0;
|
||||||
|
expected[1] = 1;
|
||||||
|
|
||||||
|
result.assignFormat("ret={%d, %d}", results[0], results[1]);
|
||||||
|
expect.assignFormat("ret={%d, %d}", expected[0], expected[1]);
|
||||||
|
|
||||||
|
return result == expect;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [X86Test_AllocBase]
|
// [X86Test_AllocBase]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -4167,7 +4250,8 @@ void compiler_add_x86_tests(TestApp& app) {
|
|||||||
app.addT<X86Test_JumpMany>();
|
app.addT<X86Test_JumpMany>();
|
||||||
app.addT<X86Test_JumpUnreachable1>();
|
app.addT<X86Test_JumpUnreachable1>();
|
||||||
app.addT<X86Test_JumpUnreachable2>();
|
app.addT<X86Test_JumpUnreachable2>();
|
||||||
app.addT<X86Test_JumpTable>();
|
app.addT<X86Test_JumpTable1>();
|
||||||
|
app.addT<X86Test_JumpTable2>();
|
||||||
|
|
||||||
// Alloc tests.
|
// Alloc tests.
|
||||||
app.addT<X86Test_AllocBase>();
|
app.addT<X86Test_AllocBase>();
|
||||||
|
|||||||
Reference in New Issue
Block a user