mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 12:34:35 +03:00
Fixed indirect jumps to a single label (Compiler) (fixes #380)
This commit is contained in:
committed by
Petr Kobalicek
parent
5c469e3f7c
commit
052b4430e9
@@ -328,9 +328,14 @@ Error BaseRAPass::initSharedAssignments(const ZoneVector<uint32_t>& sharedAssign
|
|||||||
RABlock* firstSuccessor = successors[0];
|
RABlock* firstSuccessor = successors[0];
|
||||||
// NOTE: Shared assignments connect all possible successors so we only need the first to propagate exit scratch
|
// NOTE: Shared assignments connect all possible successors so we only need the first to propagate exit scratch
|
||||||
// GP registers.
|
// GP registers.
|
||||||
ASMJIT_ASSERT(firstSuccessor->hasSharedAssignmentId());
|
if (firstSuccessor->hasSharedAssignmentId()) {
|
||||||
RASharedAssignment& sa = _sharedAssignments[firstSuccessor->sharedAssignmentId()];
|
RASharedAssignment& sa = _sharedAssignments[firstSuccessor->sharedAssignmentId()];
|
||||||
sa.addEntryScratchGpRegs(block->exitScratchGpRegs());
|
sa.addEntryScratchGpRegs(block->exitScratchGpRegs());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// This is only allowed if there is a single successor - in that case shared assignment is not necessary.
|
||||||
|
ASMJIT_ASSERT(successors.size() == 1u);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (block->hasSharedAssignmentId()) {
|
if (block->hasSharedAssignmentId()) {
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(x86::Compiler& cc) {
|
virtual void compile(x86::Compiler& cc) {
|
||||||
Label L0 = cc.newLabel();
|
Label L0 = cc.newLabel();
|
||||||
Label L1 = cc.newLabel();
|
Label L1 = cc.newLabel();
|
||||||
Label L2 = cc.newLabel();
|
Label L2 = cc.newLabel();
|
||||||
Label LEnd = cc.newLabel();
|
Label LEnd = cc.newLabel();
|
||||||
@@ -715,6 +715,126 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// x86::Compiler - X86Test_JumpTable3
|
||||||
|
// ==================================
|
||||||
|
|
||||||
|
class X86Test_JumpTable3 : public X86TestCase {
|
||||||
|
public:
|
||||||
|
X86Test_JumpTable3()
|
||||||
|
: X86TestCase("JumpTable {Jumping to a single label}") {}
|
||||||
|
|
||||||
|
static void add(TestApp& app) {
|
||||||
|
app.add(new X86Test_JumpTable3());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void compile(x86::Compiler& cc) {
|
||||||
|
cc.addFunc(FuncSignatureT<int>(CallConvId::kHost));
|
||||||
|
|
||||||
|
Label L_Target = cc.newLabel();
|
||||||
|
x86::Gp target = cc.newUIntPtr("target");
|
||||||
|
x86::Gp result = cc.newUInt32("result");
|
||||||
|
|
||||||
|
JumpAnnotation* annotation = cc.newJumpAnnotation();
|
||||||
|
annotation->addLabel(L_Target);
|
||||||
|
|
||||||
|
cc.lea(target, x86::ptr(L_Target));
|
||||||
|
cc.jmp(target, annotation);
|
||||||
|
|
||||||
|
cc.bind(L_Target);
|
||||||
|
cc.mov(result, 1234);
|
||||||
|
cc.ret(result);
|
||||||
|
cc.endFunc();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool run(void* _func, String& result, String& expect) {
|
||||||
|
typedef int (*Func)(void);
|
||||||
|
Func func = ptr_as_func<Func>(_func);
|
||||||
|
|
||||||
|
int out = func();
|
||||||
|
int expected = 1234;
|
||||||
|
|
||||||
|
result.assignFormat("ret=%d", out);
|
||||||
|
expect.assignFormat("ret=%d", expected);
|
||||||
|
|
||||||
|
return result == expect;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// x86::Compiler - X86Test_JumpTable4
|
||||||
|
// ==================================
|
||||||
|
|
||||||
|
class X86Test_JumpTable4 : public X86TestCase {
|
||||||
|
public:
|
||||||
|
X86Test_JumpTable4()
|
||||||
|
: X86TestCase("JumpTable {Jumping to a single label and multiple labels}") {}
|
||||||
|
|
||||||
|
static void add(TestApp& app) {
|
||||||
|
app.add(new X86Test_JumpTable4());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void compile(x86::Compiler& cc) {
|
||||||
|
x86::Gp result = cc.newUInt32("result");
|
||||||
|
x86::Gp condition = cc.newUInt32("condition");
|
||||||
|
|
||||||
|
FuncNode* func = cc.addFunc(FuncSignatureT<int, int>(CallConvId::kHost));
|
||||||
|
func->setArg(0, condition);
|
||||||
|
|
||||||
|
Label L_NonZero = cc.newLabel();
|
||||||
|
cc.test(condition, condition);
|
||||||
|
cc.jnz(L_NonZero);
|
||||||
|
|
||||||
|
{
|
||||||
|
JumpAnnotation* annotation = cc.newJumpAnnotation();
|
||||||
|
Label L_Target = cc.newLabel();
|
||||||
|
annotation->addLabel(L_Target);
|
||||||
|
|
||||||
|
x86::Gp target = cc.newUIntPtr("target");
|
||||||
|
cc.lea(target, x86::ptr(L_Target));
|
||||||
|
cc.jmp(target, annotation);
|
||||||
|
cc.bind(L_Target);
|
||||||
|
cc.mov(result, 1234);
|
||||||
|
cc.ret(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
JumpAnnotation* annotation = cc.newJumpAnnotation();
|
||||||
|
Label L_Target1 = cc.newLabel();
|
||||||
|
Label L_Target2 = cc.newLabel();
|
||||||
|
annotation->addLabel(L_Target1);
|
||||||
|
annotation->addLabel(L_Target2);
|
||||||
|
|
||||||
|
cc.bind(L_NonZero);
|
||||||
|
x86::Gp target = cc.newUIntPtr("target");
|
||||||
|
cc.lea(target, x86::ptr(L_Target1));
|
||||||
|
cc.jmp(target, annotation);
|
||||||
|
|
||||||
|
cc.bind(L_Target1);
|
||||||
|
cc.mov(result, 4321);
|
||||||
|
cc.ret(result);
|
||||||
|
|
||||||
|
// Never executed.
|
||||||
|
cc.bind(L_Target2);
|
||||||
|
cc.mov(result, 0);
|
||||||
|
cc.ret(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
cc.endFunc();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool run(void* _func, String& result, String& expect) {
|
||||||
|
typedef int (*Func)(int);
|
||||||
|
Func func = ptr_as_func<Func>(_func);
|
||||||
|
|
||||||
|
int results[2] = { func(0), func(1) };
|
||||||
|
int expected[2] = { 1234, 4321 };
|
||||||
|
|
||||||
|
result.assignFormat("ret={%d, %d}", results[0], results[1]);
|
||||||
|
expect.assignFormat("ret={%d, %d}", expected[0], expected[1]);
|
||||||
|
|
||||||
|
return result == expect;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// x86::Compiler - X86Test_AllocBase
|
// x86::Compiler - X86Test_AllocBase
|
||||||
// =================================
|
// =================================
|
||||||
|
|
||||||
@@ -4246,6 +4366,8 @@ void compiler_add_x86_tests(TestApp& app) {
|
|||||||
app.addT<X86Test_JumpUnreachable2>();
|
app.addT<X86Test_JumpUnreachable2>();
|
||||||
app.addT<X86Test_JumpTable1>();
|
app.addT<X86Test_JumpTable1>();
|
||||||
app.addT<X86Test_JumpTable2>();
|
app.addT<X86Test_JumpTable2>();
|
||||||
|
app.addT<X86Test_JumpTable3>();
|
||||||
|
app.addT<X86Test_JumpTable4>();
|
||||||
|
|
||||||
// Alloc tests.
|
// Alloc tests.
|
||||||
app.addT<X86Test_AllocBase>();
|
app.addT<X86Test_AllocBase>();
|
||||||
|
|||||||
Reference in New Issue
Block a user