assembler_x86_64_test.cc revision fb8d279bc011b31d0765dc7ca59afea324fd0d0c
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/stl_util.h"
24#include "utils/assembler_test.h"
25#include "utils.h"
26
27namespace art {
28
29TEST(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
39static constexpr size_t kRandomIterations = 1000;  // Devices might be puny, don't stress them...
40#else
41static constexpr size_t kRandomIterations = 100000;  // Hosts are pretty powerful.
42#endif
43
44TEST(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
119struct X86_64CpuRegisterCompare {
120    bool operator()(const x86_64::CpuRegister& a, const x86_64::CpuRegister& b) const {
121        return a.AsRegister() < b.AsRegister();
122    }
123};
124
125class 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, ...
133  std::string GetArchitectureString() OVERRIDE {
134    return "x86_64";
135  }
136
137  std::string GetDisassembleParameters() OVERRIDE {
138    return " -D -bbinary -mi386:x86-64 -Mx86-64,addr64,data32 --no-show-raw-insn";
139  }
140
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      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM0));
178      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM1));
179      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM2));
180      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM3));
181      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM4));
182      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM5));
183      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM6));
184      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM7));
185      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM8));
186      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM9));
187      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM10));
188      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM11));
189      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM12));
190      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM13));
191      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM14));
192      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM15));
193    }
194  }
195
196  void TearDown() OVERRIDE {
197    AssemblerTest::TearDown();
198    STLDeleteElements(&registers_);
199    STLDeleteElements(&fp_registers_);
200  }
201
202  std::vector<x86_64::CpuRegister*> GetRegisters() OVERRIDE {
203    return registers_;
204  }
205
206  std::vector<x86_64::XmmRegister*> GetFPRegisters() OVERRIDE {
207    return fp_registers_;
208  }
209
210  x86_64::Immediate CreateImmediate(int64_t imm_value) OVERRIDE {
211    return x86_64::Immediate(imm_value);
212  }
213
214  std::string GetSecondaryRegisterName(const x86_64::CpuRegister& reg) OVERRIDE {
215    CHECK(secondary_register_names_.find(reg) != secondary_register_names_.end());
216    return secondary_register_names_[reg];
217  }
218
219 private:
220  std::vector<x86_64::CpuRegister*> registers_;
221  std::map<x86_64::CpuRegister, std::string, X86_64CpuRegisterCompare> secondary_register_names_;
222
223  std::vector<x86_64::XmmRegister*> fp_registers_;
224};
225
226
227TEST_F(AssemblerX86_64Test, Toolchain) {
228  EXPECT_TRUE(CheckTools());
229}
230
231
232TEST_F(AssemblerX86_64Test, PushqRegs) {
233  DriverStr(RepeatR(&x86_64::X86_64Assembler::pushq, "pushq %{reg}"), "pushq");
234}
235
236TEST_F(AssemblerX86_64Test, PushqImm) {
237  DriverStr(RepeatI(&x86_64::X86_64Assembler::pushq, 4U, "pushq ${imm}"), "pushqi");
238}
239
240TEST_F(AssemblerX86_64Test, MovqRegs) {
241  DriverStr(RepeatRR(&x86_64::X86_64Assembler::movq, "movq %{reg2}, %{reg1}"), "movq");
242}
243
244TEST_F(AssemblerX86_64Test, MovqImm) {
245  DriverStr(RepeatRI(&x86_64::X86_64Assembler::movq, 8U, "movq ${imm}, %{reg}"), "movqi");
246}
247
248TEST_F(AssemblerX86_64Test, MovlRegs) {
249  DriverStr(Repeatrr(&x86_64::X86_64Assembler::movl, "mov %{reg2}, %{reg1}"), "movl");
250}
251
252TEST_F(AssemblerX86_64Test, MovlImm) {
253  DriverStr(Repeatri(&x86_64::X86_64Assembler::movl, 4U, "mov ${imm}, %{reg}"), "movli");
254}
255
256TEST_F(AssemblerX86_64Test, AddqRegs) {
257  DriverStr(RepeatRR(&x86_64::X86_64Assembler::addq, "addq %{reg2}, %{reg1}"), "addq");
258}
259
260TEST_F(AssemblerX86_64Test, AddqImm) {
261  DriverStr(RepeatRI(&x86_64::X86_64Assembler::addq, 4U, "addq ${imm}, %{reg}"), "addqi");
262}
263
264TEST_F(AssemblerX86_64Test, AddlRegs) {
265  DriverStr(Repeatrr(&x86_64::X86_64Assembler::addl, "add %{reg2}, %{reg1}"), "addl");
266}
267
268TEST_F(AssemblerX86_64Test, AddlImm) {
269  DriverStr(Repeatri(&x86_64::X86_64Assembler::addl, 4U, "add ${imm}, %{reg}"), "addli");
270}
271
272TEST_F(AssemblerX86_64Test, ImulqRegs) {
273  DriverStr(RepeatRR(&x86_64::X86_64Assembler::imulq, "imulq %{reg2}, %{reg1}"), "imulq");
274}
275
276TEST_F(AssemblerX86_64Test, ImulqImm) {
277  DriverStr(RepeatRI(&x86_64::X86_64Assembler::imulq, 4U, "imulq ${imm}, %{reg}, %{reg}"),
278            "imulqi");
279}
280
281TEST_F(AssemblerX86_64Test, ImullRegs) {
282  DriverStr(Repeatrr(&x86_64::X86_64Assembler::imull, "imul %{reg2}, %{reg1}"), "imull");
283}
284
285TEST_F(AssemblerX86_64Test, ImullImm) {
286  DriverStr(Repeatri(&x86_64::X86_64Assembler::imull, 4U, "imull ${imm}, %{reg}, %{reg}"),
287            "imulli");
288}
289
290TEST_F(AssemblerX86_64Test, Mull) {
291  DriverStr(Repeatr(&x86_64::X86_64Assembler::mull, "mull %{reg}"), "mull");
292}
293
294TEST_F(AssemblerX86_64Test, SubqRegs) {
295  DriverStr(RepeatRR(&x86_64::X86_64Assembler::subq, "subq %{reg2}, %{reg1}"), "subq");
296}
297
298TEST_F(AssemblerX86_64Test, SubqImm) {
299  DriverStr(RepeatRI(&x86_64::X86_64Assembler::subq, 4U, "subq ${imm}, %{reg}"), "subqi");
300}
301
302TEST_F(AssemblerX86_64Test, SublRegs) {
303  DriverStr(Repeatrr(&x86_64::X86_64Assembler::subl, "sub %{reg2}, %{reg1}"), "subl");
304}
305
306TEST_F(AssemblerX86_64Test, SublImm) {
307  DriverStr(Repeatri(&x86_64::X86_64Assembler::subl, 4U, "sub ${imm}, %{reg}"), "subli");
308}
309
310// Shll only allows CL as the shift count.
311std::string shll_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
312  std::ostringstream str;
313
314  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
315
316  x86_64::CpuRegister shifter(x86_64::RCX);
317  for (auto reg : registers) {
318    assembler->shll(*reg, shifter);
319    str << "shll %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n";
320  }
321
322  return str.str();
323}
324
325TEST_F(AssemblerX86_64Test, ShllReg) {
326  DriverFn(&shll_fn, "shll");
327}
328
329TEST_F(AssemblerX86_64Test, ShllImm) {
330  DriverStr(Repeatri(&x86_64::X86_64Assembler::shll, 1U, "shll ${imm}, %{reg}"), "shlli");
331}
332
333// Shlq only allows CL as the shift count.
334std::string shlq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
335  std::ostringstream str;
336
337  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
338
339  x86_64::CpuRegister shifter(x86_64::RCX);
340  for (auto reg : registers) {
341    assembler->shlq(*reg, shifter);
342    str << "shlq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n";
343  }
344
345  return str.str();
346}
347
348TEST_F(AssemblerX86_64Test, ShlqReg) {
349  DriverFn(&shlq_fn, "shlq");
350}
351
352TEST_F(AssemblerX86_64Test, ShlqImm) {
353  DriverStr(RepeatRI(&x86_64::X86_64Assembler::shlq, 1U, "shlq ${imm}, %{reg}"), "shlqi");
354}
355
356// Shrl only allows CL as the shift count.
357std::string shrl_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
358  std::ostringstream str;
359
360  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
361
362  x86_64::CpuRegister shifter(x86_64::RCX);
363  for (auto reg : registers) {
364    assembler->shrl(*reg, shifter);
365    str << "shrl %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n";
366  }
367
368  return str.str();
369}
370
371TEST_F(AssemblerX86_64Test, ShrlReg) {
372  DriverFn(&shrl_fn, "shrl");
373}
374
375TEST_F(AssemblerX86_64Test, ShrlImm) {
376  DriverStr(Repeatri(&x86_64::X86_64Assembler::shrl, 1U, "shrl ${imm}, %{reg}"), "shrli");
377}
378
379// Shrq only allows CL as the shift count.
380std::string shrq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
381  std::ostringstream str;
382
383  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
384
385  x86_64::CpuRegister shifter(x86_64::RCX);
386  for (auto reg : registers) {
387    assembler->shrq(*reg, shifter);
388    str << "shrq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n";
389  }
390
391  return str.str();
392}
393
394TEST_F(AssemblerX86_64Test, ShrqReg) {
395  DriverFn(&shrq_fn, "shrq");
396}
397
398TEST_F(AssemblerX86_64Test, ShrqImm) {
399  DriverStr(RepeatRI(&x86_64::X86_64Assembler::shrq, 1U, "shrq ${imm}, %{reg}"), "shrqi");
400}
401
402// Sarl only allows CL as the shift count.
403std::string sarl_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
404  std::ostringstream str;
405
406  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
407
408  x86_64::CpuRegister shifter(x86_64::RCX);
409  for (auto reg : registers) {
410    assembler->sarl(*reg, shifter);
411    str << "sarl %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n";
412  }
413
414  return str.str();
415}
416
417TEST_F(AssemblerX86_64Test, SarlReg) {
418  DriverFn(&sarl_fn, "sarl");
419}
420
421TEST_F(AssemblerX86_64Test, SarlImm) {
422  DriverStr(Repeatri(&x86_64::X86_64Assembler::sarl, 1U, "sarl ${imm}, %{reg}"), "sarli");
423}
424
425// Sarq only allows CL as the shift count.
426std::string sarq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
427  std::ostringstream str;
428
429  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
430
431  x86_64::CpuRegister shifter(x86_64::RCX);
432  for (auto reg : registers) {
433    assembler->sarq(*reg, shifter);
434    str << "sarq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n";
435  }
436
437  return str.str();
438}
439
440TEST_F(AssemblerX86_64Test, SarqReg) {
441  DriverFn(&sarq_fn, "sarq");
442}
443
444TEST_F(AssemblerX86_64Test, SarqImm) {
445  DriverStr(RepeatRI(&x86_64::X86_64Assembler::sarq, 1U, "sarq ${imm}, %{reg}"), "sarqi");
446}
447
448TEST_F(AssemblerX86_64Test, CmpqRegs) {
449  DriverStr(RepeatRR(&x86_64::X86_64Assembler::cmpq, "cmpq %{reg2}, %{reg1}"), "cmpq");
450}
451
452TEST_F(AssemblerX86_64Test, CmpqImm) {
453  DriverStr(RepeatRI(&x86_64::X86_64Assembler::cmpq, 4U  /* cmpq only supports 32b imm */,
454                     "cmpq ${imm}, %{reg}"), "cmpqi");
455}
456
457TEST_F(AssemblerX86_64Test, CmplRegs) {
458  DriverStr(Repeatrr(&x86_64::X86_64Assembler::cmpl, "cmp %{reg2}, %{reg1}"), "cmpl");
459}
460
461TEST_F(AssemblerX86_64Test, CmplImm) {
462  DriverStr(Repeatri(&x86_64::X86_64Assembler::cmpl, 4U, "cmpl ${imm}, %{reg}"), "cmpli");
463}
464
465TEST_F(AssemblerX86_64Test, Testl) {
466  // Note: uses different order for GCC than usual. This makes GCC happy, and doesn't have an
467  // impact on functional correctness.
468  DriverStr(Repeatrr(&x86_64::X86_64Assembler::testl, "testl %{reg1}, %{reg2}"), "testl");
469}
470
471TEST_F(AssemblerX86_64Test, Negq) {
472  DriverStr(RepeatR(&x86_64::X86_64Assembler::negq, "negq %{reg}"), "negq");
473}
474
475TEST_F(AssemblerX86_64Test, Negl) {
476  DriverStr(Repeatr(&x86_64::X86_64Assembler::negl, "negl %{reg}"), "negl");
477}
478
479TEST_F(AssemblerX86_64Test, Notq) {
480  DriverStr(RepeatR(&x86_64::X86_64Assembler::notq, "notq %{reg}"), "notq");
481}
482
483TEST_F(AssemblerX86_64Test, Notl) {
484  DriverStr(Repeatr(&x86_64::X86_64Assembler::notl, "notl %{reg}"), "notl");
485}
486
487TEST_F(AssemblerX86_64Test, AndqRegs) {
488  DriverStr(RepeatRR(&x86_64::X86_64Assembler::andq, "andq %{reg2}, %{reg1}"), "andq");
489}
490
491TEST_F(AssemblerX86_64Test, AndqImm) {
492  DriverStr(RepeatRI(&x86_64::X86_64Assembler::andq, 4U  /* andq only supports 32b imm */,
493                     "andq ${imm}, %{reg}"), "andqi");
494}
495
496TEST_F(AssemblerX86_64Test, AndlRegs) {
497  DriverStr(Repeatrr(&x86_64::X86_64Assembler::andl, "andl %{reg2}, %{reg1}"), "andl");
498}
499
500TEST_F(AssemblerX86_64Test, AndlImm) {
501  DriverStr(Repeatri(&x86_64::X86_64Assembler::andl, 4U, "andl ${imm}, %{reg}"), "andli");
502}
503
504TEST_F(AssemblerX86_64Test, OrqRegs) {
505  DriverStr(RepeatRR(&x86_64::X86_64Assembler::orq, "orq %{reg2}, %{reg1}"), "orq");
506}
507
508TEST_F(AssemblerX86_64Test, OrlRegs) {
509  DriverStr(Repeatrr(&x86_64::X86_64Assembler::orl, "orl %{reg2}, %{reg1}"), "orl");
510}
511
512TEST_F(AssemblerX86_64Test, OrlImm) {
513  DriverStr(Repeatri(&x86_64::X86_64Assembler::orl, 4U, "orl ${imm}, %{reg}"), "orli");
514}
515
516TEST_F(AssemblerX86_64Test, XorqRegs) {
517  DriverStr(RepeatRR(&x86_64::X86_64Assembler::xorq, "xorq %{reg2}, %{reg1}"), "xorq");
518}
519
520TEST_F(AssemblerX86_64Test, XorqImm) {
521  DriverStr(RepeatRI(&x86_64::X86_64Assembler::xorq, 4U, "xorq ${imm}, %{reg}"), "xorqi");
522}
523
524TEST_F(AssemblerX86_64Test, XorlRegs) {
525  DriverStr(Repeatrr(&x86_64::X86_64Assembler::xorl, "xor %{reg2}, %{reg1}"), "xorl");
526}
527
528TEST_F(AssemblerX86_64Test, XorlImm) {
529  DriverStr(Repeatri(&x86_64::X86_64Assembler::xorl, 4U, "xor ${imm}, %{reg}"), "xorli");
530}
531
532TEST_F(AssemblerX86_64Test, Xchgq) {
533  DriverStr(RepeatRR(&x86_64::X86_64Assembler::xchgq, "xchgq %{reg2}, %{reg1}"), "xchgq");
534}
535
536TEST_F(AssemblerX86_64Test, Xchgl) {
537  // Test is disabled because GCC generates 0x87 0xC0 for xchgl eax, eax. All other cases are the
538  // same. Anyone know why it doesn't emit a simple 0x90? It does so for xchgq rax, rax...
539  // DriverStr(Repeatrr(&x86_64::X86_64Assembler::xchgl, "xchgl %{reg2}, %{reg1}"), "xchgl");
540}
541
542TEST_F(AssemblerX86_64Test, Movl) {
543  GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address(
544      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
545  GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address(
546      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
547  GetAssembler()->movl(x86_64::CpuRegister(x86_64::R8), x86_64::Address(
548      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
549  GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address(
550      x86_64::CpuRegister(x86_64::R13), 0));
551  GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address(
552      x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0));
553  const char* expected =
554    "movl 0xc(%RDI,%RBX,4), %EAX\n"
555    "movl 0xc(%RDI,%R9,4), %EAX\n"
556    "movl 0xc(%RDI,%R9,4), %R8d\n"
557    "movl (%R13), %EAX\n"
558    "movl (%R13,%R9,1), %EAX\n";
559
560  DriverStr(expected, "movl");
561}
562
563TEST_F(AssemblerX86_64Test, Movw) {
564  GetAssembler()->movw(x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
565                       x86_64::CpuRegister(x86_64::R9));
566  const char* expected = "movw %R9w, 0(%RAX)\n";
567  DriverStr(expected, "movw");
568}
569
570TEST_F(AssemblerX86_64Test, Movsxd) {
571  DriverStr(RepeatRr(&x86_64::X86_64Assembler::movsxd, "movsxd %{reg2}, %{reg1}"), "movsxd");
572}
573
574///////////////////
575// FP Operations //
576///////////////////
577
578TEST_F(AssemblerX86_64Test, Movaps) {
579  DriverStr(RepeatFF(&x86_64::X86_64Assembler::movaps, "movaps %{reg2}, %{reg1}"), "movaps");
580}
581
582TEST_F(AssemblerX86_64Test, Movss) {
583  DriverStr(RepeatFF(&x86_64::X86_64Assembler::movss, "movss %{reg2}, %{reg1}"), "movss");
584}
585
586TEST_F(AssemblerX86_64Test, Movsd) {
587  DriverStr(RepeatFF(&x86_64::X86_64Assembler::movsd, "movsd %{reg2}, %{reg1}"), "movsd");
588}
589
590TEST_F(AssemblerX86_64Test, Movd1) {
591  DriverStr(RepeatFR(&x86_64::X86_64Assembler::movd, "movd %{reg2}, %{reg1}"), "movd.1");
592}
593
594TEST_F(AssemblerX86_64Test, Movd2) {
595  DriverStr(RepeatRF(&x86_64::X86_64Assembler::movd, "movd %{reg2}, %{reg1}"), "movd.2");
596}
597
598TEST_F(AssemblerX86_64Test, Addss) {
599  DriverStr(RepeatFF(&x86_64::X86_64Assembler::addss, "addss %{reg2}, %{reg1}"), "addss");
600}
601
602TEST_F(AssemblerX86_64Test, Addsd) {
603  DriverStr(RepeatFF(&x86_64::X86_64Assembler::addsd, "addsd %{reg2}, %{reg1}"), "addsd");
604}
605
606TEST_F(AssemblerX86_64Test, Subss) {
607  DriverStr(RepeatFF(&x86_64::X86_64Assembler::subss, "subss %{reg2}, %{reg1}"), "subss");
608}
609
610TEST_F(AssemblerX86_64Test, Subsd) {
611  DriverStr(RepeatFF(&x86_64::X86_64Assembler::subsd, "subsd %{reg2}, %{reg1}"), "subsd");
612}
613
614TEST_F(AssemblerX86_64Test, Mulss) {
615  DriverStr(RepeatFF(&x86_64::X86_64Assembler::mulss, "mulss %{reg2}, %{reg1}"), "mulss");
616}
617
618TEST_F(AssemblerX86_64Test, Mulsd) {
619  DriverStr(RepeatFF(&x86_64::X86_64Assembler::mulsd, "mulsd %{reg2}, %{reg1}"), "mulsd");
620}
621
622TEST_F(AssemblerX86_64Test, Divss) {
623  DriverStr(RepeatFF(&x86_64::X86_64Assembler::divss, "divss %{reg2}, %{reg1}"), "divss");
624}
625
626TEST_F(AssemblerX86_64Test, Divsd) {
627  DriverStr(RepeatFF(&x86_64::X86_64Assembler::divsd, "divsd %{reg2}, %{reg1}"), "divsd");
628}
629
630TEST_F(AssemblerX86_64Test, Cvtsi2ss) {
631  DriverStr(RepeatFr(&x86_64::X86_64Assembler::cvtsi2ss, "cvtsi2ss %{reg2}, %{reg1}"), "cvtsi2ss");
632}
633
634TEST_F(AssemblerX86_64Test, Cvtsi2sd) {
635  DriverStr(RepeatFr(&x86_64::X86_64Assembler::cvtsi2sd, "cvtsi2sd %{reg2}, %{reg1}"), "cvtsi2sd");
636}
637
638
639TEST_F(AssemblerX86_64Test, Cvtss2si) {
640  DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvtss2si, "cvtss2si %{reg2}, %{reg1}"), "cvtss2si");
641}
642
643
644TEST_F(AssemblerX86_64Test, Cvtss2sd) {
645  DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtss2sd, "cvtss2sd %{reg2}, %{reg1}"), "cvtss2sd");
646}
647
648
649TEST_F(AssemblerX86_64Test, Cvtsd2si) {
650  DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvtsd2si, "cvtsd2si %{reg2}, %{reg1}"), "cvtsd2si");
651}
652
653TEST_F(AssemblerX86_64Test, Cvttss2si) {
654  DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvttss2si, "cvttss2si %{reg2}, %{reg1}"),
655            "cvttss2si");
656}
657
658TEST_F(AssemblerX86_64Test, Cvttsd2si) {
659  DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvttsd2si, "cvttsd2si %{reg2}, %{reg1}"),
660            "cvttsd2si");
661}
662
663TEST_F(AssemblerX86_64Test, Cvtsd2ss) {
664  DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtsd2ss, "cvtsd2ss %{reg2}, %{reg1}"), "cvtsd2ss");
665}
666
667TEST_F(AssemblerX86_64Test, Cvtdq2pd) {
668  DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtdq2pd, "cvtdq2pd %{reg2}, %{reg1}"), "cvtdq2pd");
669}
670
671TEST_F(AssemblerX86_64Test, Comiss) {
672  DriverStr(RepeatFF(&x86_64::X86_64Assembler::comiss, "comiss %{reg2}, %{reg1}"), "comiss");
673}
674
675TEST_F(AssemblerX86_64Test, Comisd) {
676  DriverStr(RepeatFF(&x86_64::X86_64Assembler::comisd, "comisd %{reg2}, %{reg1}"), "comisd");
677}
678
679TEST_F(AssemblerX86_64Test, Ucomiss) {
680  DriverStr(RepeatFF(&x86_64::X86_64Assembler::ucomiss, "ucomiss %{reg2}, %{reg1}"), "ucomiss");
681}
682
683TEST_F(AssemblerX86_64Test, Ucomisd) {
684  DriverStr(RepeatFF(&x86_64::X86_64Assembler::ucomisd, "ucomisd %{reg2}, %{reg1}"), "ucomisd");
685}
686
687TEST_F(AssemblerX86_64Test, Sqrtss) {
688  DriverStr(RepeatFF(&x86_64::X86_64Assembler::sqrtss, "sqrtss %{reg2}, %{reg1}"), "sqrtss");
689}
690
691TEST_F(AssemblerX86_64Test, Sqrtsd) {
692  DriverStr(RepeatFF(&x86_64::X86_64Assembler::sqrtsd, "sqrtsd %{reg2}, %{reg1}"), "sqrtsd");
693}
694
695TEST_F(AssemblerX86_64Test, Roundss) {
696  DriverStr(RepeatFFI(&x86_64::X86_64Assembler::roundss, 1, "roundss ${imm}, %{reg2}, %{reg1}"), "roundss");
697}
698
699TEST_F(AssemblerX86_64Test, Roundsd) {
700  DriverStr(RepeatFFI(&x86_64::X86_64Assembler::roundsd, 1, "roundsd ${imm}, %{reg2}, %{reg1}"), "roundsd");
701}
702
703TEST_F(AssemblerX86_64Test, Xorps) {
704  DriverStr(RepeatFF(&x86_64::X86_64Assembler::xorps, "xorps %{reg2}, %{reg1}"), "xorps");
705}
706
707TEST_F(AssemblerX86_64Test, Xorpd) {
708  DriverStr(RepeatFF(&x86_64::X86_64Assembler::xorpd, "xorpd %{reg2}, %{reg1}"), "xorpd");
709}
710
711TEST_F(AssemblerX86_64Test, Andps) {
712  DriverStr(RepeatFF(&x86_64::X86_64Assembler::andps, "andps %{reg2}, %{reg1}"), "andps");
713}
714
715TEST_F(AssemblerX86_64Test, Andpd) {
716  DriverStr(RepeatFF(&x86_64::X86_64Assembler::andpd, "andpd %{reg2}, %{reg1}"), "andpd");
717}
718
719TEST_F(AssemblerX86_64Test, Orps) {
720  DriverStr(RepeatFF(&x86_64::X86_64Assembler::orps, "orps %{reg2}, %{reg1}"), "orps");
721}
722
723TEST_F(AssemblerX86_64Test, Orpd) {
724  DriverStr(RepeatFF(&x86_64::X86_64Assembler::orpd, "orpd %{reg2}, %{reg1}"), "orpd");
725}
726
727// X87
728
729std::string x87_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
730                   x86_64::X86_64Assembler* assembler) {
731  std::ostringstream str;
732
733  assembler->fincstp();
734  str << "fincstp\n";
735
736  assembler->fsin();
737  str << "fsin\n";
738
739  assembler->fcos();
740  str << "fcos\n";
741
742  assembler->fptan();
743  str << "fptan\n";
744
745  return str.str();
746}
747
748TEST_F(AssemblerX86_64Test, X87) {
749  DriverFn(&x87_fn, "x87");
750}
751
752////////////////
753// CALL / JMP //
754////////////////
755
756TEST_F(AssemblerX86_64Test, Call) {
757  DriverStr(RepeatR(&x86_64::X86_64Assembler::call, "call *%{reg}"), "call");
758}
759
760TEST_F(AssemblerX86_64Test, Jmp) {
761  DriverStr(RepeatR(&x86_64::X86_64Assembler::jmp, "jmp *%{reg}"), "jmp");
762}
763
764TEST_F(AssemblerX86_64Test, Enter) {
765  DriverStr(RepeatI(&x86_64::X86_64Assembler::enter, 2U  /* 16b immediate */, "enter ${imm}, $0",
766                    true  /* Only non-negative number */), "enter");
767}
768
769TEST_F(AssemblerX86_64Test, RetImm) {
770  DriverStr(RepeatI(&x86_64::X86_64Assembler::ret, 2U  /* 16b immediate */, "ret ${imm}",
771                    true  /* Only non-negative number */), "reti");
772}
773
774std::string ret_and_leave_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
775                             x86_64::X86_64Assembler* assembler) {
776  std::ostringstream str;
777
778  assembler->ret();
779  str << "ret\n";
780
781  assembler->leave();
782  str << "leave\n";
783
784  return str.str();
785}
786
787TEST_F(AssemblerX86_64Test, RetAndLeave) {
788  DriverFn(&ret_and_leave_fn, "retleave");
789}
790
791//////////
792// MISC //
793//////////
794
795TEST_F(AssemblerX86_64Test, Bswapl) {
796  DriverStr(Repeatr(&x86_64::X86_64Assembler::bswapl, "bswap %{reg}"), "bswapl");
797}
798
799TEST_F(AssemblerX86_64Test, Bswapq) {
800  DriverStr(RepeatR(&x86_64::X86_64Assembler::bswapq, "bswap %{reg}"), "bswapq");
801}
802
803std::string setcc_test_fn(AssemblerX86_64Test::Base* assembler_test,
804                          x86_64::X86_64Assembler* assembler) {
805  // From Condition
806  /*
807  kOverflow     =  0,
808  kNoOverflow   =  1,
809  kBelow        =  2,
810  kAboveEqual   =  3,
811  kEqual        =  4,
812  kNotEqual     =  5,
813  kBelowEqual   =  6,
814  kAbove        =  7,
815  kSign         =  8,
816  kNotSign      =  9,
817  kParityEven   = 10,
818  kParityOdd    = 11,
819  kLess         = 12,
820  kGreaterEqual = 13,
821  kLessEqual    = 14,
822  */
823  std::string suffixes[15] = { "o", "no", "b", "ae", "e", "ne", "be", "a", "s", "ns", "pe", "po",
824                               "l", "ge", "le" };
825
826  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
827
828  std::string byte_regs[16];
829  byte_regs[x86_64::RAX] = "al";
830  byte_regs[x86_64::RBX] = "bl";
831  byte_regs[x86_64::RCX] = "cl";
832  byte_regs[x86_64::RDX] = "dl";
833  byte_regs[x86_64::RBP] = "bpl";
834  byte_regs[x86_64::RSP] = "spl";
835  byte_regs[x86_64::RSI] = "sil";
836  byte_regs[x86_64::RDI] = "dil";
837  byte_regs[x86_64::R8] = "r8b";
838  byte_regs[x86_64::R9] = "r9b";
839  byte_regs[x86_64::R10] = "r10b";
840  byte_regs[x86_64::R11] = "r11b";
841  byte_regs[x86_64::R12] = "r12b";
842  byte_regs[x86_64::R13] = "r13b";
843  byte_regs[x86_64::R14] = "r14b";
844  byte_regs[x86_64::R15] = "r15b";
845
846  std::ostringstream str;
847
848  for (auto reg : registers) {
849    for (size_t i = 0; i < 15; ++i) {
850      assembler->setcc(static_cast<x86_64::Condition>(i), *reg);
851      str << "set" << suffixes[i] << " %" << byte_regs[reg->AsRegister()] << "\n";
852    }
853  }
854
855  return str.str();
856}
857
858TEST_F(AssemblerX86_64Test, SetCC) {
859  DriverFn(&setcc_test_fn, "setcc");
860}
861
862static x86_64::X86_64ManagedRegister ManagedFromCpu(x86_64::Register r) {
863  return x86_64::X86_64ManagedRegister::FromCpuRegister(r);
864}
865
866static x86_64::X86_64ManagedRegister ManagedFromFpu(x86_64::FloatRegister r) {
867  return x86_64::X86_64ManagedRegister::FromXmmRegister(r);
868}
869
870std::string buildframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
871                               x86_64::X86_64Assembler* assembler) {
872  // TODO: more interesting spill registers / entry spills.
873
874  // Two random spill regs.
875  std::vector<ManagedRegister> spill_regs;
876  spill_regs.push_back(ManagedFromCpu(x86_64::R10));
877  spill_regs.push_back(ManagedFromCpu(x86_64::RSI));
878
879  // Three random entry spills.
880  ManagedRegisterEntrySpills entry_spills;
881  ManagedRegisterSpill spill(ManagedFromCpu(x86_64::RAX), 8, 0);
882  entry_spills.push_back(spill);
883  ManagedRegisterSpill spill2(ManagedFromCpu(x86_64::RBX), 8, 8);
884  entry_spills.push_back(spill2);
885  ManagedRegisterSpill spill3(ManagedFromFpu(x86_64::XMM1), 8, 16);
886  entry_spills.push_back(spill3);
887
888  x86_64::X86_64ManagedRegister method_reg = ManagedFromCpu(x86_64::RDI);
889
890  size_t frame_size = 10 * kStackAlignment;
891  assembler->BuildFrame(10 * kStackAlignment, method_reg, spill_regs, entry_spills);
892
893  // Construct assembly text counterpart.
894  std::ostringstream str;
895  // 1) Push the spill_regs.
896  str << "pushq %rsi\n";
897  str << "pushq %r10\n";
898  // 2) Move down the stack pointer.
899  ssize_t displacement = static_cast<ssize_t>(frame_size) - (spill_regs.size() * 8 + 8);
900  str << "subq $" << displacement << ", %rsp\n";
901  // 3) Store method reference.
902  str << "movl %edi, (%rsp)\n";
903  // 4) Entry spills.
904  str << "movq %rax, " << frame_size + 0 << "(%rsp)\n";
905  str << "movq %rbx, " << frame_size + 8 << "(%rsp)\n";
906  str << "movsd %xmm1, " << frame_size + 16 << "(%rsp)\n";
907
908  return str.str();
909}
910
911TEST_F(AssemblerX86_64Test, BuildFrame) {
912  DriverFn(&buildframe_test_fn, "BuildFrame");
913}
914
915std::string removeframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
916                                x86_64::X86_64Assembler* assembler) {
917  // TODO: more interesting spill registers / entry spills.
918
919  // Two random spill regs.
920  std::vector<ManagedRegister> spill_regs;
921  spill_regs.push_back(ManagedFromCpu(x86_64::R10));
922  spill_regs.push_back(ManagedFromCpu(x86_64::RSI));
923
924  size_t frame_size = 10 * kStackAlignment;
925  assembler->RemoveFrame(10 * kStackAlignment, spill_regs);
926
927  // Construct assembly text counterpart.
928  std::ostringstream str;
929  // 1) Move up the stack pointer.
930  ssize_t displacement = static_cast<ssize_t>(frame_size) - spill_regs.size() * 8 - 8;
931  str << "addq $" << displacement << ", %rsp\n";
932  // 2) Pop spill regs.
933  str << "popq %r10\n";
934  str << "popq %rsi\n";
935  str << "ret\n";
936
937  return str.str();
938}
939
940TEST_F(AssemblerX86_64Test, RemoveFrame) {
941  DriverFn(&removeframe_test_fn, "RemoveFrame");
942}
943
944std::string increaseframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
945                                  x86_64::X86_64Assembler* assembler) {
946  assembler->IncreaseFrameSize(0U);
947  assembler->IncreaseFrameSize(kStackAlignment);
948  assembler->IncreaseFrameSize(10 * kStackAlignment);
949
950  // Construct assembly text counterpart.
951  std::ostringstream str;
952  str << "addq $0, %rsp\n";
953  str << "addq $-" << kStackAlignment << ", %rsp\n";
954  str << "addq $-" << 10 * kStackAlignment << ", %rsp\n";
955
956  return str.str();
957}
958
959TEST_F(AssemblerX86_64Test, IncreaseFrame) {
960  DriverFn(&increaseframe_test_fn, "IncreaseFrame");
961}
962
963std::string decreaseframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
964                                  x86_64::X86_64Assembler* assembler) {
965  assembler->DecreaseFrameSize(0U);
966  assembler->DecreaseFrameSize(kStackAlignment);
967  assembler->DecreaseFrameSize(10 * kStackAlignment);
968
969  // Construct assembly text counterpart.
970  std::ostringstream str;
971  str << "addq $0, %rsp\n";
972  str << "addq $" << kStackAlignment << ", %rsp\n";
973  str << "addq $" << 10 * kStackAlignment << ", %rsp\n";
974
975  return str.str();
976}
977
978TEST_F(AssemblerX86_64Test, DecreaseFrame) {
979  DriverFn(&decreaseframe_test_fn, "DecreaseFrame");
980}
981
982}  // namespace art
983