| Index: unittest/AssemblerX8632/ControlFlow.cpp
|
| diff --git a/unittest/AssemblerX8632/ControlFlow.cpp b/unittest/AssemblerX8632/ControlFlow.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..35adf072c304ed14b1ab19cbeed9a237a1c62de9
|
| --- /dev/null
|
| +++ b/unittest/AssemblerX8632/ControlFlow.cpp
|
| @@ -0,0 +1,244 @@
|
| +//===- subzero/unittest/AssemblerX8632/ControleFlow.cpp -------------------===//
|
| +//
|
| +// The Subzero Code Generator
|
| +//
|
| +// This file is distributed under the University of Illinois Open Source
|
| +// License. See LICENSE.TXT for details.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +#include "IceAssemblerX8632.h"
|
| +#include "AssemblerX8632/TestUtil.h"
|
| +
|
| +namespace Ice {
|
| +namespace X8632 {
|
| +namespace Test {
|
| +namespace {
|
| +
|
| +TEST_F(AssemblerX8632Test, J) {
|
| +#define TestJ(C, Near, Src0, Value0, Src1, Value1, Dest) \
|
| + do { \
|
| + const bool NearJmp = AssemblerX8632::k##Near##Jump; \
|
| + Label ShouldBeTaken; \
|
| + __ mov(IceType_i32, GPRRegister::Encoded_Reg_##Src0, Immediate(Value0)); \
|
| + __ mov(IceType_i32, GPRRegister::Encoded_Reg_##Src1, Immediate(Value1)); \
|
| + __ mov(IceType_i32, GPRRegister::Encoded_Reg_##Dest, Immediate(0xBEEF)); \
|
| + __ cmp(IceType_i32, GPRRegister::Encoded_Reg_##Src0, \
|
| + GPRRegister::Encoded_Reg_##Src1); \
|
| + __ j(Cond::Br_##C, &ShouldBeTaken, NearJmp); \
|
| + __ mov(IceType_i32, GPRRegister::Encoded_Reg_##Dest, Immediate(0xC0FFEE)); \
|
| + __ bind(&ShouldBeTaken); \
|
| + AssembledTest test = assemble(); \
|
| + test.run(); \
|
| + EXPECT_EQ(Value0, test.Src0()) << "Br_" #C ", " #Near; \
|
| + EXPECT_EQ(Value1, test.Src1()) << "Br_" #C ", " #Near; \
|
| + EXPECT_EQ(0xBEEFul, test.Dest()) << "Br_" #C ", " #Near; \
|
| + reset(); \
|
| + } while (0)
|
| +
|
| + TestJ(o, Near, eax, 0x80000000ul, ebx, 0x1ul, ecx);
|
| + TestJ(o, Far, ebx, 0x80000000ul, ecx, 0x1ul, edx);
|
| + TestJ(no, Near, ecx, 0x1ul, edx, 0x1ul, edi);
|
| + TestJ(no, Far, edx, 0x1ul, edi, 0x1ul, esi);
|
| + TestJ(b, Near, edi, 0x1ul, esi, 0x80000000ul, eax);
|
| + TestJ(b, Far, esi, 0x1ul, eax, 0x80000000ul, ebx);
|
| + TestJ(ae, Near, eax, 0x80000000ul, ebx, 0x1ul, ecx);
|
| + TestJ(ae, Far, ebx, 0x80000000ul, ecx, 0x1ul, edx);
|
| + TestJ(e, Near, ecx, 0x80000000ul, edx, 0x80000000ul, edi);
|
| + TestJ(e, Far, edx, 0x80000000ul, edi, 0x80000000ul, esi);
|
| + TestJ(ne, Near, edi, 0x80000000ul, esi, 0x1ul, eax);
|
| + TestJ(ne, Far, esi, 0x80000000ul, eax, 0x1ul, ebx);
|
| + TestJ(be, Near, eax, 0x1ul, ebx, 0x80000000ul, ecx);
|
| + TestJ(be, Far, ebx, 0x1ul, ecx, 0x80000000ul, edx);
|
| + TestJ(a, Near, ecx, 0x80000000ul, edx, 0x1ul, edi);
|
| + TestJ(a, Far, edx, 0x80000000ul, edi, 0x1ul, esi);
|
| + TestJ(s, Near, edi, 0x1ul, esi, 0x80000000ul, eax);
|
| + TestJ(s, Far, esi, 0x1ul, eax, 0x80000000ul, ebx);
|
| + TestJ(ns, Near, eax, 0x80000000ul, ebx, 0x1ul, ecx);
|
| + TestJ(ns, Far, ebx, 0x80000000ul, ecx, 0x1ul, edx);
|
| + TestJ(p, Near, ecx, 0x80000000ul, edx, 0x1ul, edi);
|
| + TestJ(p, Far, edx, 0x80000000ul, edi, 0x1ul, esi);
|
| + TestJ(np, Near, edi, 0x1ul, esi, 0x80000000ul, eax);
|
| + TestJ(np, Far, esi, 0x1ul, eax, 0x80000000ul, ebx);
|
| + TestJ(l, Near, eax, 0x80000000ul, ebx, 0x1ul, ecx);
|
| + TestJ(l, Far, ebx, 0x80000000ul, ecx, 0x1ul, edx);
|
| + TestJ(ge, Near, ecx, 0x1ul, edx, 0x80000000ul, edi);
|
| + TestJ(ge, Far, edx, 0x1ul, edi, 0x80000000ul, esi);
|
| + TestJ(le, Near, edi, 0x80000000ul, esi, 0x1ul, eax);
|
| + TestJ(le, Far, esi, 0x80000000ul, eax, 0x1ul, ebx);
|
| + TestJ(g, Near, eax, 0x1ul, ebx, 0x80000000ul, ecx);
|
| + TestJ(g, Far, ebx, 0x1ul, ecx, 0x80000000ul, edx);
|
| +
|
| +#undef TestJ
|
| +}
|
| +
|
| +TEST_F(AssemblerX8632Test, CallImm) {
|
| + __ call(Immediate(16));
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ mov(IceType_i32, GPRRegister::Encoded_Reg_eax, Immediate(0xf00f));
|
| + __ popl(GPRRegister::Encoded_Reg_ebx);
|
| +
|
| + AssembledTest test = assemble();
|
| +
|
| + test.run();
|
| +
|
| + EXPECT_EQ(0xF00Fu, test.eax());
|
| +}
|
| +
|
| +TEST_F(AssemblerX8632Test, CallReg) {
|
| + __ call(Immediate(16));
|
| + __ popl(GPRRegister::Encoded_Reg_edx);
|
| + __ pushl(GPRRegister::Encoded_Reg_edx);
|
| + __ ret();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ popl(GPRRegister::Encoded_Reg_ebx);
|
| + __ call(GPRRegister::Encoded_Reg_ebx);
|
| +
|
| + AssembledTest test = assemble();
|
| +
|
| + test.run();
|
| +
|
| + EXPECT_EQ(15u, test.edx() - test.ebx());
|
| +}
|
| +
|
| +TEST_F(AssemblerX8632Test, CallAddr) {
|
| + __ call(Immediate(16));
|
| + __ mov(IceType_i8, GPRRegister::Encoded_Reg_eax, Immediate(0xf4));
|
| + __ ret();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ hlt();
|
| + __ mov(IceType_i32, GPRRegister::Encoded_Reg_eax, Immediate(0xf1f2f300));
|
| + __ call(Address(GPRRegister::Encoded_Reg_esp, 0));
|
| + __ popl(GPRRegister::Encoded_Reg_edx);
|
| +
|
| + AssembledTest test = assemble();
|
| +
|
| + test.run();
|
| +
|
| + EXPECT_EQ(0xf1f2f3f4, test.eax());
|
| +}
|
| +
|
| +TEST_F(AssemblerX8632Test, Jmp) {
|
| +// TestImplReg uses jmp(Label), so jmp(Label) needs to be tested before it.
|
| +#define TestImplAddr(Near) \
|
| + do { \
|
| + Label ForwardJmp; \
|
| + Label BackwardJmp; \
|
| + Label Done; \
|
| + \
|
| + __ jmp(&ForwardJmp, AssemblerX8632::k##Near##Jump); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ bind(&BackwardJmp); \
|
| + __ jmp(&Done, AssemblerX8632::k##Near##Jump); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ bind(&ForwardJmp); \
|
| + __ jmp(&BackwardJmp, AssemblerX8632::k##NearJump); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ bind(&Done); \
|
| + } while (0)
|
| +
|
| +#define TestImplReg(Dst) \
|
| + do { \
|
| + __ call(Immediate(16)); \
|
| + Label Done; \
|
| + __ jmp(&Done, AssemblerX8632::kNearJump); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ popl(GPRRegister::Encoded_Reg_##Dst); \
|
| + __ jmp(GPRRegister::Encoded_Reg_##Dst); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ hlt(); \
|
| + __ bind(&Done); \
|
| + \
|
| + AssembledTest test = assemble(); \
|
| + test.run(); \
|
| + \
|
| + reset(); \
|
| + } while (0)
|
| +
|
| + TestImplAddr(Near);
|
| + TestImplAddr(Far);
|
| +
|
| + TestImplReg(eax);
|
| + TestImplReg(ebx);
|
| + TestImplReg(ecx);
|
| + TestImplReg(edx);
|
| + TestImplReg(esi);
|
| + TestImplReg(edi);
|
| +
|
| +#undef TestImplReg
|
| +#undef TestImplAddr
|
| +}
|
| +
|
| +} // end of anonymous namespace
|
| +} // end of namespace Test
|
| +} // end of namespace X8632
|
| +} // end of namespace Ice
|
|
|