Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(767)

Unified Diff: unittest/AssemblerX8664/ControlFlow.cpp

Issue 1224173006: Adds the x86-64 assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments; make format Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « unittest/AssemblerX8632/XmmArith.cpp ('k') | unittest/AssemblerX8664/DataMov.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: unittest/AssemblerX8664/ControlFlow.cpp
diff --git a/unittest/AssemblerX8664/ControlFlow.cpp b/unittest/AssemblerX8664/ControlFlow.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..704f6fdb7d1fea6c7410c7eef5c77038d603f46e
--- /dev/null
+++ b/unittest/AssemblerX8664/ControlFlow.cpp
@@ -0,0 +1,307 @@
+//===- subzero/unittest/AssemblerX8664/ControlFlow.cpp --------------------===//
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "AssemblerX8664/TestUtil.h"
+
+namespace Ice {
+namespace X8664 {
+namespace Test {
+namespace {
+
+TEST_F(AssemblerX8664Test, J) {
+#define TestJ(C, Near, Dest, Src0, Value0, Src1, Value1) \
+ do { \
+ static constexpr char TestString[] = \
+ "(" #C ", " #Near ", " #Dest ", " #Src0 ", " #Value0 ", " #Src1 \
+ ", " #Value1 ")"; \
+ const bool NearJmp = AssemblerX8664::k##Near##Jump; \
+ Label ShouldBeTaken; \
+ __ mov(IceType_i32, Encoded_GPR_##Src0(), Immediate(Value0)); \
+ __ mov(IceType_i32, Encoded_GPR_##Src1(), Immediate(Value1)); \
+ __ mov(IceType_i32, Encoded_GPR_##Dest(), Immediate(0xBEEF)); \
+ __ cmp(IceType_i32, Encoded_GPR_##Src0(), Encoded_GPR_##Src1()); \
+ __ j(Cond::Br_##C, &ShouldBeTaken, NearJmp); \
+ __ mov(IceType_i32, Encoded_GPR_##Dest(), Immediate(0xC0FFEE)); \
+ __ bind(&ShouldBeTaken); \
+ AssembledTest test = assemble(); \
+ test.run(); \
+ ASSERT_EQ(Value0, test.Src0()) << TestString; \
+ ASSERT_EQ(Value1, test.Src1()) << TestString; \
+ ASSERT_EQ(0xBEEFul, test.Dest()) << TestString; \
+ reset(); \
+ } while (0)
+
+#define TestImpl(Dst, Src0, Src1) \
+ do { \
+ TestJ(o, Near, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(o, Far, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(no, Near, Dst, Src0, 0x1ul, Src1, 0x1ul); \
+ TestJ(no, Far, Dst, Src0, 0x1ul, Src1, 0x1ul); \
+ TestJ(b, Near, Dst, Src0, 0x1ul, Src1, 0x80000000ul); \
+ TestJ(b, Far, Dst, Src0, 0x1ul, Src1, 0x80000000ul); \
+ TestJ(ae, Near, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(ae, Far, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(e, Near, Dst, Src0, 0x80000000ul, Src1, 0x80000000ul); \
+ TestJ(e, Far, Dst, Src0, 0x80000000ul, Src1, 0x80000000ul); \
+ TestJ(ne, Near, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(ne, Far, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(be, Near, Dst, Src0, 0x1ul, Src1, 0x80000000ul); \
+ TestJ(be, Far, Dst, Src0, 0x1ul, Src1, 0x80000000ul); \
+ TestJ(a, Near, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(a, Far, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(s, Near, Dst, Src0, 0x1ul, Src1, 0x80000000ul); \
+ TestJ(s, Far, Dst, Src0, 0x1ul, Src1, 0x80000000ul); \
+ TestJ(ns, Near, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(ns, Far, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(p, Near, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(p, Far, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(np, Near, Dst, Src0, 0x1ul, Src1, 0x80000000ul); \
+ TestJ(np, Far, Dst, Src0, 0x1ul, Src1, 0x80000000ul); \
+ TestJ(l, Near, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(l, Far, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(ge, Near, Dst, Src0, 0x1ul, Src1, 0x80000000ul); \
+ TestJ(ge, Far, Dst, Src0, 0x1ul, Src1, 0x80000000ul); \
+ TestJ(le, Near, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(le, Far, Dst, Src0, 0x80000000ul, Src1, 0x1ul); \
+ TestJ(g, Near, Dst, Src0, 0x1ul, Src1, 0x80000000ul); \
+ TestJ(g, Far, Dst, Src0, 0x1ul, Src1, 0x80000000ul); \
+ } while (0)
+
+ TestImpl(r1, r2, r3);
+ TestImpl(r2, r3, r4);
+ TestImpl(r3, r4, r5);
+ TestImpl(r4, r5, r6);
+ TestImpl(r5, r6, r7);
+ TestImpl(r6, r7, r8);
+ TestImpl(r7, r8, r10);
+ TestImpl(r8, r10, r11);
+ TestImpl(r10, r11, r12);
+ TestImpl(r11, r12, r13);
+ TestImpl(r12, r13, r14);
+ TestImpl(r13, r14, r15);
+ TestImpl(r14, r15, r1);
+ TestImpl(r15, r1, r2);
+
+#undef TestImpl
+#undef TestJ
+}
+
+TEST_F(AssemblerX8664Test, 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(AssemblerX8664Test, CallReg) {
+#define TestImpl(Dst, Src) \
+ do { \
+ __ call(Immediate(16)); \
+ int CallTargetAddr = codeBytesSize() + 12; \
+ __ popl(Encoded_GPR_##Dst()); \
+ __ pushl(Encoded_GPR_##Dst()); \
+ __ ret(); \
+ for (int I = codeBytesSize(); I < CallTargetAddr; ++I) { \
+ __ hlt(); \
+ } \
+ __ popl(Encoded_GPR_##Src()); \
+ __ call(Encoded_GPR_##Src()); \
+ \
+ AssembledTest test = assemble(); \
+ \
+ test.run(); \
+ \
+ ASSERT_LE(15u, test.Dst() - test.Src()) << "(" #Dst ", " #Src ")"; \
+ reset(); \
+ } while (0)
+
+ TestImpl(r1, r2);
+ TestImpl(r2, r3);
+ TestImpl(r3, r4);
+ TestImpl(r4, r5);
+ TestImpl(r5, r6);
+ TestImpl(r6, r7);
+ TestImpl(r7, r8);
+ TestImpl(r8, r10);
+ TestImpl(r10, r11);
+ TestImpl(r11, r12);
+ TestImpl(r12, r13);
+ TestImpl(r13, r14);
+ TestImpl(r14, r15);
+ TestImpl(r15, r1);
+
+#undef TestImpl
+}
+
+TEST_F(AssemblerX8664Test, CallAddr) {
+#define TestImpl(Dst, Src) \
+ do { \
+ const uint32_t T0 = allocateQword(); \
+ const uint64_t V0 = 0xA0C0FFEEBEEFFEEFull; \
+ __ call(Immediate(16)); \
+ int CallTargetAddr = codeBytesSize() + 12; \
+ __ mov(IceType_i8, Encoded_GPR_##Dst##l(), Immediate(0xf4)); \
+ __ ret(); \
+ for (int I = codeBytesSize(); I < CallTargetAddr; ++I) { \
+ __ hlt(); \
+ } \
+ __ mov(IceType_i64, Encoded_GPR_##Dst##q(), dwordAddress(T0)); \
+ __ mov(IceType_i64, Encoded_GPR_##Src##q(), Encoded_GPR_rsp()); \
+ __ call(Address(Encoded_GPR_##Src##q(), 0)); \
+ __ popl(Encoded_GPR_##Src##q()); \
+ \
+ AssembledTest test = assemble(); \
+ test.setQwordTo(T0, V0); \
+ test.run(); \
+ \
+ ASSERT_EQ(0xA0C0FFEEBEEFFEF4ull, test.Dst##q()) << "(" #Dst ", " #Src ")"; \
+ reset(); \
+ } while (0)
+
+ TestImpl(r1, r2);
+ TestImpl(r2, r3);
+ TestImpl(r3, r4);
+ TestImpl(r4, r5);
+ TestImpl(r5, r6);
+ TestImpl(r6, r7);
+ TestImpl(r7, r8);
+ TestImpl(r8, r10);
+ TestImpl(r10, r11);
+ TestImpl(r11, r12);
+ TestImpl(r12, r13);
+ TestImpl(r13, r14);
+ TestImpl(r14, r15);
+ TestImpl(r15, r1);
+
+#undef TestImpl
+}
+
+TEST_F(AssemblerX8664Test, 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, AssemblerX8664::k##Near##Jump); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ bind(&BackwardJmp); \
+ __ jmp(&Done, AssemblerX8664::k##Near##Jump); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ bind(&ForwardJmp); \
+ __ jmp(&BackwardJmp, AssemblerX8664::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, AssemblerX8664::kNearJump); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ hlt(); \
+ __ popl(Encoded_GPR_##Dst()); \
+ __ jmp(Encoded_GPR_##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(r1);
+ TestImplReg(r2);
+ TestImplReg(r3);
+ TestImplReg(r4);
+ TestImplReg(r5);
+ TestImplReg(r6);
+ TestImplReg(r7);
+ TestImplReg(r8);
+ TestImplReg(r10);
+ TestImplReg(r11);
+ TestImplReg(r12);
+ TestImplReg(r13);
+ TestImplReg(r14);
+ TestImplReg(r15);
+
+#undef TestImplReg
+#undef TestImplAddr
+}
+
+} // end of anonymous namespace
+} // end of namespace Test
+} // end of namespace X8664
+} // end of namespace Ice
« no previous file with comments | « unittest/AssemblerX8632/XmmArith.cpp ('k') | unittest/AssemblerX8664/DataMov.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698