Merge "Test assembler driver utilities."
diff --git a/compiler/utils/assembler_test.h b/compiler/utils/assembler_test.h
index ef53d72..5ab558b 100644
--- a/compiler/utils/assembler_test.h
+++ b/compiler/utils/assembler_test.h
@@ -159,7 +159,9 @@
for (auto reg2 : reg2_registers) {
for (int64_t imm : imms) {
ImmType new_imm = CreateImmediate(imm);
- (assembler_.get()->*f)(*reg1, *reg2, new_imm * multiplier + bias);
+ if (f != nullptr) {
+ (assembler_.get()->*f)(*reg1, *reg2, new_imm * multiplier + bias);
+ }
std::string base = fmt;
std::string reg1_string = (this->*GetName1)(*reg1);
@@ -213,7 +215,9 @@
for (auto reg3 : reg3_registers) {
for (int64_t imm : imms) {
ImmType new_imm = CreateImmediate(imm);
- (assembler_.get()->*f)(*reg1, *reg2, *reg3, new_imm + bias);
+ if (f != nullptr) {
+ (assembler_.get()->*f)(*reg1, *reg2, *reg3, new_imm + bias);
+ }
std::string base = fmt;
std::string reg1_string = (this->*GetName1)(*reg1);
@@ -272,7 +276,9 @@
for (auto reg2 : reg2_registers) {
for (int64_t imm : imms) {
ImmType new_imm = CreateImmediate(imm);
- (assembler_.get()->*f)(new_imm, *reg1, *reg2);
+ if (f != nullptr) {
+ (assembler_.get()->*f)(new_imm, *reg1, *reg2);
+ }
std::string base = fmt;
std::string reg1_string = (this->*GetName1)(*reg1);
@@ -320,7 +326,9 @@
for (auto reg : registers) {
for (int64_t imm : imms) {
ImmType new_imm = CreateImmediate(imm);
- (assembler_.get()->*f)(*reg, new_imm + bias);
+ if (f != nullptr) {
+ (assembler_.get()->*f)(*reg, new_imm + bias);
+ }
std::string base = fmt;
std::string reg_string = (this->*GetName)(*reg);
@@ -522,7 +530,9 @@
for (int64_t imm : imms) {
Imm new_imm = CreateImmediate(imm);
- (assembler_.get()->*f)(new_imm);
+ if (f != nullptr) {
+ (assembler_.get()->*f)(new_imm);
+ }
std::string base = fmt;
size_t imm_index = base.find(IMM_TOKEN);
@@ -835,7 +845,9 @@
const std::string& fmt) {
std::string str;
for (auto reg : registers) {
- (assembler_.get()->*f)(*reg);
+ if (f != nullptr) {
+ (assembler_.get()->*f)(*reg);
+ }
std::string base = fmt;
std::string reg_string = (this->*GetName)(*reg);
@@ -866,7 +878,9 @@
std::string str;
for (auto reg1 : reg1_registers) {
for (auto reg2 : reg2_registers) {
- (assembler_.get()->*f)(*reg1, *reg2);
+ if (f != nullptr) {
+ (assembler_.get()->*f)(*reg1, *reg2);
+ }
std::string base = fmt;
std::string reg1_string = (this->*GetName1)(*reg1);
@@ -905,7 +919,9 @@
for (auto reg1 : reg1_registers) {
for (auto reg2 : reg2_registers) {
if (reg1 == reg2) continue;
- (assembler_.get()->*f)(*reg1, *reg2);
+ if (f != nullptr) {
+ (assembler_.get()->*f)(*reg1, *reg2);
+ }
std::string base = fmt;
std::string reg1_string = (this->*GetName1)(*reg1);
@@ -944,7 +960,9 @@
for (auto reg1 : reg1_registers) {
for (auto reg2 : reg2_registers) {
for (auto reg3 : reg3_registers) {
- (assembler_.get()->*f)(*reg1, *reg2, *reg3);
+ if (f != nullptr) {
+ (assembler_.get()->*f)(*reg1, *reg2, *reg3);
+ }
std::string base = fmt;
std::string reg1_string = (this->*GetName1)(*reg1);
@@ -993,7 +1011,9 @@
for (auto reg2 : reg2_registers) {
for (int64_t imm : imms) {
Imm new_imm = CreateImmediate(imm);
- (assembler_.get()->*f)(*reg1, *reg2, new_imm);
+ if (f != nullptr) {
+ (assembler_.get()->*f)(*reg1, *reg2, new_imm);
+ }
std::string base = fmt;
std::string reg1_string = (this->*GetName1)(*reg1);
@@ -1094,7 +1114,9 @@
for (auto reg : registers) {
for (int64_t imm : imms) {
Imm new_imm = CreateImmediate(imm);
- (assembler_.get()->*f)(*reg, new_imm);
+ if (f != nullptr) {
+ (assembler_.get()->*f)(*reg, new_imm);
+ }
std::string base = fmt;
std::string reg_string = GetRegName<kRegView>(*reg);
diff --git a/compiler/utils/x86/assembler_x86_test.cc b/compiler/utils/x86/assembler_x86_test.cc
index d2122db..48e4117 100644
--- a/compiler/utils/x86/assembler_x86_test.cc
+++ b/compiler/utils/x86/assembler_x86_test.cc
@@ -33,6 +33,10 @@
ASSERT_EQ(static_cast<size_t>(5), buffer.Size());
}
+//
+// Test fixture.
+//
+
class AssemblerX86Test : public AssemblerTest<x86::X86Assembler, x86::Register,
x86::XmmRegister, x86::Immediate> {
public:
@@ -105,6 +109,56 @@
std::vector<x86::XmmRegister*> fp_registers_;
};
+//
+// Test repeat drivers used in the tests.
+//
+
+TEST_F(AssemblerX86Test, RepeatRR) {
+ EXPECT_EQ("%eax %eax\n%eax %ebx\n%eax %ecx\n%eax %edx\n%eax %ebp\n%eax %esp\n%eax %esi\n"
+ "%eax %edi\n%ebx %eax\n%ebx %ebx\n%ebx %ecx\n%ebx %edx\n%ebx %ebp\n%ebx %esp\n"
+ "%ebx %esi\n%ebx %edi\n%ecx %eax\n%ecx %ebx\n%ecx %ecx\n%ecx %edx\n%ecx %ebp\n"
+ "%ecx %esp\n%ecx %esi\n%ecx %edi\n%edx %eax\n%edx %ebx\n%edx %ecx\n%edx %edx\n"
+ "%edx %ebp\n%edx %esp\n%edx %esi\n%edx %edi\n%ebp %eax\n%ebp %ebx\n%ebp %ecx\n"
+ "%ebp %edx\n%ebp %ebp\n%ebp %esp\n%ebp %esi\n%ebp %edi\n%esp %eax\n%esp %ebx\n"
+ "%esp %ecx\n%esp %edx\n%esp %ebp\n%esp %esp\n%esp %esi\n%esp %edi\n%esi %eax\n"
+ "%esi %ebx\n%esi %ecx\n%esi %edx\n%esi %ebp\n%esi %esp\n%esi %esi\n%esi %edi\n"
+ "%edi %eax\n%edi %ebx\n%edi %ecx\n%edi %edx\n%edi %ebp\n%edi %esp\n%edi %esi\n"
+ "%edi %edi\n",
+ RepeatRR(/*f*/ nullptr, "%{reg1} %{reg2}"));
+}
+
+TEST_F(AssemblerX86Test, RepeatRI) {
+ EXPECT_EQ("%eax %0\n%eax %-1\n%eax %18\n%ebx %0\n%ebx %-1\n%ebx %18\n%ecx %0\n%ecx %-1\n"
+ "%ecx %18\n%edx %0\n%edx %-1\n%edx %18\n%ebp %0\n%ebp %-1\n%ebp %18\n%esp %0\n"
+ "%esp %-1\n%esp %18\n%esi %0\n%esi %-1\n%esi %18\n%edi %0\n%edi %-1\n%edi %18\n",
+ RepeatRI(/*f*/ nullptr, /*imm_bytes*/ 1U, "%{reg} %{imm}"));
+}
+
+TEST_F(AssemblerX86Test, RepeatFF) {
+ EXPECT_EQ("%XMM0 %XMM0\n%XMM0 %XMM1\n%XMM0 %XMM2\n%XMM0 %XMM3\n%XMM0 %XMM4\n%XMM0 %XMM5\n"
+ "%XMM0 %XMM6\n%XMM0 %XMM7\n%XMM1 %XMM0\n%XMM1 %XMM1\n%XMM1 %XMM2\n%XMM1 %XMM3\n"
+ "%XMM1 %XMM4\n%XMM1 %XMM5\n%XMM1 %XMM6\n%XMM1 %XMM7\n%XMM2 %XMM0\n%XMM2 %XMM1\n"
+ "%XMM2 %XMM2\n%XMM2 %XMM3\n%XMM2 %XMM4\n%XMM2 %XMM5\n%XMM2 %XMM6\n%XMM2 %XMM7\n"
+ "%XMM3 %XMM0\n%XMM3 %XMM1\n%XMM3 %XMM2\n%XMM3 %XMM3\n%XMM3 %XMM4\n%XMM3 %XMM5\n"
+ "%XMM3 %XMM6\n%XMM3 %XMM7\n%XMM4 %XMM0\n%XMM4 %XMM1\n%XMM4 %XMM2\n%XMM4 %XMM3\n"
+ "%XMM4 %XMM4\n%XMM4 %XMM5\n%XMM4 %XMM6\n%XMM4 %XMM7\n%XMM5 %XMM0\n%XMM5 %XMM1\n"
+ "%XMM5 %XMM2\n%XMM5 %XMM3\n%XMM5 %XMM4\n%XMM5 %XMM5\n%XMM5 %XMM6\n%XMM5 %XMM7\n"
+ "%XMM6 %XMM0\n%XMM6 %XMM1\n%XMM6 %XMM2\n%XMM6 %XMM3\n%XMM6 %XMM4\n%XMM6 %XMM5\n"
+ "%XMM6 %XMM6\n%XMM6 %XMM7\n%XMM7 %XMM0\n%XMM7 %XMM1\n%XMM7 %XMM2\n%XMM7 %XMM3\n"
+ "%XMM7 %XMM4\n%XMM7 %XMM5\n%XMM7 %XMM6\n%XMM7 %XMM7\n",
+ RepeatFF(/*f*/ nullptr, "%{reg1} %{reg2}"));
+}
+
+TEST_F(AssemblerX86Test, RepeatFFI) {
+ EXPECT_NE(RepeatFFI(/*f*/ nullptr, /*imm_bytes*/ 1U, "%{reg1} %{reg2} %{imm}")
+ .find("%XMM0 %XMM0 %0\n%XMM0 %XMM0 %-1\n%XMM0 %XMM0 %18\n"
+ "%XMM0 %XMM1 %0\n%XMM0 %XMM1 %-1\n%XMM0 %XMM1 %18\n"),
+ std::string::npos);
+}
+
+//
+// Actual x86 instruction assembler tests.
+//
TEST_F(AssemblerX86Test, Movl) {
GetAssembler()->movl(x86::EAX, x86::EBX);
@@ -838,10 +892,6 @@
DriverStr("psrldq $0x10, %xmm0\n", "psrldqi");
}
-/////////////////
-// Near labels //
-/////////////////
-
TEST_F(AssemblerX86Test, Jecxz) {
x86::NearLabel target;
GetAssembler()->jecxz(&target);
diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc
index 85afee0..29de925 100644
--- a/compiler/utils/x86_64/assembler_x86_64_test.cc
+++ b/compiler/utils/x86_64/assembler_x86_64_test.cc
@@ -126,6 +126,10 @@
}
};
+//
+// Test fixture.
+//
+
class AssemblerX86_64Test : public AssemblerTest<x86_64::X86_64Assembler, x86_64::CpuRegister,
x86_64::XmmRegister, x86_64::Immediate> {
public:
@@ -273,12 +277,130 @@
std::vector<x86_64::XmmRegister*> fp_registers_;
};
+//
+// Test repeat drivers used in the tests.
+//
+
+TEST_F(AssemblerX86_64Test, RepeatI4) {
+ EXPECT_EQ("%0\n%-1\n%18\n%4660\n%-4660\n%305419896\n%-305419896\n",
+ RepeatI(/*f*/ nullptr, /*imm_bytes*/ 4U, "%{imm}"));
+}
+
+TEST_F(AssemblerX86_64Test, RepeatI8) {
+ EXPECT_EQ("%0\n%-1\n%18\n%4660\n%-4660\n%305419896\n%-305419896\n"
+ "%20015998343868\n%-20015998343868\n%1311768467463790320\n"
+ "%-1311768467463790320\n",
+ RepeatI(/*f*/ nullptr, /*imm_bytes*/ 8U, "%{imm}"));
+}
+
+TEST_F(AssemblerX86_64Test, Repeatr) {
+ EXPECT_EQ("%eax\n%ebx\n%ecx\n%edx\n%ebp\n%esp\n%esi\n%edi\n"
+ "%r8d\n%r9d\n%r10d\n%r11d\n%r12d\n%r13d\n%r14d\n%r15d\n",
+ Repeatr(/*f*/ nullptr, "%{reg}"));
+}
+
+TEST_F(AssemblerX86_64Test, Repeatri) {
+ EXPECT_NE(Repeatri(/*f*/ nullptr, /*imm_bytes*/ 1U, "%{reg} %{imm}").
+ find("%eax %0\n%eax %-1\n%eax %18\n%ebx %0\n%ebx %-1\n%ebx %18\n"
+ "%ecx %0\n%ecx %-1\n%ecx %18\n%edx %0\n%edx %-1\n%edx %18\n"),
+ std::string::npos);
+}
+
+TEST_F(AssemblerX86_64Test, Repeatrr) {
+ EXPECT_NE(Repeatrr(/*f*/ nullptr, "%{reg1} %{reg2}")
+ .find("%eax %eax\n%eax %ebx\n%eax %ecx\n%eax %edx\n"
+ "%eax %ebp\n%eax %esp\n%eax %esi\n%eax %edi\n"),
+ std::string::npos);
+}
+
+TEST_F(AssemblerX86_64Test, Repeatrb) {
+ EXPECT_NE(Repeatrb(/*f*/ nullptr, "%{reg1} %{reg2}").
+ find("%eax %al\n%eax %bl\n%eax %cl\n%eax %dl\n%eax %bpl\n"
+ "%eax %spl\n%eax %sil\n%eax %dil\n%eax %r8b\n%eax %r9b\n"),
+ std::string::npos);
+}
+
+TEST_F(AssemblerX86_64Test, RepeatrF) {
+ EXPECT_NE(RepeatrF(/*f*/ nullptr, "%{reg1} %{reg2}")
+ .find("%eax %xmm0\n%eax %xmm1\n%eax %xmm2\n%eax %xmm3\n"
+ "%eax %xmm4\n%eax %xmm5\n%eax %xmm6\n%eax %xmm7\n"
+ "%eax %xmm8\n%eax %xmm9\n%eax %xmm10\n%eax %xmm11\n"
+ "%eax %xmm12\n%eax %xmm13\n%eax %xmm14\n%eax %xmm15\n"
+ "%ebx %xmm0\n%ebx %xmm1\n%ebx %xmm2\n%ebx %xmm3\n%ebx %xmm4\n"),
+ std::string::npos);
+}
+
+TEST_F(AssemblerX86_64Test, RepeatR) {
+ EXPECT_EQ("%rax\n%rbx\n%rcx\n%rdx\n%rbp\n%rsp\n%rsi\n%rdi\n"
+ "%r8\n%r9\n%r10\n%r11\n%r12\n%r13\n%r14\n%r15\n",
+ RepeatR(/*f*/ nullptr, "%{reg}"));
+}
+
+TEST_F(AssemblerX86_64Test, RepeatRI) {
+ EXPECT_EQ("%rax %0\n%rax %-1\n%rax %18\n%rbx %0\n%rbx %-1\n%rbx %18\n"
+ "%rcx %0\n%rcx %-1\n%rcx %18\n%rdx %0\n%rdx %-1\n%rdx %18\n"
+ "%rbp %0\n%rbp %-1\n%rbp %18\n%rsp %0\n%rsp %-1\n%rsp %18\n"
+ "%rsi %0\n%rsi %-1\n%rsi %18\n%rdi %0\n%rdi %-1\n%rdi %18\n"
+ "%r8 %0\n%r8 %-1\n%r8 %18\n%r9 %0\n%r9 %-1\n%r9 %18\n"
+ "%r10 %0\n%r10 %-1\n%r10 %18\n%r11 %0\n%r11 %-1\n%r11 %18\n"
+ "%r12 %0\n%r12 %-1\n%r12 %18\n%r13 %0\n%r13 %-1\n%r13 %18\n"
+ "%r14 %0\n%r14 %-1\n%r14 %18\n%r15 %0\n%r15 %-1\n%r15 %18\n",
+ RepeatRI(/*f*/ nullptr, /*imm_bytes*/ 1U, "%{reg} %{imm}"));
+}
+
+TEST_F(AssemblerX86_64Test, RepeatRr) {
+ EXPECT_NE(RepeatRr(/*f*/ nullptr, "%{reg1} %{reg2}")
+ .find("%rax %eax\n%rax %ebx\n%rax %ecx\n%rax %edx\n%rax %ebp\n"
+ "%rax %esp\n%rax %esi\n%rax %edi\n%rax %r8d\n%rax %r9d\n"
+ "%rax %r10d\n%rax %r11d\n%rax %r12d\n%rax %r13d\n%rax %r14d\n"
+ "%rax %r15d\n%rbx %eax\n%rbx %ebx\n%rbx %ecx\n%rbx %edx\n"),
+ std::string::npos);
+}
+
+TEST_F(AssemblerX86_64Test, RepeatRR) {
+ EXPECT_NE(RepeatRR(/*f*/ nullptr, "%{reg1} %{reg2}")
+ .find("%rax %rax\n%rax %rbx\n%rax %rcx\n%rax %rdx\n%rax %rbp\n"
+ "%rax %rsp\n%rax %rsi\n%rax %rdi\n%rax %r8\n%rax %r9\n"
+ "%rax %r10\n%rax %r11\n%rax %r12\n%rax %r13\n%rax %r14\n"
+ "%rax %r15\n%rbx %rax\n%rbx %rbx\n%rbx %rcx\n%rbx %rdx\n"),
+ std::string::npos);
+}
+
+TEST_F(AssemblerX86_64Test, RepeatRF) {
+ EXPECT_NE(RepeatRF(/*f*/ nullptr, "%{reg1} %{reg2}")
+ .find("%rax %xmm0\n%rax %xmm1\n%rax %xmm2\n%rax %xmm3\n%rax %xmm4\n"
+ "%rax %xmm5\n%rax %xmm6\n%rax %xmm7\n%rax %xmm8\n%rax %xmm9\n"
+ "%rax %xmm10\n%rax %xmm11\n%rax %xmm12\n%rax %xmm13\n%rax %xmm14\n"
+ "%rax %xmm15\n%rbx %xmm0\n%rbx %xmm1\n%rbx %xmm2\n%rbx %xmm3\n"),
+ std::string::npos);
+}
+
+TEST_F(AssemblerX86_64Test, RepeatFF) {
+ EXPECT_NE(RepeatFF(/*f*/ nullptr, "%{reg1} %{reg2}")
+ .find("%xmm0 %xmm0\n%xmm0 %xmm1\n%xmm0 %xmm2\n%xmm0 %xmm3\n%xmm0 %xmm4\n"
+ "%xmm0 %xmm5\n%xmm0 %xmm6\n%xmm0 %xmm7\n%xmm0 %xmm8\n%xmm0 %xmm9\n"
+ "%xmm0 %xmm10\n%xmm0 %xmm11\n%xmm0 %xmm12\n%xmm0 %xmm13\n%xmm0 %xmm14\n"
+ "%xmm0 %xmm15\n%xmm1 %xmm0\n%xmm1 %xmm1\n%xmm1 %xmm2\n%xmm1 %xmm3\n"),
+ std::string::npos);
+}
+
+TEST_F(AssemblerX86_64Test, RepeatFFI) {
+ EXPECT_NE(RepeatFFI(/*f*/ nullptr, /*imm_bytes*/ 1U, "%{reg1} %{reg2} %{imm}")
+ .find("%xmm0 %xmm0 %0\n%xmm0 %xmm0 %-1\n%xmm0 %xmm0 %18\n"
+ "%xmm0 %xmm1 %0\n%xmm0 %xmm1 %-1\n%xmm0 %xmm1 %18\n"
+ "%xmm0 %xmm2 %0\n%xmm0 %xmm2 %-1\n%xmm0 %xmm2 %18\n"
+ "%xmm0 %xmm3 %0\n%xmm0 %xmm3 %-1\n%xmm0 %xmm3 %18\n"),
+ std::string::npos);
+}
+
+//
+// Actual x86-64 instruction assembler tests.
+//
TEST_F(AssemblerX86_64Test, Toolchain) {
EXPECT_TRUE(CheckTools());
}
-
TEST_F(AssemblerX86_64Test, PushqRegs) {
DriverStr(RepeatR(&x86_64::X86_64Assembler::pushq, "pushq %{reg}"), "pushq");
}
@@ -978,10 +1100,6 @@
DriverStr(RepeatRr(&x86_64::X86_64Assembler::movsxd, "movsxd %{reg2}, %{reg1}"), "movsxd");
}
-///////////////////
-// FP Operations //
-///////////////////
-
TEST_F(AssemblerX86_64Test, Movaps) {
DriverStr(RepeatFF(&x86_64::X86_64Assembler::movaps, "movaps %{reg2}, %{reg1}"), "movaps");
}
@@ -1176,17 +1294,14 @@
DriverStr(RepeatFr(&x86_64::X86_64Assembler::cvtsi2sd, "cvtsi2sd %{reg2}, %{reg1}"), "cvtsi2sd");
}
-
TEST_F(AssemblerX86_64Test, Cvtss2si) {
DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvtss2si, "cvtss2si %{reg2}, %{reg1}"), "cvtss2si");
}
-
TEST_F(AssemblerX86_64Test, Cvtss2sd) {
DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtss2sd, "cvtss2sd %{reg2}, %{reg1}"), "cvtss2sd");
}
-
TEST_F(AssemblerX86_64Test, Cvtsd2si) {
DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvtsd2si, "cvtsd2si %{reg2}, %{reg1}"), "cvtsd2si");
}
@@ -1586,8 +1701,6 @@
DriverStr(expected, "ucomisd_address");
}
-// X87
-
std::string x87_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
x86_64::X86_64Assembler* assembler) {
std::ostringstream str;
@@ -1629,10 +1742,6 @@
DriverStr(expected, "FPUIntegerStore");
}
-////////////////
-// CALL / JMP //
-////////////////
-
TEST_F(AssemblerX86_64Test, Call) {
DriverStr(RepeatR(&x86_64::X86_64Assembler::call, "call *%{reg}"), "call");
}
@@ -1668,10 +1777,6 @@
DriverFn(&ret_and_leave_fn, "retleave");
}
-//////////
-// MISC //
-//////////
-
TEST_F(AssemblerX86_64Test, Bswapl) {
DriverStr(Repeatr(&x86_64::X86_64Assembler::bswapl, "bswap %{reg}"), "bswapl");
}
@@ -1824,11 +1929,6 @@
DriverStr(expected, "cmovq_address");
}
-
-/////////////////
-// Near labels //
-/////////////////
-
TEST_F(AssemblerX86_64Test, Jrcxz) {
x86_64::NearLabel target;
GetAssembler()->jrcxz(&target);