mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-18 13:04:36 +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 {
|
struct X86Test_JumpUnreachable1 : public X86Test {
|
||||||
X86Test_JumpUnreachable() : X86Test("[Jump] Unreachable code") {}
|
X86Test_JumpUnreachable1() : X86Test("[Jump] Unreachable #1") {}
|
||||||
|
|
||||||
static void add(PodVector<X86Test*>& tests) {
|
static void add(PodVector<X86Test*>& tests) {
|
||||||
tests.append(new X86Test_JumpUnreachable());
|
tests.append(new X86Test_JumpUnreachable1());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Compiler& c) {
|
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]
|
// [X86Test_AllocBase]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -2331,7 +2377,8 @@ X86TestSuite::X86TestSuite() :
|
|||||||
|
|
||||||
// Jump.
|
// Jump.
|
||||||
ADD_TEST(X86Test_JumpCross);
|
ADD_TEST(X86Test_JumpCross);
|
||||||
ADD_TEST(X86Test_JumpUnreachable);
|
ADD_TEST(X86Test_JumpUnreachable1);
|
||||||
|
ADD_TEST(X86Test_JumpUnreachable2);
|
||||||
|
|
||||||
// Alloc.
|
// Alloc.
|
||||||
ADD_TEST(X86Test_AllocBase);
|
ADD_TEST(X86Test_AllocBase);
|
||||||
|
|||||||
@@ -270,11 +270,11 @@ Error BaseContext::removeUnreachableCode() {
|
|||||||
|
|
||||||
while (link != NULL) {
|
while (link != NULL) {
|
||||||
BaseNode* node = link->getValue();
|
BaseNode* node = link->getValue();
|
||||||
if (node != NULL) {
|
if (node != NULL && node->getPrev() != NULL) {
|
||||||
// Locate all unreachable nodes.
|
// Locate all unreachable nodes.
|
||||||
BaseNode* first = node;
|
BaseNode* first = node;
|
||||||
do {
|
do {
|
||||||
if (node->isFetched() || (node->getType() == kNodeTypeTarget && static_cast<TargetNode*>(node)->getNumRefs() > 0))
|
if (node->isFetched())
|
||||||
break;
|
break;
|
||||||
node = node->getNext();
|
node = node->getNext();
|
||||||
} while (node != stop);
|
} while (node != stop);
|
||||||
|
|||||||
@@ -2021,9 +2021,20 @@ _GroupPop_Gp:
|
|||||||
opReg = static_cast<const GpReg*>(o1)->getRegIndex();
|
opReg = static_cast<const GpReg*>(o1)->getRegIndex();
|
||||||
rmReg = static_cast<const GpReg*>(o0)->getRegIndex();
|
rmReg = static_cast<const GpReg*>(o0)->getRegIndex();
|
||||||
|
|
||||||
// Special opcode for AX/EAX/RAX.
|
// Special opcode for 'xchg ?ax, reg'.
|
||||||
if (o0->getSize() > 1 && (opReg == 0 || rmReg == 0)) {
|
if (code == kInstXchg && o0->getSize() > 1 && (opReg == 0 || rmReg == 0)) {
|
||||||
opCode = 0x90 + opReg + rmReg; // One of them is zero.
|
// 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_66H_P(o0->getSize() == 2);
|
||||||
ADD_REX_W(o0->getSize() == 8);
|
ADD_REX_W(o0->getSize() == 8);
|
||||||
goto _EmitX86Op;
|
goto _EmitX86Op;
|
||||||
|
|||||||
Reference in New Issue
Block a user