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