1 /*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "assembler_x86_64.h"
18
19 #include <inttypes.h>
20 #include <map>
21 #include <random>
22
23 #include "base/bit_utils.h"
24 #include "base/stl_util.h"
25 #include "utils/assembler_test.h"
26
27 namespace art {
28
TEST(AssemblerX86_64,CreateBuffer)29 TEST(AssemblerX86_64, CreateBuffer) {
30 AssemblerBuffer buffer;
31 AssemblerBuffer::EnsureCapacity ensured(&buffer);
32 buffer.Emit<uint8_t>(0x42);
33 ASSERT_EQ(static_cast<size_t>(1), buffer.Size());
34 buffer.Emit<int32_t>(42);
35 ASSERT_EQ(static_cast<size_t>(5), buffer.Size());
36 }
37
38 #ifdef HAVE_ANDROID_OS
39 static constexpr size_t kRandomIterations = 1000; // Devices might be puny, don't stress them...
40 #else
41 static constexpr size_t kRandomIterations = 100000; // Hosts are pretty powerful.
42 #endif
43
TEST(AssemblerX86_64,SignExtension)44 TEST(AssemblerX86_64, SignExtension) {
45 // 32bit.
46 for (int32_t i = 0; i < 128; i++) {
47 EXPECT_TRUE(IsInt<8>(i)) << i;
48 }
49 for (int32_t i = 128; i < 255; i++) {
50 EXPECT_FALSE(IsInt<8>(i)) << i;
51 }
52 // Do some higher ones randomly.
53 std::random_device rd;
54 std::default_random_engine e1(rd());
55 std::uniform_int_distribution<int32_t> uniform_dist(256, INT32_MAX);
56 for (size_t i = 0; i < kRandomIterations; i++) {
57 int32_t value = uniform_dist(e1);
58 EXPECT_FALSE(IsInt<8>(value)) << value;
59 }
60
61 // Negative ones.
62 for (int32_t i = -1; i >= -128; i--) {
63 EXPECT_TRUE(IsInt<8>(i)) << i;
64 }
65
66 for (int32_t i = -129; i > -256; i--) {
67 EXPECT_FALSE(IsInt<8>(i)) << i;
68 }
69
70 // Do some lower ones randomly.
71 std::uniform_int_distribution<int32_t> uniform_dist2(INT32_MIN, -256);
72 for (size_t i = 0; i < 100; i++) {
73 int32_t value = uniform_dist2(e1);
74 EXPECT_FALSE(IsInt<8>(value)) << value;
75 }
76
77 // 64bit.
78 for (int64_t i = 0; i < 128; i++) {
79 EXPECT_TRUE(IsInt<8>(i)) << i;
80 }
81 for (int32_t i = 128; i < 255; i++) {
82 EXPECT_FALSE(IsInt<8>(i)) << i;
83 }
84 // Do some higher ones randomly.
85 std::uniform_int_distribution<int64_t> uniform_dist3(256, INT64_MAX);
86 for (size_t i = 0; i < 100; i++) {
87 int64_t value = uniform_dist3(e1);
88 EXPECT_FALSE(IsInt<8>(value)) << value;
89 }
90
91 // Negative ones.
92 for (int64_t i = -1; i >= -128; i--) {
93 EXPECT_TRUE(IsInt<8>(i)) << i;
94 }
95
96 for (int64_t i = -129; i > -256; i--) {
97 EXPECT_FALSE(IsInt<8>(i)) << i;
98 }
99
100 // Do some lower ones randomly.
101 std::uniform_int_distribution<int64_t> uniform_dist4(INT64_MIN, -256);
102 for (size_t i = 0; i < kRandomIterations; i++) {
103 int64_t value = uniform_dist4(e1);
104 EXPECT_FALSE(IsInt<8>(value)) << value;
105 }
106
107 int64_t value = INT64_C(0x1200000010);
108 x86_64::Immediate imm(value);
109 EXPECT_FALSE(imm.is_int8());
110 EXPECT_FALSE(imm.is_int16());
111 EXPECT_FALSE(imm.is_int32());
112 value = INT64_C(0x8000000000000001);
113 x86_64::Immediate imm2(value);
114 EXPECT_FALSE(imm2.is_int8());
115 EXPECT_FALSE(imm2.is_int16());
116 EXPECT_FALSE(imm2.is_int32());
117 }
118
119 struct X86_64CpuRegisterCompare {
operator ()art::X86_64CpuRegisterCompare120 bool operator()(const x86_64::CpuRegister& a, const x86_64::CpuRegister& b) const {
121 return a.AsRegister() < b.AsRegister();
122 }
123 };
124
125 class AssemblerX86_64Test : public AssemblerTest<x86_64::X86_64Assembler, x86_64::CpuRegister,
126 x86_64::XmmRegister, x86_64::Immediate> {
127 public:
128 typedef AssemblerTest<x86_64::X86_64Assembler, x86_64::CpuRegister,
129 x86_64::XmmRegister, x86_64::Immediate> Base;
130
131 protected:
132 // Get the typically used name for this architecture, e.g., aarch64, x86-64, ...
GetArchitectureString()133 std::string GetArchitectureString() OVERRIDE {
134 return "x86_64";
135 }
136
GetDisassembleParameters()137 std::string GetDisassembleParameters() OVERRIDE {
138 return " -D -bbinary -mi386:x86-64 -Mx86-64,addr64,data32 --no-show-raw-insn";
139 }
140
SetUpHelpers()141 void SetUpHelpers() OVERRIDE {
142 if (registers_.size() == 0) {
143 registers_.push_back(new x86_64::CpuRegister(x86_64::RAX));
144 registers_.push_back(new x86_64::CpuRegister(x86_64::RBX));
145 registers_.push_back(new x86_64::CpuRegister(x86_64::RCX));
146 registers_.push_back(new x86_64::CpuRegister(x86_64::RDX));
147 registers_.push_back(new x86_64::CpuRegister(x86_64::RBP));
148 registers_.push_back(new x86_64::CpuRegister(x86_64::RSP));
149 registers_.push_back(new x86_64::CpuRegister(x86_64::RSI));
150 registers_.push_back(new x86_64::CpuRegister(x86_64::RDI));
151 registers_.push_back(new x86_64::CpuRegister(x86_64::R8));
152 registers_.push_back(new x86_64::CpuRegister(x86_64::R9));
153 registers_.push_back(new x86_64::CpuRegister(x86_64::R10));
154 registers_.push_back(new x86_64::CpuRegister(x86_64::R11));
155 registers_.push_back(new x86_64::CpuRegister(x86_64::R12));
156 registers_.push_back(new x86_64::CpuRegister(x86_64::R13));
157 registers_.push_back(new x86_64::CpuRegister(x86_64::R14));
158 registers_.push_back(new x86_64::CpuRegister(x86_64::R15));
159
160 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RAX), "eax");
161 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBX), "ebx");
162 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RCX), "ecx");
163 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDX), "edx");
164 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBP), "ebp");
165 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSP), "esp");
166 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSI), "esi");
167 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDI), "edi");
168 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R8), "r8d");
169 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R9), "r9d");
170 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R10), "r10d");
171 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R11), "r11d");
172 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R12), "r12d");
173 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R13), "r13d");
174 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R14), "r14d");
175 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R15), "r15d");
176
177 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RAX), "ax");
178 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBX), "bx");
179 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RCX), "cx");
180 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDX), "dx");
181 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBP), "bp");
182 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSP), "sp");
183 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSI), "si");
184 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDI), "di");
185 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R8), "r8w");
186 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R9), "r9w");
187 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R10), "r10w");
188 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R11), "r11w");
189 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R12), "r12w");
190 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R13), "r13w");
191 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R14), "r14w");
192 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R15), "r15w");
193
194 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RAX), "al");
195 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBX), "bl");
196 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RCX), "cl");
197 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDX), "dl");
198 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBP), "bpl");
199 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSP), "spl");
200 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSI), "sil");
201 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDI), "dil");
202 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R8), "r8b");
203 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R9), "r9b");
204 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R10), "r10b");
205 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R11), "r11b");
206 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R12), "r12b");
207 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R13), "r13b");
208 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R14), "r14b");
209 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R15), "r15b");
210
211 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM0));
212 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM1));
213 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM2));
214 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM3));
215 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM4));
216 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM5));
217 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM6));
218 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM7));
219 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM8));
220 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM9));
221 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM10));
222 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM11));
223 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM12));
224 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM13));
225 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM14));
226 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM15));
227 }
228 }
229
TearDown()230 void TearDown() OVERRIDE {
231 AssemblerTest::TearDown();
232 STLDeleteElements(®isters_);
233 STLDeleteElements(&fp_registers_);
234 }
235
GetRegisters()236 std::vector<x86_64::CpuRegister*> GetRegisters() OVERRIDE {
237 return registers_;
238 }
239
GetFPRegisters()240 std::vector<x86_64::XmmRegister*> GetFPRegisters() OVERRIDE {
241 return fp_registers_;
242 }
243
CreateImmediate(int64_t imm_value)244 x86_64::Immediate CreateImmediate(int64_t imm_value) OVERRIDE {
245 return x86_64::Immediate(imm_value);
246 }
247
GetSecondaryRegisterName(const x86_64::CpuRegister & reg)248 std::string GetSecondaryRegisterName(const x86_64::CpuRegister& reg) OVERRIDE {
249 CHECK(secondary_register_names_.find(reg) != secondary_register_names_.end());
250 return secondary_register_names_[reg];
251 }
252
GetTertiaryRegisterName(const x86_64::CpuRegister & reg)253 std::string GetTertiaryRegisterName(const x86_64::CpuRegister& reg) OVERRIDE {
254 CHECK(tertiary_register_names_.find(reg) != tertiary_register_names_.end());
255 return tertiary_register_names_[reg];
256 }
257
GetQuaternaryRegisterName(const x86_64::CpuRegister & reg)258 std::string GetQuaternaryRegisterName(const x86_64::CpuRegister& reg) OVERRIDE {
259 CHECK(quaternary_register_names_.find(reg) != quaternary_register_names_.end());
260 return quaternary_register_names_[reg];
261 }
262
263 private:
264 std::vector<x86_64::CpuRegister*> registers_;
265 std::map<x86_64::CpuRegister, std::string, X86_64CpuRegisterCompare> secondary_register_names_;
266 std::map<x86_64::CpuRegister, std::string, X86_64CpuRegisterCompare> tertiary_register_names_;
267 std::map<x86_64::CpuRegister, std::string, X86_64CpuRegisterCompare> quaternary_register_names_;
268
269 std::vector<x86_64::XmmRegister*> fp_registers_;
270 };
271
272
TEST_F(AssemblerX86_64Test,Toolchain)273 TEST_F(AssemblerX86_64Test, Toolchain) {
274 EXPECT_TRUE(CheckTools());
275 }
276
277
TEST_F(AssemblerX86_64Test,PushqRegs)278 TEST_F(AssemblerX86_64Test, PushqRegs) {
279 DriverStr(RepeatR(&x86_64::X86_64Assembler::pushq, "pushq %{reg}"), "pushq");
280 }
281
TEST_F(AssemblerX86_64Test,PushqImm)282 TEST_F(AssemblerX86_64Test, PushqImm) {
283 DriverStr(RepeatI(&x86_64::X86_64Assembler::pushq, 4U, "pushq ${imm}"), "pushqi");
284 }
285
TEST_F(AssemblerX86_64Test,MovqRegs)286 TEST_F(AssemblerX86_64Test, MovqRegs) {
287 DriverStr(RepeatRR(&x86_64::X86_64Assembler::movq, "movq %{reg2}, %{reg1}"), "movq");
288 }
289
TEST_F(AssemblerX86_64Test,MovqImm)290 TEST_F(AssemblerX86_64Test, MovqImm) {
291 DriverStr(RepeatRI(&x86_64::X86_64Assembler::movq, 8U, "movq ${imm}, %{reg}"), "movqi");
292 }
293
TEST_F(AssemblerX86_64Test,MovlRegs)294 TEST_F(AssemblerX86_64Test, MovlRegs) {
295 DriverStr(Repeatrr(&x86_64::X86_64Assembler::movl, "mov %{reg2}, %{reg1}"), "movl");
296 }
297
TEST_F(AssemblerX86_64Test,MovlImm)298 TEST_F(AssemblerX86_64Test, MovlImm) {
299 DriverStr(Repeatri(&x86_64::X86_64Assembler::movl, 4U, "mov ${imm}, %{reg}"), "movli");
300 }
301
TEST_F(AssemblerX86_64Test,AddqRegs)302 TEST_F(AssemblerX86_64Test, AddqRegs) {
303 DriverStr(RepeatRR(&x86_64::X86_64Assembler::addq, "addq %{reg2}, %{reg1}"), "addq");
304 }
305
TEST_F(AssemblerX86_64Test,AddqImm)306 TEST_F(AssemblerX86_64Test, AddqImm) {
307 DriverStr(RepeatRI(&x86_64::X86_64Assembler::addq, 4U, "addq ${imm}, %{reg}"), "addqi");
308 }
309
TEST_F(AssemblerX86_64Test,AddlRegs)310 TEST_F(AssemblerX86_64Test, AddlRegs) {
311 DriverStr(Repeatrr(&x86_64::X86_64Assembler::addl, "add %{reg2}, %{reg1}"), "addl");
312 }
313
TEST_F(AssemblerX86_64Test,AddlImm)314 TEST_F(AssemblerX86_64Test, AddlImm) {
315 DriverStr(Repeatri(&x86_64::X86_64Assembler::addl, 4U, "add ${imm}, %{reg}"), "addli");
316 }
317
TEST_F(AssemblerX86_64Test,ImulqReg1)318 TEST_F(AssemblerX86_64Test, ImulqReg1) {
319 DriverStr(RepeatR(&x86_64::X86_64Assembler::imulq, "imulq %{reg}"), "imulq");
320 }
321
TEST_F(AssemblerX86_64Test,ImulqRegs)322 TEST_F(AssemblerX86_64Test, ImulqRegs) {
323 DriverStr(RepeatRR(&x86_64::X86_64Assembler::imulq, "imulq %{reg2}, %{reg1}"), "imulq");
324 }
325
TEST_F(AssemblerX86_64Test,ImulqImm)326 TEST_F(AssemblerX86_64Test, ImulqImm) {
327 DriverStr(RepeatRI(&x86_64::X86_64Assembler::imulq, 4U, "imulq ${imm}, %{reg}, %{reg}"),
328 "imulqi");
329 }
330
TEST_F(AssemblerX86_64Test,ImullRegs)331 TEST_F(AssemblerX86_64Test, ImullRegs) {
332 DriverStr(Repeatrr(&x86_64::X86_64Assembler::imull, "imul %{reg2}, %{reg1}"), "imull");
333 }
334
TEST_F(AssemblerX86_64Test,ImullImm)335 TEST_F(AssemblerX86_64Test, ImullImm) {
336 DriverStr(Repeatri(&x86_64::X86_64Assembler::imull, 4U, "imull ${imm}, %{reg}, %{reg}"),
337 "imulli");
338 }
339
TEST_F(AssemblerX86_64Test,Mull)340 TEST_F(AssemblerX86_64Test, Mull) {
341 DriverStr(Repeatr(&x86_64::X86_64Assembler::mull, "mull %{reg}"), "mull");
342 }
343
TEST_F(AssemblerX86_64Test,SubqRegs)344 TEST_F(AssemblerX86_64Test, SubqRegs) {
345 DriverStr(RepeatRR(&x86_64::X86_64Assembler::subq, "subq %{reg2}, %{reg1}"), "subq");
346 }
347
TEST_F(AssemblerX86_64Test,SubqImm)348 TEST_F(AssemblerX86_64Test, SubqImm) {
349 DriverStr(RepeatRI(&x86_64::X86_64Assembler::subq, 4U, "subq ${imm}, %{reg}"), "subqi");
350 }
351
TEST_F(AssemblerX86_64Test,SublRegs)352 TEST_F(AssemblerX86_64Test, SublRegs) {
353 DriverStr(Repeatrr(&x86_64::X86_64Assembler::subl, "sub %{reg2}, %{reg1}"), "subl");
354 }
355
TEST_F(AssemblerX86_64Test,SublImm)356 TEST_F(AssemblerX86_64Test, SublImm) {
357 DriverStr(Repeatri(&x86_64::X86_64Assembler::subl, 4U, "sub ${imm}, %{reg}"), "subli");
358 }
359
360 // Shll only allows CL as the shift count.
shll_fn(AssemblerX86_64Test::Base * assembler_test,x86_64::X86_64Assembler * assembler)361 std::string shll_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
362 std::ostringstream str;
363
364 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
365
366 x86_64::CpuRegister shifter(x86_64::RCX);
367 for (auto reg : registers) {
368 assembler->shll(*reg, shifter);
369 str << "shll %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n";
370 }
371
372 return str.str();
373 }
374
TEST_F(AssemblerX86_64Test,ShllReg)375 TEST_F(AssemblerX86_64Test, ShllReg) {
376 DriverFn(&shll_fn, "shll");
377 }
378
TEST_F(AssemblerX86_64Test,ShllImm)379 TEST_F(AssemblerX86_64Test, ShllImm) {
380 DriverStr(Repeatri(&x86_64::X86_64Assembler::shll, 1U, "shll ${imm}, %{reg}"), "shlli");
381 }
382
383 // Shlq only allows CL as the shift count.
shlq_fn(AssemblerX86_64Test::Base * assembler_test,x86_64::X86_64Assembler * assembler)384 std::string shlq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
385 std::ostringstream str;
386
387 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
388
389 x86_64::CpuRegister shifter(x86_64::RCX);
390 for (auto reg : registers) {
391 assembler->shlq(*reg, shifter);
392 str << "shlq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n";
393 }
394
395 return str.str();
396 }
397
TEST_F(AssemblerX86_64Test,ShlqReg)398 TEST_F(AssemblerX86_64Test, ShlqReg) {
399 DriverFn(&shlq_fn, "shlq");
400 }
401
TEST_F(AssemblerX86_64Test,ShlqImm)402 TEST_F(AssemblerX86_64Test, ShlqImm) {
403 DriverStr(RepeatRI(&x86_64::X86_64Assembler::shlq, 1U, "shlq ${imm}, %{reg}"), "shlqi");
404 }
405
406 // Shrl only allows CL as the shift count.
shrl_fn(AssemblerX86_64Test::Base * assembler_test,x86_64::X86_64Assembler * assembler)407 std::string shrl_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
408 std::ostringstream str;
409
410 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
411
412 x86_64::CpuRegister shifter(x86_64::RCX);
413 for (auto reg : registers) {
414 assembler->shrl(*reg, shifter);
415 str << "shrl %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n";
416 }
417
418 return str.str();
419 }
420
TEST_F(AssemblerX86_64Test,ShrlReg)421 TEST_F(AssemblerX86_64Test, ShrlReg) {
422 DriverFn(&shrl_fn, "shrl");
423 }
424
TEST_F(AssemblerX86_64Test,ShrlImm)425 TEST_F(AssemblerX86_64Test, ShrlImm) {
426 DriverStr(Repeatri(&x86_64::X86_64Assembler::shrl, 1U, "shrl ${imm}, %{reg}"), "shrli");
427 }
428
429 // Shrq only allows CL as the shift count.
shrq_fn(AssemblerX86_64Test::Base * assembler_test,x86_64::X86_64Assembler * assembler)430 std::string shrq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
431 std::ostringstream str;
432
433 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
434
435 x86_64::CpuRegister shifter(x86_64::RCX);
436 for (auto reg : registers) {
437 assembler->shrq(*reg, shifter);
438 str << "shrq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n";
439 }
440
441 return str.str();
442 }
443
TEST_F(AssemblerX86_64Test,ShrqReg)444 TEST_F(AssemblerX86_64Test, ShrqReg) {
445 DriverFn(&shrq_fn, "shrq");
446 }
447
TEST_F(AssemblerX86_64Test,ShrqImm)448 TEST_F(AssemblerX86_64Test, ShrqImm) {
449 DriverStr(RepeatRI(&x86_64::X86_64Assembler::shrq, 1U, "shrq ${imm}, %{reg}"), "shrqi");
450 }
451
452 // Sarl only allows CL as the shift count.
sarl_fn(AssemblerX86_64Test::Base * assembler_test,x86_64::X86_64Assembler * assembler)453 std::string sarl_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
454 std::ostringstream str;
455
456 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
457
458 x86_64::CpuRegister shifter(x86_64::RCX);
459 for (auto reg : registers) {
460 assembler->sarl(*reg, shifter);
461 str << "sarl %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n";
462 }
463
464 return str.str();
465 }
466
TEST_F(AssemblerX86_64Test,SarlReg)467 TEST_F(AssemblerX86_64Test, SarlReg) {
468 DriverFn(&sarl_fn, "sarl");
469 }
470
TEST_F(AssemblerX86_64Test,SarlImm)471 TEST_F(AssemblerX86_64Test, SarlImm) {
472 DriverStr(Repeatri(&x86_64::X86_64Assembler::sarl, 1U, "sarl ${imm}, %{reg}"), "sarli");
473 }
474
475 // Sarq only allows CL as the shift count.
sarq_fn(AssemblerX86_64Test::Base * assembler_test,x86_64::X86_64Assembler * assembler)476 std::string sarq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
477 std::ostringstream str;
478
479 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
480
481 x86_64::CpuRegister shifter(x86_64::RCX);
482 for (auto reg : registers) {
483 assembler->sarq(*reg, shifter);
484 str << "sarq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n";
485 }
486
487 return str.str();
488 }
489
TEST_F(AssemblerX86_64Test,SarqReg)490 TEST_F(AssemblerX86_64Test, SarqReg) {
491 DriverFn(&sarq_fn, "sarq");
492 }
493
TEST_F(AssemblerX86_64Test,SarqImm)494 TEST_F(AssemblerX86_64Test, SarqImm) {
495 DriverStr(RepeatRI(&x86_64::X86_64Assembler::sarq, 1U, "sarq ${imm}, %{reg}"), "sarqi");
496 }
497
TEST_F(AssemblerX86_64Test,CmpqRegs)498 TEST_F(AssemblerX86_64Test, CmpqRegs) {
499 DriverStr(RepeatRR(&x86_64::X86_64Assembler::cmpq, "cmpq %{reg2}, %{reg1}"), "cmpq");
500 }
501
TEST_F(AssemblerX86_64Test,CmpqImm)502 TEST_F(AssemblerX86_64Test, CmpqImm) {
503 DriverStr(RepeatRI(&x86_64::X86_64Assembler::cmpq, 4U /* cmpq only supports 32b imm */,
504 "cmpq ${imm}, %{reg}"), "cmpqi");
505 }
506
TEST_F(AssemblerX86_64Test,CmplRegs)507 TEST_F(AssemblerX86_64Test, CmplRegs) {
508 DriverStr(Repeatrr(&x86_64::X86_64Assembler::cmpl, "cmp %{reg2}, %{reg1}"), "cmpl");
509 }
510
TEST_F(AssemblerX86_64Test,CmplImm)511 TEST_F(AssemblerX86_64Test, CmplImm) {
512 DriverStr(Repeatri(&x86_64::X86_64Assembler::cmpl, 4U, "cmpl ${imm}, %{reg}"), "cmpli");
513 }
514
TEST_F(AssemblerX86_64Test,Testl)515 TEST_F(AssemblerX86_64Test, Testl) {
516 // Note: uses different order for GCC than usual. This makes GCC happy, and doesn't have an
517 // impact on functional correctness.
518 DriverStr(Repeatrr(&x86_64::X86_64Assembler::testl, "testl %{reg1}, %{reg2}"), "testl");
519 }
520
TEST_F(AssemblerX86_64Test,Negq)521 TEST_F(AssemblerX86_64Test, Negq) {
522 DriverStr(RepeatR(&x86_64::X86_64Assembler::negq, "negq %{reg}"), "negq");
523 }
524
TEST_F(AssemblerX86_64Test,Negl)525 TEST_F(AssemblerX86_64Test, Negl) {
526 DriverStr(Repeatr(&x86_64::X86_64Assembler::negl, "negl %{reg}"), "negl");
527 }
528
TEST_F(AssemblerX86_64Test,Notq)529 TEST_F(AssemblerX86_64Test, Notq) {
530 DriverStr(RepeatR(&x86_64::X86_64Assembler::notq, "notq %{reg}"), "notq");
531 }
532
TEST_F(AssemblerX86_64Test,Notl)533 TEST_F(AssemblerX86_64Test, Notl) {
534 DriverStr(Repeatr(&x86_64::X86_64Assembler::notl, "notl %{reg}"), "notl");
535 }
536
TEST_F(AssemblerX86_64Test,AndqRegs)537 TEST_F(AssemblerX86_64Test, AndqRegs) {
538 DriverStr(RepeatRR(&x86_64::X86_64Assembler::andq, "andq %{reg2}, %{reg1}"), "andq");
539 }
540
TEST_F(AssemblerX86_64Test,AndqImm)541 TEST_F(AssemblerX86_64Test, AndqImm) {
542 DriverStr(RepeatRI(&x86_64::X86_64Assembler::andq, 4U /* andq only supports 32b imm */,
543 "andq ${imm}, %{reg}"), "andqi");
544 }
545
TEST_F(AssemblerX86_64Test,AndlRegs)546 TEST_F(AssemblerX86_64Test, AndlRegs) {
547 DriverStr(Repeatrr(&x86_64::X86_64Assembler::andl, "andl %{reg2}, %{reg1}"), "andl");
548 }
549
TEST_F(AssemblerX86_64Test,AndlImm)550 TEST_F(AssemblerX86_64Test, AndlImm) {
551 DriverStr(Repeatri(&x86_64::X86_64Assembler::andl, 4U, "andl ${imm}, %{reg}"), "andli");
552 }
553
TEST_F(AssemblerX86_64Test,OrqRegs)554 TEST_F(AssemblerX86_64Test, OrqRegs) {
555 DriverStr(RepeatRR(&x86_64::X86_64Assembler::orq, "orq %{reg2}, %{reg1}"), "orq");
556 }
557
TEST_F(AssemblerX86_64Test,OrlRegs)558 TEST_F(AssemblerX86_64Test, OrlRegs) {
559 DriverStr(Repeatrr(&x86_64::X86_64Assembler::orl, "orl %{reg2}, %{reg1}"), "orl");
560 }
561
TEST_F(AssemblerX86_64Test,OrlImm)562 TEST_F(AssemblerX86_64Test, OrlImm) {
563 DriverStr(Repeatri(&x86_64::X86_64Assembler::orl, 4U, "orl ${imm}, %{reg}"), "orli");
564 }
565
TEST_F(AssemblerX86_64Test,XorqRegs)566 TEST_F(AssemblerX86_64Test, XorqRegs) {
567 DriverStr(RepeatRR(&x86_64::X86_64Assembler::xorq, "xorq %{reg2}, %{reg1}"), "xorq");
568 }
569
TEST_F(AssemblerX86_64Test,XorqImm)570 TEST_F(AssemblerX86_64Test, XorqImm) {
571 DriverStr(RepeatRI(&x86_64::X86_64Assembler::xorq, 4U, "xorq ${imm}, %{reg}"), "xorqi");
572 }
573
TEST_F(AssemblerX86_64Test,XorlRegs)574 TEST_F(AssemblerX86_64Test, XorlRegs) {
575 DriverStr(Repeatrr(&x86_64::X86_64Assembler::xorl, "xor %{reg2}, %{reg1}"), "xorl");
576 }
577
TEST_F(AssemblerX86_64Test,XorlImm)578 TEST_F(AssemblerX86_64Test, XorlImm) {
579 DriverStr(Repeatri(&x86_64::X86_64Assembler::xorl, 4U, "xor ${imm}, %{reg}"), "xorli");
580 }
581
TEST_F(AssemblerX86_64Test,Xchgq)582 TEST_F(AssemblerX86_64Test, Xchgq) {
583 DriverStr(RepeatRR(&x86_64::X86_64Assembler::xchgq, "xchgq %{reg2}, %{reg1}"), "xchgq");
584 }
585
TEST_F(AssemblerX86_64Test,Xchgl)586 TEST_F(AssemblerX86_64Test, Xchgl) {
587 // Test is disabled because GCC generates 0x87 0xC0 for xchgl eax, eax. All other cases are the
588 // same. Anyone know why it doesn't emit a simple 0x90? It does so for xchgq rax, rax...
589 // DriverStr(Repeatrr(&x86_64::X86_64Assembler::xchgl, "xchgl %{reg2}, %{reg1}"), "xchgl");
590 }
591
TEST_F(AssemblerX86_64Test,LockCmpxchgl)592 TEST_F(AssemblerX86_64Test, LockCmpxchgl) {
593 GetAssembler()->LockCmpxchgl(x86_64::Address(
594 x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12),
595 x86_64::CpuRegister(x86_64::RSI));
596 GetAssembler()->LockCmpxchgl(x86_64::Address(
597 x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12),
598 x86_64::CpuRegister(x86_64::RSI));
599 GetAssembler()->LockCmpxchgl(x86_64::Address(
600 x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12),
601 x86_64::CpuRegister(x86_64::R8));
602 GetAssembler()->LockCmpxchgl(x86_64::Address(
603 x86_64::CpuRegister(x86_64::R13), 0), x86_64::CpuRegister(x86_64::RSI));
604 GetAssembler()->LockCmpxchgl(x86_64::Address(
605 x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0),
606 x86_64::CpuRegister(x86_64::RSI));
607 const char* expected =
608 "lock cmpxchgl %ESI, 0xc(%RDI,%RBX,4)\n"
609 "lock cmpxchgl %ESI, 0xc(%RDI,%R9,4)\n"
610 "lock cmpxchgl %R8d, 0xc(%RDI,%R9,4)\n"
611 "lock cmpxchgl %ESI, (%R13)\n"
612 "lock cmpxchgl %ESI, (%R13,%R9,1)\n";
613
614 DriverStr(expected, "lock_cmpxchgl");
615 }
616
TEST_F(AssemblerX86_64Test,LockCmpxchgq)617 TEST_F(AssemblerX86_64Test, LockCmpxchgq) {
618 GetAssembler()->LockCmpxchgq(x86_64::Address(
619 x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12),
620 x86_64::CpuRegister(x86_64::RSI));
621 GetAssembler()->LockCmpxchgq(x86_64::Address(
622 x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12),
623 x86_64::CpuRegister(x86_64::RSI));
624 GetAssembler()->LockCmpxchgq(x86_64::Address(
625 x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12),
626 x86_64::CpuRegister(x86_64::R8));
627 GetAssembler()->LockCmpxchgq(x86_64::Address(
628 x86_64::CpuRegister(x86_64::R13), 0), x86_64::CpuRegister(x86_64::RSI));
629 GetAssembler()->LockCmpxchgq(x86_64::Address(
630 x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0),
631 x86_64::CpuRegister(x86_64::RSI));
632 const char* expected =
633 "lock cmpxchg %RSI, 0xc(%RDI,%RBX,4)\n"
634 "lock cmpxchg %RSI, 0xc(%RDI,%R9,4)\n"
635 "lock cmpxchg %R8, 0xc(%RDI,%R9,4)\n"
636 "lock cmpxchg %RSI, (%R13)\n"
637 "lock cmpxchg %RSI, (%R13,%R9,1)\n";
638
639 DriverStr(expected, "lock_cmpxchg");
640 }
641
TEST_F(AssemblerX86_64Test,Movl)642 TEST_F(AssemblerX86_64Test, Movl) {
643 GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address(
644 x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
645 GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address(
646 x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
647 GetAssembler()->movl(x86_64::CpuRegister(x86_64::R8), x86_64::Address(
648 x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
649 GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address(
650 x86_64::CpuRegister(x86_64::R13), 0));
651 GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address(
652 x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0));
653 const char* expected =
654 "movl 0xc(%RDI,%RBX,4), %EAX\n"
655 "movl 0xc(%RDI,%R9,4), %EAX\n"
656 "movl 0xc(%RDI,%R9,4), %R8d\n"
657 "movl (%R13), %EAX\n"
658 "movl (%R13,%R9,1), %EAX\n";
659
660 DriverStr(expected, "movl");
661 }
662
TEST_F(AssemblerX86_64Test,Movw)663 TEST_F(AssemblerX86_64Test, Movw) {
664 GetAssembler()->movw(x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
665 x86_64::CpuRegister(x86_64::R9));
666 const char* expected = "movw %R9w, 0(%RAX)\n";
667 DriverStr(expected, "movw");
668 }
669
TEST_F(AssemblerX86_64Test,MovqAddrImm)670 TEST_F(AssemblerX86_64Test, MovqAddrImm) {
671 GetAssembler()->movq(x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
672 x86_64::Immediate(-5));
673 const char* expected = "movq $-5, 0(%RAX)\n";
674 DriverStr(expected, "movq");
675 }
676
TEST_F(AssemblerX86_64Test,Cvtsi2ssAddr)677 TEST_F(AssemblerX86_64Test, Cvtsi2ssAddr) {
678 GetAssembler()->cvtsi2ss(x86_64::XmmRegister(x86_64::XMM0),
679 x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
680 false);
681 GetAssembler()->cvtsi2ss(x86_64::XmmRegister(x86_64::XMM0),
682 x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
683 true);
684 const char* expected = "cvtsi2ss 0(%RAX), %xmm0\n"
685 "cvtsi2ssq 0(%RAX), %xmm0\n";
686 DriverStr(expected, "cvtsi2ss");
687 }
688
TEST_F(AssemblerX86_64Test,Cvtsi2sdAddr)689 TEST_F(AssemblerX86_64Test, Cvtsi2sdAddr) {
690 GetAssembler()->cvtsi2sd(x86_64::XmmRegister(x86_64::XMM0),
691 x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
692 false);
693 GetAssembler()->cvtsi2sd(x86_64::XmmRegister(x86_64::XMM0),
694 x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
695 true);
696 const char* expected = "cvtsi2sd 0(%RAX), %xmm0\n"
697 "cvtsi2sdq 0(%RAX), %xmm0\n";
698 DriverStr(expected, "cvtsi2sd");
699 }
700
TEST_F(AssemblerX86_64Test,CmpqAddr)701 TEST_F(AssemblerX86_64Test, CmpqAddr) {
702 GetAssembler()->cmpq(x86_64::CpuRegister(x86_64::R12),
703 x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0));
704 const char* expected = "cmpq 0(%R9), %R12\n";
705 DriverStr(expected, "cmpq");
706 }
707
TEST_F(AssemblerX86_64Test,MovsxdAddr)708 TEST_F(AssemblerX86_64Test, MovsxdAddr) {
709 GetAssembler()->movsxd(x86_64::CpuRegister(x86_64::R12),
710 x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0));
711 const char* expected = "movslq 0(%R9), %R12\n";
712 DriverStr(expected, "movsxd");
713 }
714
TEST_F(AssemblerX86_64Test,TestqAddr)715 TEST_F(AssemblerX86_64Test, TestqAddr) {
716 GetAssembler()->testq(x86_64::CpuRegister(x86_64::R12),
717 x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0));
718 const char* expected = "testq 0(%R9), %R12\n";
719 DriverStr(expected, "testq");
720 }
721
TEST_F(AssemblerX86_64Test,AddqAddr)722 TEST_F(AssemblerX86_64Test, AddqAddr) {
723 GetAssembler()->addq(x86_64::CpuRegister(x86_64::R12),
724 x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0));
725 const char* expected = "addq 0(%R9), %R12\n";
726 DriverStr(expected, "addq");
727 }
728
TEST_F(AssemblerX86_64Test,SubqAddr)729 TEST_F(AssemblerX86_64Test, SubqAddr) {
730 GetAssembler()->subq(x86_64::CpuRegister(x86_64::R12),
731 x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0));
732 const char* expected = "subq 0(%R9), %R12\n";
733 DriverStr(expected, "subq");
734 }
735
TEST_F(AssemblerX86_64Test,Cvtss2sdAddr)736 TEST_F(AssemblerX86_64Test, Cvtss2sdAddr) {
737 GetAssembler()->cvtss2sd(x86_64::XmmRegister(x86_64::XMM0),
738 x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
739 const char* expected = "cvtss2sd 0(%RAX), %xmm0\n";
740 DriverStr(expected, "cvtss2sd");
741 }
742
TEST_F(AssemblerX86_64Test,Cvtsd2ssAddr)743 TEST_F(AssemblerX86_64Test, Cvtsd2ssAddr) {
744 GetAssembler()->cvtsd2ss(x86_64::XmmRegister(x86_64::XMM0),
745 x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
746 const char* expected = "cvtsd2ss 0(%RAX), %xmm0\n";
747 DriverStr(expected, "cvtsd2ss");
748 }
749
TEST_F(AssemblerX86_64Test,ComissAddr)750 TEST_F(AssemblerX86_64Test, ComissAddr) {
751 GetAssembler()->comiss(x86_64::XmmRegister(x86_64::XMM14),
752 x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
753 const char* expected = "comiss 0(%RAX), %xmm14\n";
754 DriverStr(expected, "comiss");
755 }
756
TEST_F(AssemblerX86_64Test,ComisdAddr)757 TEST_F(AssemblerX86_64Test, ComisdAddr) {
758 GetAssembler()->comisd(x86_64::XmmRegister(x86_64::XMM0),
759 x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0));
760 const char* expected = "comisd 0(%R9), %xmm0\n";
761 DriverStr(expected, "comisd");
762 }
763
TEST_F(AssemblerX86_64Test,UComissAddr)764 TEST_F(AssemblerX86_64Test, UComissAddr) {
765 GetAssembler()->ucomiss(x86_64::XmmRegister(x86_64::XMM0),
766 x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
767 const char* expected = "ucomiss 0(%RAX), %xmm0\n";
768 DriverStr(expected, "ucomiss");
769 }
770
TEST_F(AssemblerX86_64Test,UComisdAddr)771 TEST_F(AssemblerX86_64Test, UComisdAddr) {
772 GetAssembler()->ucomisd(x86_64::XmmRegister(x86_64::XMM0),
773 x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
774 const char* expected = "ucomisd 0(%RAX), %xmm0\n";
775 DriverStr(expected, "ucomisd");
776 }
777
TEST_F(AssemblerX86_64Test,Andq)778 TEST_F(AssemblerX86_64Test, Andq) {
779 GetAssembler()->andq(x86_64::CpuRegister(x86_64::R9),
780 x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
781 const char* expected = "andq 0(%RAX), %r9\n";
782 DriverStr(expected, "andq");
783 }
784
TEST_F(AssemblerX86_64Test,Orq)785 TEST_F(AssemblerX86_64Test, Orq) {
786 GetAssembler()->orq(x86_64::CpuRegister(x86_64::R9),
787 x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
788 const char* expected = "orq 0(%RAX), %r9\n";
789 DriverStr(expected, "orq");
790 }
791
TEST_F(AssemblerX86_64Test,Xorq)792 TEST_F(AssemblerX86_64Test, Xorq) {
793 GetAssembler()->xorq(x86_64::CpuRegister(x86_64::R9),
794 x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
795 const char* expected = "xorq 0(%RAX), %r9\n";
796 DriverStr(expected, "xorq");
797 }
798
TEST_F(AssemblerX86_64Test,Movsxd)799 TEST_F(AssemblerX86_64Test, Movsxd) {
800 DriverStr(RepeatRr(&x86_64::X86_64Assembler::movsxd, "movsxd %{reg2}, %{reg1}"), "movsxd");
801 }
802
803 ///////////////////
804 // FP Operations //
805 ///////////////////
806
TEST_F(AssemblerX86_64Test,Movaps)807 TEST_F(AssemblerX86_64Test, Movaps) {
808 DriverStr(RepeatFF(&x86_64::X86_64Assembler::movaps, "movaps %{reg2}, %{reg1}"), "movaps");
809 }
810
TEST_F(AssemblerX86_64Test,Movss)811 TEST_F(AssemblerX86_64Test, Movss) {
812 DriverStr(RepeatFF(&x86_64::X86_64Assembler::movss, "movss %{reg2}, %{reg1}"), "movss");
813 }
814
TEST_F(AssemblerX86_64Test,Movsd)815 TEST_F(AssemblerX86_64Test, Movsd) {
816 DriverStr(RepeatFF(&x86_64::X86_64Assembler::movsd, "movsd %{reg2}, %{reg1}"), "movsd");
817 }
818
TEST_F(AssemblerX86_64Test,Movd1)819 TEST_F(AssemblerX86_64Test, Movd1) {
820 DriverStr(RepeatFR(&x86_64::X86_64Assembler::movd, "movd %{reg2}, %{reg1}"), "movd.1");
821 }
822
TEST_F(AssemblerX86_64Test,Movd2)823 TEST_F(AssemblerX86_64Test, Movd2) {
824 DriverStr(RepeatRF(&x86_64::X86_64Assembler::movd, "movd %{reg2}, %{reg1}"), "movd.2");
825 }
826
TEST_F(AssemblerX86_64Test,Addss)827 TEST_F(AssemblerX86_64Test, Addss) {
828 DriverStr(RepeatFF(&x86_64::X86_64Assembler::addss, "addss %{reg2}, %{reg1}"), "addss");
829 }
830
TEST_F(AssemblerX86_64Test,Addsd)831 TEST_F(AssemblerX86_64Test, Addsd) {
832 DriverStr(RepeatFF(&x86_64::X86_64Assembler::addsd, "addsd %{reg2}, %{reg1}"), "addsd");
833 }
834
TEST_F(AssemblerX86_64Test,Subss)835 TEST_F(AssemblerX86_64Test, Subss) {
836 DriverStr(RepeatFF(&x86_64::X86_64Assembler::subss, "subss %{reg2}, %{reg1}"), "subss");
837 }
838
TEST_F(AssemblerX86_64Test,Subsd)839 TEST_F(AssemblerX86_64Test, Subsd) {
840 DriverStr(RepeatFF(&x86_64::X86_64Assembler::subsd, "subsd %{reg2}, %{reg1}"), "subsd");
841 }
842
TEST_F(AssemblerX86_64Test,Mulss)843 TEST_F(AssemblerX86_64Test, Mulss) {
844 DriverStr(RepeatFF(&x86_64::X86_64Assembler::mulss, "mulss %{reg2}, %{reg1}"), "mulss");
845 }
846
TEST_F(AssemblerX86_64Test,Mulsd)847 TEST_F(AssemblerX86_64Test, Mulsd) {
848 DriverStr(RepeatFF(&x86_64::X86_64Assembler::mulsd, "mulsd %{reg2}, %{reg1}"), "mulsd");
849 }
850
TEST_F(AssemblerX86_64Test,Divss)851 TEST_F(AssemblerX86_64Test, Divss) {
852 DriverStr(RepeatFF(&x86_64::X86_64Assembler::divss, "divss %{reg2}, %{reg1}"), "divss");
853 }
854
TEST_F(AssemblerX86_64Test,Divsd)855 TEST_F(AssemblerX86_64Test, Divsd) {
856 DriverStr(RepeatFF(&x86_64::X86_64Assembler::divsd, "divsd %{reg2}, %{reg1}"), "divsd");
857 }
858
TEST_F(AssemblerX86_64Test,Cvtsi2ss)859 TEST_F(AssemblerX86_64Test, Cvtsi2ss) {
860 DriverStr(RepeatFr(&x86_64::X86_64Assembler::cvtsi2ss, "cvtsi2ss %{reg2}, %{reg1}"), "cvtsi2ss");
861 }
862
TEST_F(AssemblerX86_64Test,Cvtsi2sd)863 TEST_F(AssemblerX86_64Test, Cvtsi2sd) {
864 DriverStr(RepeatFr(&x86_64::X86_64Assembler::cvtsi2sd, "cvtsi2sd %{reg2}, %{reg1}"), "cvtsi2sd");
865 }
866
867
TEST_F(AssemblerX86_64Test,Cvtss2si)868 TEST_F(AssemblerX86_64Test, Cvtss2si) {
869 DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvtss2si, "cvtss2si %{reg2}, %{reg1}"), "cvtss2si");
870 }
871
872
TEST_F(AssemblerX86_64Test,Cvtss2sd)873 TEST_F(AssemblerX86_64Test, Cvtss2sd) {
874 DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtss2sd, "cvtss2sd %{reg2}, %{reg1}"), "cvtss2sd");
875 }
876
877
TEST_F(AssemblerX86_64Test,Cvtsd2si)878 TEST_F(AssemblerX86_64Test, Cvtsd2si) {
879 DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvtsd2si, "cvtsd2si %{reg2}, %{reg1}"), "cvtsd2si");
880 }
881
TEST_F(AssemblerX86_64Test,Cvttss2si)882 TEST_F(AssemblerX86_64Test, Cvttss2si) {
883 DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvttss2si, "cvttss2si %{reg2}, %{reg1}"),
884 "cvttss2si");
885 }
886
TEST_F(AssemblerX86_64Test,Cvttsd2si)887 TEST_F(AssemblerX86_64Test, Cvttsd2si) {
888 DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvttsd2si, "cvttsd2si %{reg2}, %{reg1}"),
889 "cvttsd2si");
890 }
891
TEST_F(AssemblerX86_64Test,Cvtsd2ss)892 TEST_F(AssemblerX86_64Test, Cvtsd2ss) {
893 DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtsd2ss, "cvtsd2ss %{reg2}, %{reg1}"), "cvtsd2ss");
894 }
895
TEST_F(AssemblerX86_64Test,Cvtdq2pd)896 TEST_F(AssemblerX86_64Test, Cvtdq2pd) {
897 DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtdq2pd, "cvtdq2pd %{reg2}, %{reg1}"), "cvtdq2pd");
898 }
899
TEST_F(AssemblerX86_64Test,Comiss)900 TEST_F(AssemblerX86_64Test, Comiss) {
901 DriverStr(RepeatFF(&x86_64::X86_64Assembler::comiss, "comiss %{reg2}, %{reg1}"), "comiss");
902 }
903
TEST_F(AssemblerX86_64Test,Comisd)904 TEST_F(AssemblerX86_64Test, Comisd) {
905 DriverStr(RepeatFF(&x86_64::X86_64Assembler::comisd, "comisd %{reg2}, %{reg1}"), "comisd");
906 }
907
TEST_F(AssemblerX86_64Test,Ucomiss)908 TEST_F(AssemblerX86_64Test, Ucomiss) {
909 DriverStr(RepeatFF(&x86_64::X86_64Assembler::ucomiss, "ucomiss %{reg2}, %{reg1}"), "ucomiss");
910 }
911
TEST_F(AssemblerX86_64Test,Ucomisd)912 TEST_F(AssemblerX86_64Test, Ucomisd) {
913 DriverStr(RepeatFF(&x86_64::X86_64Assembler::ucomisd, "ucomisd %{reg2}, %{reg1}"), "ucomisd");
914 }
915
TEST_F(AssemblerX86_64Test,Sqrtss)916 TEST_F(AssemblerX86_64Test, Sqrtss) {
917 DriverStr(RepeatFF(&x86_64::X86_64Assembler::sqrtss, "sqrtss %{reg2}, %{reg1}"), "sqrtss");
918 }
919
TEST_F(AssemblerX86_64Test,Sqrtsd)920 TEST_F(AssemblerX86_64Test, Sqrtsd) {
921 DriverStr(RepeatFF(&x86_64::X86_64Assembler::sqrtsd, "sqrtsd %{reg2}, %{reg1}"), "sqrtsd");
922 }
923
TEST_F(AssemblerX86_64Test,Roundss)924 TEST_F(AssemblerX86_64Test, Roundss) {
925 DriverStr(RepeatFFI(&x86_64::X86_64Assembler::roundss, 1, "roundss ${imm}, %{reg2}, %{reg1}"), "roundss");
926 }
927
TEST_F(AssemblerX86_64Test,Roundsd)928 TEST_F(AssemblerX86_64Test, Roundsd) {
929 DriverStr(RepeatFFI(&x86_64::X86_64Assembler::roundsd, 1, "roundsd ${imm}, %{reg2}, %{reg1}"), "roundsd");
930 }
931
TEST_F(AssemblerX86_64Test,Xorps)932 TEST_F(AssemblerX86_64Test, Xorps) {
933 DriverStr(RepeatFF(&x86_64::X86_64Assembler::xorps, "xorps %{reg2}, %{reg1}"), "xorps");
934 }
935
TEST_F(AssemblerX86_64Test,Xorpd)936 TEST_F(AssemblerX86_64Test, Xorpd) {
937 DriverStr(RepeatFF(&x86_64::X86_64Assembler::xorpd, "xorpd %{reg2}, %{reg1}"), "xorpd");
938 }
939
TEST_F(AssemblerX86_64Test,Andps)940 TEST_F(AssemblerX86_64Test, Andps) {
941 DriverStr(RepeatFF(&x86_64::X86_64Assembler::andps, "andps %{reg2}, %{reg1}"), "andps");
942 }
943
TEST_F(AssemblerX86_64Test,Andpd)944 TEST_F(AssemblerX86_64Test, Andpd) {
945 DriverStr(RepeatFF(&x86_64::X86_64Assembler::andpd, "andpd %{reg2}, %{reg1}"), "andpd");
946 }
947
TEST_F(AssemblerX86_64Test,Orps)948 TEST_F(AssemblerX86_64Test, Orps) {
949 DriverStr(RepeatFF(&x86_64::X86_64Assembler::orps, "orps %{reg2}, %{reg1}"), "orps");
950 }
951
TEST_F(AssemblerX86_64Test,Orpd)952 TEST_F(AssemblerX86_64Test, Orpd) {
953 DriverStr(RepeatFF(&x86_64::X86_64Assembler::orpd, "orpd %{reg2}, %{reg1}"), "orpd");
954 }
955
956 // X87
957
x87_fn(AssemblerX86_64Test::Base * assembler_test ATTRIBUTE_UNUSED,x86_64::X86_64Assembler * assembler)958 std::string x87_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
959 x86_64::X86_64Assembler* assembler) {
960 std::ostringstream str;
961
962 assembler->fincstp();
963 str << "fincstp\n";
964
965 assembler->fsin();
966 str << "fsin\n";
967
968 assembler->fcos();
969 str << "fcos\n";
970
971 assembler->fptan();
972 str << "fptan\n";
973
974 return str.str();
975 }
976
TEST_F(AssemblerX86_64Test,X87)977 TEST_F(AssemblerX86_64Test, X87) {
978 DriverFn(&x87_fn, "x87");
979 }
980
TEST_F(AssemblerX86_64Test,FPUIntegerLoad)981 TEST_F(AssemblerX86_64Test, FPUIntegerLoad) {
982 GetAssembler()->filds(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 4));
983 GetAssembler()->fildl(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 12));
984 const char* expected =
985 "fildl 0x4(%RSP)\n"
986 "fildll 0xc(%RSP)\n";
987 DriverStr(expected, "FPUIntegerLoad");
988 }
989
TEST_F(AssemblerX86_64Test,FPUIntegerStore)990 TEST_F(AssemblerX86_64Test, FPUIntegerStore) {
991 GetAssembler()->fistps(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 16));
992 GetAssembler()->fistpl(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 24));
993 const char* expected =
994 "fistpl 0x10(%RSP)\n"
995 "fistpll 0x18(%RSP)\n";
996 DriverStr(expected, "FPUIntegerStore");
997 }
998
999 ////////////////
1000 // CALL / JMP //
1001 ////////////////
1002
TEST_F(AssemblerX86_64Test,Call)1003 TEST_F(AssemblerX86_64Test, Call) {
1004 DriverStr(RepeatR(&x86_64::X86_64Assembler::call, "call *%{reg}"), "call");
1005 }
1006
TEST_F(AssemblerX86_64Test,Jmp)1007 TEST_F(AssemblerX86_64Test, Jmp) {
1008 DriverStr(RepeatR(&x86_64::X86_64Assembler::jmp, "jmp *%{reg}"), "jmp");
1009 }
1010
TEST_F(AssemblerX86_64Test,Enter)1011 TEST_F(AssemblerX86_64Test, Enter) {
1012 DriverStr(RepeatI(&x86_64::X86_64Assembler::enter, 2U /* 16b immediate */, "enter ${imm}, $0",
1013 true /* Only non-negative number */), "enter");
1014 }
1015
TEST_F(AssemblerX86_64Test,RetImm)1016 TEST_F(AssemblerX86_64Test, RetImm) {
1017 DriverStr(RepeatI(&x86_64::X86_64Assembler::ret, 2U /* 16b immediate */, "ret ${imm}",
1018 true /* Only non-negative number */), "reti");
1019 }
1020
ret_and_leave_fn(AssemblerX86_64Test::Base * assembler_test ATTRIBUTE_UNUSED,x86_64::X86_64Assembler * assembler)1021 std::string ret_and_leave_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
1022 x86_64::X86_64Assembler* assembler) {
1023 std::ostringstream str;
1024
1025 assembler->ret();
1026 str << "ret\n";
1027
1028 assembler->leave();
1029 str << "leave\n";
1030
1031 return str.str();
1032 }
1033
TEST_F(AssemblerX86_64Test,RetAndLeave)1034 TEST_F(AssemblerX86_64Test, RetAndLeave) {
1035 DriverFn(&ret_and_leave_fn, "retleave");
1036 }
1037
1038 //////////
1039 // MISC //
1040 //////////
1041
TEST_F(AssemblerX86_64Test,Bswapl)1042 TEST_F(AssemblerX86_64Test, Bswapl) {
1043 DriverStr(Repeatr(&x86_64::X86_64Assembler::bswapl, "bswap %{reg}"), "bswapl");
1044 }
1045
TEST_F(AssemblerX86_64Test,Bswapq)1046 TEST_F(AssemblerX86_64Test, Bswapq) {
1047 DriverStr(RepeatR(&x86_64::X86_64Assembler::bswapq, "bswap %{reg}"), "bswapq");
1048 }
1049
setcc_test_fn(AssemblerX86_64Test::Base * assembler_test,x86_64::X86_64Assembler * assembler)1050 std::string setcc_test_fn(AssemblerX86_64Test::Base* assembler_test,
1051 x86_64::X86_64Assembler* assembler) {
1052 // From Condition
1053 /*
1054 kOverflow = 0,
1055 kNoOverflow = 1,
1056 kBelow = 2,
1057 kAboveEqual = 3,
1058 kEqual = 4,
1059 kNotEqual = 5,
1060 kBelowEqual = 6,
1061 kAbove = 7,
1062 kSign = 8,
1063 kNotSign = 9,
1064 kParityEven = 10,
1065 kParityOdd = 11,
1066 kLess = 12,
1067 kGreaterEqual = 13,
1068 kLessEqual = 14,
1069 */
1070 std::string suffixes[15] = { "o", "no", "b", "ae", "e", "ne", "be", "a", "s", "ns", "pe", "po",
1071 "l", "ge", "le" };
1072
1073 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
1074 std::ostringstream str;
1075
1076 for (auto reg : registers) {
1077 for (size_t i = 0; i < 15; ++i) {
1078 assembler->setcc(static_cast<x86_64::Condition>(i), *reg);
1079 str << "set" << suffixes[i] << " %" << assembler_test->GetQuaternaryRegisterName(*reg) << "\n";
1080 }
1081 }
1082
1083 return str.str();
1084 }
1085
TEST_F(AssemblerX86_64Test,SetCC)1086 TEST_F(AssemblerX86_64Test, SetCC) {
1087 DriverFn(&setcc_test_fn, "setcc");
1088 }
1089
ManagedFromCpu(x86_64::Register r)1090 static x86_64::X86_64ManagedRegister ManagedFromCpu(x86_64::Register r) {
1091 return x86_64::X86_64ManagedRegister::FromCpuRegister(r);
1092 }
1093
ManagedFromFpu(x86_64::FloatRegister r)1094 static x86_64::X86_64ManagedRegister ManagedFromFpu(x86_64::FloatRegister r) {
1095 return x86_64::X86_64ManagedRegister::FromXmmRegister(r);
1096 }
1097
buildframe_test_fn(AssemblerX86_64Test::Base * assembler_test ATTRIBUTE_UNUSED,x86_64::X86_64Assembler * assembler)1098 std::string buildframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
1099 x86_64::X86_64Assembler* assembler) {
1100 // TODO: more interesting spill registers / entry spills.
1101
1102 // Two random spill regs.
1103 std::vector<ManagedRegister> spill_regs;
1104 spill_regs.push_back(ManagedFromCpu(x86_64::R10));
1105 spill_regs.push_back(ManagedFromCpu(x86_64::RSI));
1106
1107 // Three random entry spills.
1108 ManagedRegisterEntrySpills entry_spills;
1109 ManagedRegisterSpill spill(ManagedFromCpu(x86_64::RAX), 8, 0);
1110 entry_spills.push_back(spill);
1111 ManagedRegisterSpill spill2(ManagedFromCpu(x86_64::RBX), 8, 8);
1112 entry_spills.push_back(spill2);
1113 ManagedRegisterSpill spill3(ManagedFromFpu(x86_64::XMM1), 8, 16);
1114 entry_spills.push_back(spill3);
1115
1116 x86_64::X86_64ManagedRegister method_reg = ManagedFromCpu(x86_64::RDI);
1117
1118 size_t frame_size = 10 * kStackAlignment;
1119 assembler->BuildFrame(10 * kStackAlignment, method_reg, spill_regs, entry_spills);
1120
1121 // Construct assembly text counterpart.
1122 std::ostringstream str;
1123 // 1) Push the spill_regs.
1124 str << "pushq %rsi\n";
1125 str << "pushq %r10\n";
1126 // 2) Move down the stack pointer.
1127 ssize_t displacement = static_cast<ssize_t>(frame_size) - (spill_regs.size() * 8 + 8);
1128 str << "subq $" << displacement << ", %rsp\n";
1129 // 3) Store method reference.
1130 str << "movq %rdi, (%rsp)\n";
1131 // 4) Entry spills.
1132 str << "movq %rax, " << frame_size + 0 << "(%rsp)\n";
1133 str << "movq %rbx, " << frame_size + 8 << "(%rsp)\n";
1134 str << "movsd %xmm1, " << frame_size + 16 << "(%rsp)\n";
1135
1136 return str.str();
1137 }
1138
TEST_F(AssemblerX86_64Test,BuildFrame)1139 TEST_F(AssemblerX86_64Test, BuildFrame) {
1140 DriverFn(&buildframe_test_fn, "BuildFrame");
1141 }
1142
removeframe_test_fn(AssemblerX86_64Test::Base * assembler_test ATTRIBUTE_UNUSED,x86_64::X86_64Assembler * assembler)1143 std::string removeframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
1144 x86_64::X86_64Assembler* assembler) {
1145 // TODO: more interesting spill registers / entry spills.
1146
1147 // Two random spill regs.
1148 std::vector<ManagedRegister> spill_regs;
1149 spill_regs.push_back(ManagedFromCpu(x86_64::R10));
1150 spill_regs.push_back(ManagedFromCpu(x86_64::RSI));
1151
1152 size_t frame_size = 10 * kStackAlignment;
1153 assembler->RemoveFrame(10 * kStackAlignment, spill_regs);
1154
1155 // Construct assembly text counterpart.
1156 std::ostringstream str;
1157 // 1) Move up the stack pointer.
1158 ssize_t displacement = static_cast<ssize_t>(frame_size) - spill_regs.size() * 8 - 8;
1159 str << "addq $" << displacement << ", %rsp\n";
1160 // 2) Pop spill regs.
1161 str << "popq %r10\n";
1162 str << "popq %rsi\n";
1163 str << "ret\n";
1164
1165 return str.str();
1166 }
1167
TEST_F(AssemblerX86_64Test,RemoveFrame)1168 TEST_F(AssemblerX86_64Test, RemoveFrame) {
1169 DriverFn(&removeframe_test_fn, "RemoveFrame");
1170 }
1171
increaseframe_test_fn(AssemblerX86_64Test::Base * assembler_test ATTRIBUTE_UNUSED,x86_64::X86_64Assembler * assembler)1172 std::string increaseframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
1173 x86_64::X86_64Assembler* assembler) {
1174 assembler->IncreaseFrameSize(0U);
1175 assembler->IncreaseFrameSize(kStackAlignment);
1176 assembler->IncreaseFrameSize(10 * kStackAlignment);
1177
1178 // Construct assembly text counterpart.
1179 std::ostringstream str;
1180 str << "addq $0, %rsp\n";
1181 str << "addq $-" << kStackAlignment << ", %rsp\n";
1182 str << "addq $-" << 10 * kStackAlignment << ", %rsp\n";
1183
1184 return str.str();
1185 }
1186
TEST_F(AssemblerX86_64Test,IncreaseFrame)1187 TEST_F(AssemblerX86_64Test, IncreaseFrame) {
1188 DriverFn(&increaseframe_test_fn, "IncreaseFrame");
1189 }
1190
decreaseframe_test_fn(AssemblerX86_64Test::Base * assembler_test ATTRIBUTE_UNUSED,x86_64::X86_64Assembler * assembler)1191 std::string decreaseframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
1192 x86_64::X86_64Assembler* assembler) {
1193 assembler->DecreaseFrameSize(0U);
1194 assembler->DecreaseFrameSize(kStackAlignment);
1195 assembler->DecreaseFrameSize(10 * kStackAlignment);
1196
1197 // Construct assembly text counterpart.
1198 std::ostringstream str;
1199 str << "addq $0, %rsp\n";
1200 str << "addq $" << kStackAlignment << ", %rsp\n";
1201 str << "addq $" << 10 * kStackAlignment << ", %rsp\n";
1202
1203 return str.str();
1204 }
1205
TEST_F(AssemblerX86_64Test,DecreaseFrame)1206 TEST_F(AssemblerX86_64Test, DecreaseFrame) {
1207 DriverFn(&decreaseframe_test_fn, "DecreaseFrame");
1208 }
1209
TEST_F(AssemblerX86_64Test,MovzxbRegs)1210 TEST_F(AssemblerX86_64Test, MovzxbRegs) {
1211 DriverStr(Repeatrb(&x86_64::X86_64Assembler::movzxb, "movzbl %{reg2}, %{reg1}"), "movzxb");
1212 }
1213
TEST_F(AssemblerX86_64Test,MovsxbRegs)1214 TEST_F(AssemblerX86_64Test, MovsxbRegs) {
1215 DriverStr(Repeatrb(&x86_64::X86_64Assembler::movsxb, "movsbl %{reg2}, %{reg1}"), "movsxb");
1216 }
1217
TEST_F(AssemblerX86_64Test,Repnescasw)1218 TEST_F(AssemblerX86_64Test, Repnescasw) {
1219 GetAssembler()->repne_scasw();
1220 const char* expected = "repne scasw\n";
1221 DriverStr(expected, "Repnescasw");
1222 }
1223
1224 } // namespace art
1225