mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-16 20:17:05 +03:00
Fixed dead code elimination.
Fixed wrong xchg instruction encoding under x64 if one of the operand is r8-15 register.
This commit is contained in:
@@ -231,14 +231,14 @@ struct X86Test_JumpCross : public X86Test {
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// [X86Test_JumpUnreachable]
|
||||
// [X86Test_JumpUnreachable1]
|
||||
// ============================================================================
|
||||
|
||||
struct X86Test_JumpUnreachable : public X86Test {
|
||||
X86Test_JumpUnreachable() : X86Test("[Jump] Unreachable code") {}
|
||||
struct X86Test_JumpUnreachable1 : public X86Test {
|
||||
X86Test_JumpUnreachable1() : X86Test("[Jump] Unreachable #1") {}
|
||||
|
||||
static void add(PodVector<X86Test*>& tests) {
|
||||
tests.append(new X86Test_JumpUnreachable());
|
||||
tests.append(new X86Test_JumpUnreachable1());
|
||||
}
|
||||
|
||||
virtual void compile(Compiler& c) {
|
||||
@@ -291,6 +291,52 @@ struct X86Test_JumpUnreachable : public X86Test {
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// [X86Test_JumpUnreachable2]
|
||||
// ============================================================================
|
||||
|
||||
struct X86Test_JumpUnreachable2 : public X86Test {
|
||||
X86Test_JumpUnreachable2() : X86Test("[Jump] Unreachable #2") {}
|
||||
|
||||
static void add(PodVector<X86Test*>& tests) {
|
||||
tests.append(new X86Test_JumpUnreachable2());
|
||||
}
|
||||
|
||||
virtual void compile(Compiler& c) {
|
||||
c.addFunc(kFuncConvHost, FuncBuilder0<FnVoid>());
|
||||
|
||||
Label L_1(c);
|
||||
Label L_2(c);
|
||||
|
||||
GpVar v0(c, kVarTypeUInt32, "v0");
|
||||
GpVar v1(c, kVarTypeUInt32, "v1");
|
||||
|
||||
c.jmp(L_1);
|
||||
c.bind(L_2);
|
||||
c.mov(v0, 1);
|
||||
c.mov(v1, 2);
|
||||
c.cmp(v0, v1);
|
||||
c.jz(L_2);
|
||||
c.jmp(L_1);
|
||||
|
||||
c.bind(L_1);
|
||||
c.ret();
|
||||
c.endFunc();
|
||||
}
|
||||
|
||||
virtual bool run(void* _func, StringBuilder& result, StringBuilder& expect) {
|
||||
typedef void (*Func)(void);
|
||||
Func func = asmjit_cast<Func>(_func);
|
||||
|
||||
func();
|
||||
|
||||
result.appendString("ret={}");
|
||||
expect.appendString("ret={}");
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// [X86Test_AllocBase]
|
||||
// ============================================================================
|
||||
@@ -2331,7 +2377,8 @@ X86TestSuite::X86TestSuite() :
|
||||
|
||||
// Jump.
|
||||
ADD_TEST(X86Test_JumpCross);
|
||||
ADD_TEST(X86Test_JumpUnreachable);
|
||||
ADD_TEST(X86Test_JumpUnreachable1);
|
||||
ADD_TEST(X86Test_JumpUnreachable2);
|
||||
|
||||
// Alloc.
|
||||
ADD_TEST(X86Test_AllocBase);
|
||||
|
||||
@@ -270,11 +270,11 @@ Error BaseContext::removeUnreachableCode() {
|
||||
|
||||
while (link != NULL) {
|
||||
BaseNode* node = link->getValue();
|
||||
if (node != NULL) {
|
||||
if (node != NULL && node->getPrev() != NULL) {
|
||||
// Locate all unreachable nodes.
|
||||
BaseNode* first = node;
|
||||
do {
|
||||
if (node->isFetched() || (node->getType() == kNodeTypeTarget && static_cast<TargetNode*>(node)->getNumRefs() > 0))
|
||||
if (node->isFetched())
|
||||
break;
|
||||
node = node->getNext();
|
||||
} while (node != stop);
|
||||
|
||||
@@ -2021,9 +2021,20 @@ _GroupPop_Gp:
|
||||
opReg = static_cast<const GpReg*>(o1)->getRegIndex();
|
||||
rmReg = static_cast<const GpReg*>(o0)->getRegIndex();
|
||||
|
||||
// Special opcode for AX/EAX/RAX.
|
||||
if (o0->getSize() > 1 && (opReg == 0 || rmReg == 0)) {
|
||||
opCode = 0x90 + opReg + rmReg; // One of them is zero.
|
||||
// Special opcode for 'xchg ?ax, reg'.
|
||||
if (code == kInstXchg && o0->getSize() > 1 && (opReg == 0 || rmReg == 0)) {
|
||||
// One of them is zero, it doesn't matter if the instruction's form is
|
||||
// 'xchg ?ax, reg' or 'xchg reg, ?ax'.
|
||||
opReg += rmReg;
|
||||
|
||||
// Rex.B (0x01).
|
||||
if (Arch == kArchX64) {
|
||||
opX += opReg >> 3;
|
||||
opReg &= 0x7;
|
||||
}
|
||||
|
||||
opCode = 0x90 + opReg;
|
||||
|
||||
ADD_66H_P(o0->getSize() == 2);
|
||||
ADD_REX_W(o0->getSize() == 8);
|
||||
goto _EmitX86Op;
|
||||
|
||||
Reference in New Issue
Block a user