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
27namespace art {
28
29TEST(AssemblerX86_64, CreateBuffer) {
30  ArenaPool pool;
31  ArenaAllocator arena(&pool);
32  AssemblerBuffer buffer(&arena);
33  AssemblerBuffer::EnsureCapacity ensured(&buffer);
34  buffer.Emit<uint8_t>(0x42);
35  ASSERT_EQ(static_cast<size_t>(1), buffer.Size());
36  buffer.Emit<int32_t>(42);
37  ASSERT_EQ(static_cast<size_t>(5), buffer.Size());
38}
39
40#ifdef __ANDROID__
41static constexpr size_t kRandomIterations = 1000;  // Devices might be puny, don't stress them...
42#else
43static constexpr size_t kRandomIterations = 100000;  // Hosts are pretty powerful.
44#endif
45
46TEST(AssemblerX86_64, SignExtension) {
47  // 32bit.
48  for (int32_t i = 0; i < 128; i++) {
49    EXPECT_TRUE(IsInt<8>(i)) << i;
50  }
51  for (int32_t i = 128; i < 255; i++) {
52    EXPECT_FALSE(IsInt<8>(i)) << i;
53  }
54  // Do some higher ones randomly.
55  std::random_device rd;
56  std::default_random_engine e1(rd());
57  std::uniform_int_distribution<int32_t> uniform_dist(256, INT32_MAX);
58  for (size_t i = 0; i < kRandomIterations; i++) {
59    int32_t value = uniform_dist(e1);
60    EXPECT_FALSE(IsInt<8>(value)) << value;
61  }
62
63  // Negative ones.
64  for (int32_t i = -1; i >= -128; i--) {
65    EXPECT_TRUE(IsInt<8>(i)) << i;
66  }
67
68  for (int32_t i = -129; i > -256; i--) {
69    EXPECT_FALSE(IsInt<8>(i)) << i;
70  }
71
72  // Do some lower ones randomly.
73  std::uniform_int_distribution<int32_t> uniform_dist2(INT32_MIN, -256);
74  for (size_t i = 0; i < 100; i++) {
75    int32_t value = uniform_dist2(e1);
76    EXPECT_FALSE(IsInt<8>(value)) << value;
77  }
78
79  // 64bit.
80  for (int64_t i = 0; i < 128; i++) {
81    EXPECT_TRUE(IsInt<8>(i)) << i;
82  }
83  for (int32_t i = 128; i < 255; i++) {
84    EXPECT_FALSE(IsInt<8>(i)) << i;
85  }
86  // Do some higher ones randomly.
87  std::uniform_int_distribution<int64_t> uniform_dist3(256, INT64_MAX);
88  for (size_t i = 0; i < 100; i++) {
89    int64_t value = uniform_dist3(e1);
90    EXPECT_FALSE(IsInt<8>(value)) << value;
91  }
92
93  // Negative ones.
94  for (int64_t i = -1; i >= -128; i--) {
95    EXPECT_TRUE(IsInt<8>(i)) << i;
96  }
97
98  for (int64_t i = -129; i > -256; i--) {
99    EXPECT_FALSE(IsInt<8>(i)) << i;
100  }
101
102  // Do some lower ones randomly.
103  std::uniform_int_distribution<int64_t> uniform_dist4(INT64_MIN, -256);
104  for (size_t i = 0; i < kRandomIterations; i++) {
105    int64_t value = uniform_dist4(e1);
106    EXPECT_FALSE(IsInt<8>(value)) << value;
107  }
108
109  int64_t value = INT64_C(0x1200000010);
110  x86_64::Immediate imm(value);
111  EXPECT_FALSE(imm.is_int8());
112  EXPECT_FALSE(imm.is_int16());
113  EXPECT_FALSE(imm.is_int32());
114  value = INT64_C(0x8000000000000001);
115  x86_64::Immediate imm2(value);
116  EXPECT_FALSE(imm2.is_int8());
117  EXPECT_FALSE(imm2.is_int16());
118  EXPECT_FALSE(imm2.is_int32());
119}
120
121struct X86_64CpuRegisterCompare {
122    bool operator()(const x86_64::CpuRegister& a, const x86_64::CpuRegister& b) const {
123        return a.AsRegister() < b.AsRegister();
124    }
125};
126
127class AssemblerX86_64Test : public AssemblerTest<x86_64::X86_64Assembler, x86_64::CpuRegister,
128                                                 x86_64::XmmRegister, x86_64::Immediate> {
129 public:
130  typedef AssemblerTest<x86_64::X86_64Assembler, x86_64::CpuRegister,
131                        x86_64::XmmRegister, x86_64::Immediate> Base;
132
133 protected:
134  // Get the typically used name for this architecture, e.g., aarch64, x86-64, ...
135  std::string GetArchitectureString() OVERRIDE {
136    return "x86_64";
137  }
138
139  std::string GetDisassembleParameters() OVERRIDE {
140    return " -D -bbinary -mi386:x86-64 -Mx86-64,addr64,data32 --no-show-raw-insn";
141  }
142
143  void SetUpHelpers() OVERRIDE {
144    if (registers_.size() == 0) {
145      registers_.push_back(new x86_64::CpuRegister(x86_64::RAX));
146      registers_.push_back(new x86_64::CpuRegister(x86_64::RBX));
147      registers_.push_back(new x86_64::CpuRegister(x86_64::RCX));
148      registers_.push_back(new x86_64::CpuRegister(x86_64::RDX));
149      registers_.push_back(new x86_64::CpuRegister(x86_64::RBP));
150      registers_.push_back(new x86_64::CpuRegister(x86_64::RSP));
151      registers_.push_back(new x86_64::CpuRegister(x86_64::RSI));
152      registers_.push_back(new x86_64::CpuRegister(x86_64::RDI));
153      registers_.push_back(new x86_64::CpuRegister(x86_64::R8));
154      registers_.push_back(new x86_64::CpuRegister(x86_64::R9));
155      registers_.push_back(new x86_64::CpuRegister(x86_64::R10));
156      registers_.push_back(new x86_64::CpuRegister(x86_64::R11));
157      registers_.push_back(new x86_64::CpuRegister(x86_64::R12));
158      registers_.push_back(new x86_64::CpuRegister(x86_64::R13));
159      registers_.push_back(new x86_64::CpuRegister(x86_64::R14));
160      registers_.push_back(new x86_64::CpuRegister(x86_64::R15));
161
162      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RAX), "eax");
163      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBX), "ebx");
164      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RCX), "ecx");
165      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDX), "edx");
166      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBP), "ebp");
167      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSP), "esp");
168      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSI), "esi");
169      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDI), "edi");
170      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R8), "r8d");
171      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R9), "r9d");
172      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R10), "r10d");
173      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R11), "r11d");
174      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R12), "r12d");
175      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R13), "r13d");
176      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R14), "r14d");
177      secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R15), "r15d");
178
179      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RAX), "ax");
180      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBX), "bx");
181      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RCX), "cx");
182      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDX), "dx");
183      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBP), "bp");
184      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSP), "sp");
185      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSI), "si");
186      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDI), "di");
187      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R8), "r8w");
188      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R9), "r9w");
189      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R10), "r10w");
190      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R11), "r11w");
191      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R12), "r12w");
192      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R13), "r13w");
193      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R14), "r14w");
194      tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R15), "r15w");
195
196      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RAX), "al");
197      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBX), "bl");
198      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RCX), "cl");
199      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDX), "dl");
200      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBP), "bpl");
201      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSP), "spl");
202      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSI), "sil");
203      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDI), "dil");
204      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R8), "r8b");
205      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R9), "r9b");
206      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R10), "r10b");
207      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R11), "r11b");
208      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R12), "r12b");
209      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R13), "r13b");
210      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R14), "r14b");
211      quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R15), "r15b");
212
213      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM0));
214      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM1));
215      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM2));
216      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM3));
217      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM4));
218      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM5));
219      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM6));
220      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM7));
221      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM8));
222      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM9));
223      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM10));
224      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM11));
225      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM12));
226      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM13));
227      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM14));
228      fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM15));
229    }
230  }
231
232  void TearDown() OVERRIDE {
233    AssemblerTest::TearDown();
234    STLDeleteElements(&registers_);
235    STLDeleteElements(&fp_registers_);
236  }
237
238  std::vector<x86_64::CpuRegister*> GetRegisters() OVERRIDE {
239    return registers_;
240  }
241
242  std::vector<x86_64::XmmRegister*> GetFPRegisters() OVERRIDE {
243    return fp_registers_;
244  }
245
246  x86_64::Immediate CreateImmediate(int64_t imm_value) OVERRIDE {
247    return x86_64::Immediate(imm_value);
248  }
249
250  std::string GetSecondaryRegisterName(const x86_64::CpuRegister& reg) OVERRIDE {
251    CHECK(secondary_register_names_.find(reg) != secondary_register_names_.end());
252    return secondary_register_names_[reg];
253  }
254
255  std::string GetTertiaryRegisterName(const x86_64::CpuRegister& reg) OVERRIDE {
256    CHECK(tertiary_register_names_.find(reg) != tertiary_register_names_.end());
257    return tertiary_register_names_[reg];
258  }
259
260  std::string GetQuaternaryRegisterName(const x86_64::CpuRegister& reg) OVERRIDE {
261    CHECK(quaternary_register_names_.find(reg) != quaternary_register_names_.end());
262    return quaternary_register_names_[reg];
263  }
264
265 private:
266  std::vector<x86_64::CpuRegister*> registers_;
267  std::map<x86_64::CpuRegister, std::string, X86_64CpuRegisterCompare> secondary_register_names_;
268  std::map<x86_64::CpuRegister, std::string, X86_64CpuRegisterCompare> tertiary_register_names_;
269  std::map<x86_64::CpuRegister, std::string, X86_64CpuRegisterCompare> quaternary_register_names_;
270
271  std::vector<x86_64::XmmRegister*> fp_registers_;
272};
273
274
275TEST_F(AssemblerX86_64Test, Toolchain) {
276  EXPECT_TRUE(CheckTools());
277}
278
279
280TEST_F(AssemblerX86_64Test, PushqRegs) {
281  DriverStr(RepeatR(&x86_64::X86_64Assembler::pushq, "pushq %{reg}"), "pushq");
282}
283
284TEST_F(AssemblerX86_64Test, PushqImm) {
285  DriverStr(RepeatI(&x86_64::X86_64Assembler::pushq, 4U, "pushq ${imm}"), "pushqi");
286}
287
288TEST_F(AssemblerX86_64Test, MovqRegs) {
289  DriverStr(RepeatRR(&x86_64::X86_64Assembler::movq, "movq %{reg2}, %{reg1}"), "movq");
290}
291
292TEST_F(AssemblerX86_64Test, MovqImm) {
293  DriverStr(RepeatRI(&x86_64::X86_64Assembler::movq, 8U, "movq ${imm}, %{reg}"), "movqi");
294}
295
296TEST_F(AssemblerX86_64Test, MovlRegs) {
297  DriverStr(Repeatrr(&x86_64::X86_64Assembler::movl, "mov %{reg2}, %{reg1}"), "movl");
298}
299
300TEST_F(AssemblerX86_64Test, MovlImm) {
301  DriverStr(Repeatri(&x86_64::X86_64Assembler::movl, 4U, "mov ${imm}, %{reg}"), "movli");
302}
303
304TEST_F(AssemblerX86_64Test, AddqRegs) {
305  DriverStr(RepeatRR(&x86_64::X86_64Assembler::addq, "addq %{reg2}, %{reg1}"), "addq");
306}
307
308TEST_F(AssemblerX86_64Test, AddqImm) {
309  DriverStr(RepeatRI(&x86_64::X86_64Assembler::addq, 4U, "addq ${imm}, %{reg}"), "addqi");
310}
311
312TEST_F(AssemblerX86_64Test, AddlRegs) {
313  DriverStr(Repeatrr(&x86_64::X86_64Assembler::addl, "add %{reg2}, %{reg1}"), "addl");
314}
315
316TEST_F(AssemblerX86_64Test, AddlImm) {
317  DriverStr(Repeatri(&x86_64::X86_64Assembler::addl, 4U, "add ${imm}, %{reg}"), "addli");
318}
319
320TEST_F(AssemblerX86_64Test, ImulqReg1) {
321  DriverStr(RepeatR(&x86_64::X86_64Assembler::imulq, "imulq %{reg}"), "imulq");
322}
323
324TEST_F(AssemblerX86_64Test, ImulqRegs) {
325  DriverStr(RepeatRR(&x86_64::X86_64Assembler::imulq, "imulq %{reg2}, %{reg1}"), "imulq");
326}
327
328TEST_F(AssemblerX86_64Test, ImulqImm) {
329  DriverStr(RepeatRI(&x86_64::X86_64Assembler::imulq, 4U, "imulq ${imm}, %{reg}, %{reg}"),
330            "imulqi");
331}
332
333TEST_F(AssemblerX86_64Test, ImullRegs) {
334  DriverStr(Repeatrr(&x86_64::X86_64Assembler::imull, "imul %{reg2}, %{reg1}"), "imull");
335}
336
337TEST_F(AssemblerX86_64Test, ImullImm) {
338  DriverStr(Repeatri(&x86_64::X86_64Assembler::imull, 4U, "imull ${imm}, %{reg}, %{reg}"),
339            "imulli");
340}
341
342TEST_F(AssemblerX86_64Test, Mull) {
343  DriverStr(Repeatr(&x86_64::X86_64Assembler::mull, "mull %{reg}"), "mull");
344}
345
346TEST_F(AssemblerX86_64Test, SubqRegs) {
347  DriverStr(RepeatRR(&x86_64::X86_64Assembler::subq, "subq %{reg2}, %{reg1}"), "subq");
348}
349
350TEST_F(AssemblerX86_64Test, SubqImm) {
351  DriverStr(RepeatRI(&x86_64::X86_64Assembler::subq, 4U, "subq ${imm}, %{reg}"), "subqi");
352}
353
354TEST_F(AssemblerX86_64Test, SublRegs) {
355  DriverStr(Repeatrr(&x86_64::X86_64Assembler::subl, "sub %{reg2}, %{reg1}"), "subl");
356}
357
358TEST_F(AssemblerX86_64Test, SublImm) {
359  DriverStr(Repeatri(&x86_64::X86_64Assembler::subl, 4U, "sub ${imm}, %{reg}"), "subli");
360}
361
362// Shll only allows CL as the shift count.
363std::string shll_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
364  std::ostringstream str;
365
366  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
367
368  x86_64::CpuRegister shifter(x86_64::RCX);
369  for (auto reg : registers) {
370    assembler->shll(*reg, shifter);
371    str << "shll %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n";
372  }
373
374  return str.str();
375}
376
377TEST_F(AssemblerX86_64Test, ShllReg) {
378  DriverFn(&shll_fn, "shll");
379}
380
381TEST_F(AssemblerX86_64Test, ShllImm) {
382  DriverStr(Repeatri(&x86_64::X86_64Assembler::shll, 1U, "shll ${imm}, %{reg}"), "shlli");
383}
384
385// Shlq only allows CL as the shift count.
386std::string shlq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
387  std::ostringstream str;
388
389  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
390
391  x86_64::CpuRegister shifter(x86_64::RCX);
392  for (auto reg : registers) {
393    assembler->shlq(*reg, shifter);
394    str << "shlq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n";
395  }
396
397  return str.str();
398}
399
400TEST_F(AssemblerX86_64Test, ShlqReg) {
401  DriverFn(&shlq_fn, "shlq");
402}
403
404TEST_F(AssemblerX86_64Test, ShlqImm) {
405  DriverStr(RepeatRI(&x86_64::X86_64Assembler::shlq, 1U, "shlq ${imm}, %{reg}"), "shlqi");
406}
407
408// Shrl only allows CL as the shift count.
409std::string shrl_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
410  std::ostringstream str;
411
412  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
413
414  x86_64::CpuRegister shifter(x86_64::RCX);
415  for (auto reg : registers) {
416    assembler->shrl(*reg, shifter);
417    str << "shrl %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n";
418  }
419
420  return str.str();
421}
422
423TEST_F(AssemblerX86_64Test, ShrlReg) {
424  DriverFn(&shrl_fn, "shrl");
425}
426
427TEST_F(AssemblerX86_64Test, ShrlImm) {
428  DriverStr(Repeatri(&x86_64::X86_64Assembler::shrl, 1U, "shrl ${imm}, %{reg}"), "shrli");
429}
430
431// Shrq only allows CL as the shift count.
432std::string shrq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
433  std::ostringstream str;
434
435  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
436
437  x86_64::CpuRegister shifter(x86_64::RCX);
438  for (auto reg : registers) {
439    assembler->shrq(*reg, shifter);
440    str << "shrq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n";
441  }
442
443  return str.str();
444}
445
446TEST_F(AssemblerX86_64Test, ShrqReg) {
447  DriverFn(&shrq_fn, "shrq");
448}
449
450TEST_F(AssemblerX86_64Test, ShrqImm) {
451  DriverStr(RepeatRI(&x86_64::X86_64Assembler::shrq, 1U, "shrq ${imm}, %{reg}"), "shrqi");
452}
453
454// Sarl only allows CL as the shift count.
455std::string sarl_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
456  std::ostringstream str;
457
458  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
459
460  x86_64::CpuRegister shifter(x86_64::RCX);
461  for (auto reg : registers) {
462    assembler->sarl(*reg, shifter);
463    str << "sarl %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n";
464  }
465
466  return str.str();
467}
468
469TEST_F(AssemblerX86_64Test, SarlReg) {
470  DriverFn(&sarl_fn, "sarl");
471}
472
473TEST_F(AssemblerX86_64Test, SarlImm) {
474  DriverStr(Repeatri(&x86_64::X86_64Assembler::sarl, 1U, "sarl ${imm}, %{reg}"), "sarli");
475}
476
477// Sarq only allows CL as the shift count.
478std::string sarq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
479  std::ostringstream str;
480
481  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
482
483  x86_64::CpuRegister shifter(x86_64::RCX);
484  for (auto reg : registers) {
485    assembler->sarq(*reg, shifter);
486    str << "sarq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n";
487  }
488
489  return str.str();
490}
491
492TEST_F(AssemblerX86_64Test, SarqReg) {
493  DriverFn(&sarq_fn, "sarq");
494}
495
496TEST_F(AssemblerX86_64Test, SarqImm) {
497  DriverStr(RepeatRI(&x86_64::X86_64Assembler::sarq, 1U, "sarq ${imm}, %{reg}"), "sarqi");
498}
499
500// Rorl only allows CL as the shift count.
501std::string rorl_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
502  std::ostringstream str;
503
504  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
505
506  x86_64::CpuRegister shifter(x86_64::RCX);
507  for (auto reg : registers) {
508    assembler->rorl(*reg, shifter);
509    str << "rorl %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n";
510  }
511
512  return str.str();
513}
514
515TEST_F(AssemblerX86_64Test, RorlReg) {
516  DriverFn(&rorl_fn, "rorl");
517}
518
519TEST_F(AssemblerX86_64Test, RorlImm) {
520  DriverStr(Repeatri(&x86_64::X86_64Assembler::rorl, 1U, "rorl ${imm}, %{reg}"), "rorli");
521}
522
523// Roll only allows CL as the shift count.
524std::string roll_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
525  std::ostringstream str;
526
527  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
528
529  x86_64::CpuRegister shifter(x86_64::RCX);
530  for (auto reg : registers) {
531    assembler->roll(*reg, shifter);
532    str << "roll %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n";
533  }
534
535  return str.str();
536}
537
538TEST_F(AssemblerX86_64Test, RollReg) {
539  DriverFn(&roll_fn, "roll");
540}
541
542TEST_F(AssemblerX86_64Test, RollImm) {
543  DriverStr(Repeatri(&x86_64::X86_64Assembler::roll, 1U, "roll ${imm}, %{reg}"), "rolli");
544}
545
546// Rorq only allows CL as the shift count.
547std::string rorq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
548  std::ostringstream str;
549
550  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
551
552  x86_64::CpuRegister shifter(x86_64::RCX);
553  for (auto reg : registers) {
554    assembler->rorq(*reg, shifter);
555    str << "rorq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n";
556  }
557
558  return str.str();
559}
560
561TEST_F(AssemblerX86_64Test, RorqReg) {
562  DriverFn(&rorq_fn, "rorq");
563}
564
565TEST_F(AssemblerX86_64Test, RorqImm) {
566  DriverStr(RepeatRI(&x86_64::X86_64Assembler::rorq, 1U, "rorq ${imm}, %{reg}"), "rorqi");
567}
568
569// Rolq only allows CL as the shift count.
570std::string rolq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) {
571  std::ostringstream str;
572
573  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
574
575  x86_64::CpuRegister shifter(x86_64::RCX);
576  for (auto reg : registers) {
577    assembler->rolq(*reg, shifter);
578    str << "rolq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n";
579  }
580
581  return str.str();
582}
583
584TEST_F(AssemblerX86_64Test, RolqReg) {
585  DriverFn(&rolq_fn, "rolq");
586}
587
588TEST_F(AssemblerX86_64Test, RolqImm) {
589  DriverStr(RepeatRI(&x86_64::X86_64Assembler::rolq, 1U, "rolq ${imm}, %{reg}"), "rolqi");
590}
591
592TEST_F(AssemblerX86_64Test, CmpqRegs) {
593  DriverStr(RepeatRR(&x86_64::X86_64Assembler::cmpq, "cmpq %{reg2}, %{reg1}"), "cmpq");
594}
595
596TEST_F(AssemblerX86_64Test, CmpqImm) {
597  DriverStr(RepeatRI(&x86_64::X86_64Assembler::cmpq, 4U  /* cmpq only supports 32b imm */,
598                     "cmpq ${imm}, %{reg}"), "cmpqi");
599}
600
601TEST_F(AssemblerX86_64Test, CmplRegs) {
602  DriverStr(Repeatrr(&x86_64::X86_64Assembler::cmpl, "cmp %{reg2}, %{reg1}"), "cmpl");
603}
604
605TEST_F(AssemblerX86_64Test, CmplImm) {
606  DriverStr(Repeatri(&x86_64::X86_64Assembler::cmpl, 4U, "cmpl ${imm}, %{reg}"), "cmpli");
607}
608
609TEST_F(AssemblerX86_64Test, Testl) {
610  // Note: uses different order for GCC than usual. This makes GCC happy, and doesn't have an
611  // impact on functional correctness.
612  DriverStr(Repeatrr(&x86_64::X86_64Assembler::testl, "testl %{reg1}, %{reg2}"), "testl");
613}
614
615TEST_F(AssemblerX86_64Test, Negq) {
616  DriverStr(RepeatR(&x86_64::X86_64Assembler::negq, "negq %{reg}"), "negq");
617}
618
619TEST_F(AssemblerX86_64Test, Negl) {
620  DriverStr(Repeatr(&x86_64::X86_64Assembler::negl, "negl %{reg}"), "negl");
621}
622
623TEST_F(AssemblerX86_64Test, Notq) {
624  DriverStr(RepeatR(&x86_64::X86_64Assembler::notq, "notq %{reg}"), "notq");
625}
626
627TEST_F(AssemblerX86_64Test, Notl) {
628  DriverStr(Repeatr(&x86_64::X86_64Assembler::notl, "notl %{reg}"), "notl");
629}
630
631TEST_F(AssemblerX86_64Test, AndqRegs) {
632  DriverStr(RepeatRR(&x86_64::X86_64Assembler::andq, "andq %{reg2}, %{reg1}"), "andq");
633}
634
635TEST_F(AssemblerX86_64Test, AndqImm) {
636  DriverStr(RepeatRI(&x86_64::X86_64Assembler::andq, 4U  /* andq only supports 32b imm */,
637                     "andq ${imm}, %{reg}"), "andqi");
638}
639
640TEST_F(AssemblerX86_64Test, AndlRegs) {
641  DriverStr(Repeatrr(&x86_64::X86_64Assembler::andl, "andl %{reg2}, %{reg1}"), "andl");
642}
643
644TEST_F(AssemblerX86_64Test, AndlImm) {
645  DriverStr(Repeatri(&x86_64::X86_64Assembler::andl, 4U, "andl ${imm}, %{reg}"), "andli");
646}
647
648TEST_F(AssemblerX86_64Test, OrqRegs) {
649  DriverStr(RepeatRR(&x86_64::X86_64Assembler::orq, "orq %{reg2}, %{reg1}"), "orq");
650}
651
652TEST_F(AssemblerX86_64Test, OrlRegs) {
653  DriverStr(Repeatrr(&x86_64::X86_64Assembler::orl, "orl %{reg2}, %{reg1}"), "orl");
654}
655
656TEST_F(AssemblerX86_64Test, OrlImm) {
657  DriverStr(Repeatri(&x86_64::X86_64Assembler::orl, 4U, "orl ${imm}, %{reg}"), "orli");
658}
659
660TEST_F(AssemblerX86_64Test, XorqRegs) {
661  DriverStr(RepeatRR(&x86_64::X86_64Assembler::xorq, "xorq %{reg2}, %{reg1}"), "xorq");
662}
663
664TEST_F(AssemblerX86_64Test, XorqImm) {
665  DriverStr(RepeatRI(&x86_64::X86_64Assembler::xorq, 4U, "xorq ${imm}, %{reg}"), "xorqi");
666}
667
668TEST_F(AssemblerX86_64Test, XorlRegs) {
669  DriverStr(Repeatrr(&x86_64::X86_64Assembler::xorl, "xor %{reg2}, %{reg1}"), "xorl");
670}
671
672TEST_F(AssemblerX86_64Test, XorlImm) {
673  DriverStr(Repeatri(&x86_64::X86_64Assembler::xorl, 4U, "xor ${imm}, %{reg}"), "xorli");
674}
675
676TEST_F(AssemblerX86_64Test, Xchgq) {
677  DriverStr(RepeatRR(&x86_64::X86_64Assembler::xchgq, "xchgq %{reg2}, %{reg1}"), "xchgq");
678}
679
680TEST_F(AssemblerX86_64Test, Xchgl) {
681  // Test is disabled because GCC generates 0x87 0xC0 for xchgl eax, eax. All other cases are the
682  // same. Anyone know why it doesn't emit a simple 0x90? It does so for xchgq rax, rax...
683  // DriverStr(Repeatrr(&x86_64::X86_64Assembler::xchgl, "xchgl %{reg2}, %{reg1}"), "xchgl");
684}
685
686TEST_F(AssemblerX86_64Test, LockCmpxchgl) {
687  GetAssembler()->LockCmpxchgl(x86_64::Address(
688      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12),
689      x86_64::CpuRegister(x86_64::RSI));
690  GetAssembler()->LockCmpxchgl(x86_64::Address(
691      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12),
692      x86_64::CpuRegister(x86_64::RSI));
693  GetAssembler()->LockCmpxchgl(x86_64::Address(
694      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12),
695      x86_64::CpuRegister(x86_64::R8));
696  GetAssembler()->LockCmpxchgl(x86_64::Address(
697      x86_64::CpuRegister(x86_64::R13), 0), x86_64::CpuRegister(x86_64::RSI));
698  GetAssembler()->LockCmpxchgl(x86_64::Address(
699      x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0),
700      x86_64::CpuRegister(x86_64::RSI));
701  const char* expected =
702    "lock cmpxchgl %ESI, 0xc(%RDI,%RBX,4)\n"
703    "lock cmpxchgl %ESI, 0xc(%RDI,%R9,4)\n"
704    "lock cmpxchgl %R8d, 0xc(%RDI,%R9,4)\n"
705    "lock cmpxchgl %ESI, (%R13)\n"
706    "lock cmpxchgl %ESI, (%R13,%R9,1)\n";
707
708  DriverStr(expected, "lock_cmpxchgl");
709}
710
711TEST_F(AssemblerX86_64Test, LockCmpxchgq) {
712  GetAssembler()->LockCmpxchgq(x86_64::Address(
713      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12),
714      x86_64::CpuRegister(x86_64::RSI));
715  GetAssembler()->LockCmpxchgq(x86_64::Address(
716      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12),
717      x86_64::CpuRegister(x86_64::RSI));
718  GetAssembler()->LockCmpxchgq(x86_64::Address(
719      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12),
720      x86_64::CpuRegister(x86_64::R8));
721  GetAssembler()->LockCmpxchgq(x86_64::Address(
722      x86_64::CpuRegister(x86_64::R13), 0), x86_64::CpuRegister(x86_64::RSI));
723  GetAssembler()->LockCmpxchgq(x86_64::Address(
724      x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0),
725      x86_64::CpuRegister(x86_64::RSI));
726  const char* expected =
727    "lock cmpxchg %RSI, 0xc(%RDI,%RBX,4)\n"
728    "lock cmpxchg %RSI, 0xc(%RDI,%R9,4)\n"
729    "lock cmpxchg %R8, 0xc(%RDI,%R9,4)\n"
730    "lock cmpxchg %RSI, (%R13)\n"
731    "lock cmpxchg %RSI, (%R13,%R9,1)\n";
732
733  DriverStr(expected, "lock_cmpxchg");
734}
735
736TEST_F(AssemblerX86_64Test, Movl) {
737  GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address(
738      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
739  GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address(
740      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
741  GetAssembler()->movl(x86_64::CpuRegister(x86_64::R8), x86_64::Address(
742      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
743  GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address(
744      x86_64::CpuRegister(x86_64::R13), 0));
745  GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address(
746      x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0));
747  const char* expected =
748    "movl 0xc(%RDI,%RBX,4), %EAX\n"
749    "movl 0xc(%RDI,%R9,4), %EAX\n"
750    "movl 0xc(%RDI,%R9,4), %R8d\n"
751    "movl (%R13), %EAX\n"
752    "movl (%R13,%R9,1), %EAX\n";
753
754  DriverStr(expected, "movl");
755}
756
757TEST_F(AssemblerX86_64Test, Movw) {
758  GetAssembler()->movw(x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
759                       x86_64::CpuRegister(x86_64::R9));
760  GetAssembler()->movw(x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
761                       x86_64::Immediate(0));
762  GetAssembler()->movw(x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0),
763                       x86_64::Immediate(0));
764  GetAssembler()->movw(x86_64::Address(x86_64::CpuRegister(x86_64::R14), 0),
765                       x86_64::Immediate(0));
766  const char* expected =
767      "movw %R9w, 0(%RAX)\n"
768      "movw $0, 0(%RAX)\n"
769      "movw $0, 0(%R9)\n"
770      "movw $0, 0(%R14)\n";
771  DriverStr(expected, "movw");
772}
773
774TEST_F(AssemblerX86_64Test, Cmpw) {
775  GetAssembler()->cmpw(x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
776                       x86_64::Immediate(0));
777  GetAssembler()->cmpw(x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0),
778                       x86_64::Immediate(0));
779  GetAssembler()->cmpw(x86_64::Address(x86_64::CpuRegister(x86_64::R14), 0),
780                       x86_64::Immediate(0));
781  const char* expected =
782      "cmpw $0, 0(%RAX)\n"
783      "cmpw $0, 0(%R9)\n"
784      "cmpw $0, 0(%R14)\n";
785  DriverStr(expected, "cmpw");
786}
787
788TEST_F(AssemblerX86_64Test, MovqAddrImm) {
789  GetAssembler()->movq(x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
790                       x86_64::Immediate(-5));
791  const char* expected = "movq $-5, 0(%RAX)\n";
792  DriverStr(expected, "movq");
793}
794
795TEST_F(AssemblerX86_64Test, Movntl) {
796  GetAssembler()->movntl(x86_64::Address(
797      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12), x86_64::CpuRegister(x86_64::RAX));
798  GetAssembler()->movntl(x86_64::Address(
799      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12), x86_64::CpuRegister(x86_64::RAX));
800  GetAssembler()->movntl(x86_64::Address(
801      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12), x86_64::CpuRegister(x86_64::RAX));
802  GetAssembler()->movntl(x86_64::Address(x86_64::CpuRegister(x86_64::R13), 0), x86_64::CpuRegister(x86_64::RAX));
803  GetAssembler()->movntl(x86_64::Address(
804      x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0), x86_64::CpuRegister(x86_64::R9));
805  const char* expected =
806    "movntil %EAX, 0xc(%RDI,%RBX,4)\n"
807    "movntil %EAX, 0xc(%RDI,%R9,4)\n"
808    "movntil %EAX, 0xc(%RDI,%R9,4)\n"
809    "movntil %EAX, (%R13)\n"
810    "movntil %R9d, (%R13,%R9,1)\n";
811
812  DriverStr(expected, "movntl");
813}
814
815TEST_F(AssemblerX86_64Test, Movntq) {
816  GetAssembler()->movntq(x86_64::Address(
817      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12), x86_64::CpuRegister(x86_64::RAX));
818  GetAssembler()->movntq(x86_64::Address(
819      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12), x86_64::CpuRegister(x86_64::RAX));
820  GetAssembler()->movntq(x86_64::Address(
821      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12), x86_64::CpuRegister(x86_64::RAX));
822  GetAssembler()->movntq(x86_64::Address(x86_64::CpuRegister(x86_64::R13), 0), x86_64::CpuRegister(x86_64::RAX));
823  GetAssembler()->movntq(x86_64::Address(
824      x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0), x86_64::CpuRegister(x86_64::R9));
825  const char* expected =
826    "movntiq %RAX, 0xc(%RDI,%RBX,4)\n"
827    "movntiq %RAX, 0xc(%RDI,%R9,4)\n"
828    "movntiq %RAX, 0xc(%RDI,%R9,4)\n"
829    "movntiq %RAX, (%R13)\n"
830    "movntiq %R9, (%R13,%R9,1)\n";
831
832  DriverStr(expected, "movntq");
833}
834
835TEST_F(AssemblerX86_64Test, Cvtsi2ssAddr) {
836  GetAssembler()->cvtsi2ss(x86_64::XmmRegister(x86_64::XMM0),
837                           x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
838                           false);
839  GetAssembler()->cvtsi2ss(x86_64::XmmRegister(x86_64::XMM0),
840                           x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
841                           true);
842  const char* expected = "cvtsi2ss 0(%RAX), %xmm0\n"
843                         "cvtsi2ssq 0(%RAX), %xmm0\n";
844  DriverStr(expected, "cvtsi2ss");
845}
846
847TEST_F(AssemblerX86_64Test, Cvtsi2sdAddr) {
848  GetAssembler()->cvtsi2sd(x86_64::XmmRegister(x86_64::XMM0),
849                           x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
850                           false);
851  GetAssembler()->cvtsi2sd(x86_64::XmmRegister(x86_64::XMM0),
852                           x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0),
853                           true);
854  const char* expected = "cvtsi2sd 0(%RAX), %xmm0\n"
855                         "cvtsi2sdq 0(%RAX), %xmm0\n";
856  DriverStr(expected, "cvtsi2sd");
857}
858
859TEST_F(AssemblerX86_64Test, CmpqAddr) {
860  GetAssembler()->cmpq(x86_64::CpuRegister(x86_64::R12),
861                       x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0));
862  const char* expected = "cmpq 0(%R9), %R12\n";
863  DriverStr(expected, "cmpq");
864}
865
866TEST_F(AssemblerX86_64Test, MovsxdAddr) {
867  GetAssembler()->movsxd(x86_64::CpuRegister(x86_64::R12),
868                       x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0));
869  const char* expected = "movslq 0(%R9), %R12\n";
870  DriverStr(expected, "movsxd");
871}
872
873TEST_F(AssemblerX86_64Test, TestqAddr) {
874  GetAssembler()->testq(x86_64::CpuRegister(x86_64::R12),
875                        x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0));
876  const char* expected = "testq 0(%R9), %R12\n";
877  DriverStr(expected, "testq");
878}
879
880TEST_F(AssemblerX86_64Test, AddqAddr) {
881  GetAssembler()->addq(x86_64::CpuRegister(x86_64::R12),
882                        x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0));
883  const char* expected = "addq 0(%R9), %R12\n";
884  DriverStr(expected, "addq");
885}
886
887TEST_F(AssemblerX86_64Test, SubqAddr) {
888  GetAssembler()->subq(x86_64::CpuRegister(x86_64::R12),
889                        x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0));
890  const char* expected = "subq 0(%R9), %R12\n";
891  DriverStr(expected, "subq");
892}
893
894TEST_F(AssemblerX86_64Test, Cvtss2sdAddr) {
895  GetAssembler()->cvtss2sd(x86_64::XmmRegister(x86_64::XMM0),
896                           x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
897  const char* expected = "cvtss2sd 0(%RAX), %xmm0\n";
898  DriverStr(expected, "cvtss2sd");
899}
900
901TEST_F(AssemblerX86_64Test, Cvtsd2ssAddr) {
902  GetAssembler()->cvtsd2ss(x86_64::XmmRegister(x86_64::XMM0),
903                           x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
904  const char* expected = "cvtsd2ss 0(%RAX), %xmm0\n";
905  DriverStr(expected, "cvtsd2ss");
906}
907
908TEST_F(AssemblerX86_64Test, ComissAddr) {
909  GetAssembler()->comiss(x86_64::XmmRegister(x86_64::XMM14),
910                           x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
911  const char* expected = "comiss 0(%RAX), %xmm14\n";
912  DriverStr(expected, "comiss");
913}
914
915TEST_F(AssemblerX86_64Test, ComisdAddr) {
916  GetAssembler()->comisd(x86_64::XmmRegister(x86_64::XMM0),
917                           x86_64::Address(x86_64::CpuRegister(x86_64::R9), 0));
918  const char* expected = "comisd 0(%R9), %xmm0\n";
919  DriverStr(expected, "comisd");
920}
921
922TEST_F(AssemblerX86_64Test, UComissAddr) {
923  GetAssembler()->ucomiss(x86_64::XmmRegister(x86_64::XMM0),
924                           x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
925  const char* expected = "ucomiss 0(%RAX), %xmm0\n";
926  DriverStr(expected, "ucomiss");
927}
928
929TEST_F(AssemblerX86_64Test, UComisdAddr) {
930  GetAssembler()->ucomisd(x86_64::XmmRegister(x86_64::XMM0),
931                           x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
932  const char* expected = "ucomisd 0(%RAX), %xmm0\n";
933  DriverStr(expected, "ucomisd");
934}
935
936TEST_F(AssemblerX86_64Test, Andq) {
937  GetAssembler()->andq(x86_64::CpuRegister(x86_64::R9),
938                           x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
939  const char* expected = "andq 0(%RAX), %r9\n";
940  DriverStr(expected, "andq");
941}
942
943TEST_F(AssemblerX86_64Test, Orq) {
944  GetAssembler()->orq(x86_64::CpuRegister(x86_64::R9),
945                           x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
946  const char* expected = "orq 0(%RAX), %r9\n";
947  DriverStr(expected, "orq");
948}
949
950TEST_F(AssemblerX86_64Test, Xorq) {
951  GetAssembler()->xorq(x86_64::CpuRegister(x86_64::R9),
952                           x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0));
953  const char* expected = "xorq 0(%RAX), %r9\n";
954  DriverStr(expected, "xorq");
955}
956
957TEST_F(AssemblerX86_64Test, RepneScasw) {
958  GetAssembler()->repne_scasw();
959  const char* expected = "repne scasw\n";
960  DriverStr(expected, "repne_scasw");
961}
962
963TEST_F(AssemblerX86_64Test, RepMovsw) {
964  GetAssembler()->rep_movsw();
965  const char* expected = "rep movsw\n";
966  DriverStr(expected, "rep_movsw");
967}
968
969TEST_F(AssemblerX86_64Test, Movsxd) {
970  DriverStr(RepeatRr(&x86_64::X86_64Assembler::movsxd, "movsxd %{reg2}, %{reg1}"), "movsxd");
971}
972
973///////////////////
974// FP Operations //
975///////////////////
976
977TEST_F(AssemblerX86_64Test, Movaps) {
978  DriverStr(RepeatFF(&x86_64::X86_64Assembler::movaps, "movaps %{reg2}, %{reg1}"), "movaps");
979}
980
981TEST_F(AssemblerX86_64Test, Movss) {
982  DriverStr(RepeatFF(&x86_64::X86_64Assembler::movss, "movss %{reg2}, %{reg1}"), "movss");
983}
984
985TEST_F(AssemblerX86_64Test, Movsd) {
986  DriverStr(RepeatFF(&x86_64::X86_64Assembler::movsd, "movsd %{reg2}, %{reg1}"), "movsd");
987}
988
989TEST_F(AssemblerX86_64Test, Movd1) {
990  DriverStr(RepeatFR(&x86_64::X86_64Assembler::movd, "movd %{reg2}, %{reg1}"), "movd.1");
991}
992
993TEST_F(AssemblerX86_64Test, Movd2) {
994  DriverStr(RepeatRF(&x86_64::X86_64Assembler::movd, "movd %{reg2}, %{reg1}"), "movd.2");
995}
996
997TEST_F(AssemblerX86_64Test, Addss) {
998  DriverStr(RepeatFF(&x86_64::X86_64Assembler::addss, "addss %{reg2}, %{reg1}"), "addss");
999}
1000
1001TEST_F(AssemblerX86_64Test, Addsd) {
1002  DriverStr(RepeatFF(&x86_64::X86_64Assembler::addsd, "addsd %{reg2}, %{reg1}"), "addsd");
1003}
1004
1005TEST_F(AssemblerX86_64Test, Subss) {
1006  DriverStr(RepeatFF(&x86_64::X86_64Assembler::subss, "subss %{reg2}, %{reg1}"), "subss");
1007}
1008
1009TEST_F(AssemblerX86_64Test, Subsd) {
1010  DriverStr(RepeatFF(&x86_64::X86_64Assembler::subsd, "subsd %{reg2}, %{reg1}"), "subsd");
1011}
1012
1013TEST_F(AssemblerX86_64Test, Mulss) {
1014  DriverStr(RepeatFF(&x86_64::X86_64Assembler::mulss, "mulss %{reg2}, %{reg1}"), "mulss");
1015}
1016
1017TEST_F(AssemblerX86_64Test, Mulsd) {
1018  DriverStr(RepeatFF(&x86_64::X86_64Assembler::mulsd, "mulsd %{reg2}, %{reg1}"), "mulsd");
1019}
1020
1021TEST_F(AssemblerX86_64Test, Divss) {
1022  DriverStr(RepeatFF(&x86_64::X86_64Assembler::divss, "divss %{reg2}, %{reg1}"), "divss");
1023}
1024
1025TEST_F(AssemblerX86_64Test, Divsd) {
1026  DriverStr(RepeatFF(&x86_64::X86_64Assembler::divsd, "divsd %{reg2}, %{reg1}"), "divsd");
1027}
1028
1029TEST_F(AssemblerX86_64Test, Cvtsi2ss) {
1030  DriverStr(RepeatFr(&x86_64::X86_64Assembler::cvtsi2ss, "cvtsi2ss %{reg2}, %{reg1}"), "cvtsi2ss");
1031}
1032
1033TEST_F(AssemblerX86_64Test, Cvtsi2sd) {
1034  DriverStr(RepeatFr(&x86_64::X86_64Assembler::cvtsi2sd, "cvtsi2sd %{reg2}, %{reg1}"), "cvtsi2sd");
1035}
1036
1037
1038TEST_F(AssemblerX86_64Test, Cvtss2si) {
1039  DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvtss2si, "cvtss2si %{reg2}, %{reg1}"), "cvtss2si");
1040}
1041
1042
1043TEST_F(AssemblerX86_64Test, Cvtss2sd) {
1044  DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtss2sd, "cvtss2sd %{reg2}, %{reg1}"), "cvtss2sd");
1045}
1046
1047
1048TEST_F(AssemblerX86_64Test, Cvtsd2si) {
1049  DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvtsd2si, "cvtsd2si %{reg2}, %{reg1}"), "cvtsd2si");
1050}
1051
1052TEST_F(AssemblerX86_64Test, Cvttss2si) {
1053  DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvttss2si, "cvttss2si %{reg2}, %{reg1}"),
1054            "cvttss2si");
1055}
1056
1057TEST_F(AssemblerX86_64Test, Cvttsd2si) {
1058  DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvttsd2si, "cvttsd2si %{reg2}, %{reg1}"),
1059            "cvttsd2si");
1060}
1061
1062TEST_F(AssemblerX86_64Test, Cvtsd2ss) {
1063  DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtsd2ss, "cvtsd2ss %{reg2}, %{reg1}"), "cvtsd2ss");
1064}
1065
1066TEST_F(AssemblerX86_64Test, Cvtdq2pd) {
1067  DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtdq2pd, "cvtdq2pd %{reg2}, %{reg1}"), "cvtdq2pd");
1068}
1069
1070TEST_F(AssemblerX86_64Test, Comiss) {
1071  DriverStr(RepeatFF(&x86_64::X86_64Assembler::comiss, "comiss %{reg2}, %{reg1}"), "comiss");
1072}
1073
1074TEST_F(AssemblerX86_64Test, Comisd) {
1075  DriverStr(RepeatFF(&x86_64::X86_64Assembler::comisd, "comisd %{reg2}, %{reg1}"), "comisd");
1076}
1077
1078TEST_F(AssemblerX86_64Test, Ucomiss) {
1079  DriverStr(RepeatFF(&x86_64::X86_64Assembler::ucomiss, "ucomiss %{reg2}, %{reg1}"), "ucomiss");
1080}
1081
1082TEST_F(AssemblerX86_64Test, Ucomisd) {
1083  DriverStr(RepeatFF(&x86_64::X86_64Assembler::ucomisd, "ucomisd %{reg2}, %{reg1}"), "ucomisd");
1084}
1085
1086TEST_F(AssemblerX86_64Test, Sqrtss) {
1087  DriverStr(RepeatFF(&x86_64::X86_64Assembler::sqrtss, "sqrtss %{reg2}, %{reg1}"), "sqrtss");
1088}
1089
1090TEST_F(AssemblerX86_64Test, Sqrtsd) {
1091  DriverStr(RepeatFF(&x86_64::X86_64Assembler::sqrtsd, "sqrtsd %{reg2}, %{reg1}"), "sqrtsd");
1092}
1093
1094TEST_F(AssemblerX86_64Test, Roundss) {
1095  DriverStr(RepeatFFI(&x86_64::X86_64Assembler::roundss, 1, "roundss ${imm}, %{reg2}, %{reg1}"), "roundss");
1096}
1097
1098TEST_F(AssemblerX86_64Test, Roundsd) {
1099  DriverStr(RepeatFFI(&x86_64::X86_64Assembler::roundsd, 1, "roundsd ${imm}, %{reg2}, %{reg1}"), "roundsd");
1100}
1101
1102TEST_F(AssemblerX86_64Test, Xorps) {
1103  DriverStr(RepeatFF(&x86_64::X86_64Assembler::xorps, "xorps %{reg2}, %{reg1}"), "xorps");
1104}
1105
1106TEST_F(AssemblerX86_64Test, Xorpd) {
1107  DriverStr(RepeatFF(&x86_64::X86_64Assembler::xorpd, "xorpd %{reg2}, %{reg1}"), "xorpd");
1108}
1109
1110TEST_F(AssemblerX86_64Test, Andps) {
1111  DriverStr(RepeatFF(&x86_64::X86_64Assembler::andps, "andps %{reg2}, %{reg1}"), "andps");
1112}
1113
1114TEST_F(AssemblerX86_64Test, Andpd) {
1115  DriverStr(RepeatFF(&x86_64::X86_64Assembler::andpd, "andpd %{reg2}, %{reg1}"), "andpd");
1116}
1117
1118TEST_F(AssemblerX86_64Test, Orps) {
1119  DriverStr(RepeatFF(&x86_64::X86_64Assembler::orps, "orps %{reg2}, %{reg1}"), "orps");
1120}
1121
1122TEST_F(AssemblerX86_64Test, Orpd) {
1123  DriverStr(RepeatFF(&x86_64::X86_64Assembler::orpd, "orpd %{reg2}, %{reg1}"), "orpd");
1124}
1125
1126TEST_F(AssemblerX86_64Test, UcomissAddress) {
1127  GetAssembler()->ucomiss(x86_64::XmmRegister(x86_64::XMM0), x86_64::Address(
1128      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1129  GetAssembler()->ucomiss(x86_64::XmmRegister(x86_64::XMM1), x86_64::Address(
1130      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
1131  GetAssembler()->ucomiss(x86_64::XmmRegister(x86_64::XMM2), x86_64::Address(
1132      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
1133  GetAssembler()->ucomiss(x86_64::XmmRegister(x86_64::XMM3), x86_64::Address(
1134      x86_64::CpuRegister(x86_64::R13), 0));
1135  GetAssembler()->ucomiss(x86_64::XmmRegister(x86_64::XMM4), x86_64::Address(
1136      x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0));
1137  const char* expected =
1138    "ucomiss 0xc(%RDI,%RBX,4), %xmm0\n"
1139    "ucomiss 0xc(%RDI,%R9,4), %xmm1\n"
1140    "ucomiss 0xc(%RDI,%R9,4), %xmm2\n"
1141    "ucomiss (%R13), %xmm3\n"
1142    "ucomiss (%R13,%R9,1), %xmm4\n";
1143
1144  DriverStr(expected, "ucomiss_address");
1145}
1146
1147TEST_F(AssemblerX86_64Test, UcomisdAddress) {
1148  GetAssembler()->ucomisd(x86_64::XmmRegister(x86_64::XMM0), x86_64::Address(
1149      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1150  GetAssembler()->ucomisd(x86_64::XmmRegister(x86_64::XMM1), x86_64::Address(
1151      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
1152  GetAssembler()->ucomisd(x86_64::XmmRegister(x86_64::XMM2), x86_64::Address(
1153      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
1154  GetAssembler()->ucomisd(x86_64::XmmRegister(x86_64::XMM3), x86_64::Address(
1155      x86_64::CpuRegister(x86_64::R13), 0));
1156  GetAssembler()->ucomisd(x86_64::XmmRegister(x86_64::XMM4), x86_64::Address(
1157      x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0));
1158  const char* expected =
1159    "ucomisd 0xc(%RDI,%RBX,4), %xmm0\n"
1160    "ucomisd 0xc(%RDI,%R9,4), %xmm1\n"
1161    "ucomisd 0xc(%RDI,%R9,4), %xmm2\n"
1162    "ucomisd (%R13), %xmm3\n"
1163    "ucomisd (%R13,%R9,1), %xmm4\n";
1164
1165  DriverStr(expected, "ucomisd_address");
1166}
1167
1168// X87
1169
1170std::string x87_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
1171                   x86_64::X86_64Assembler* assembler) {
1172  std::ostringstream str;
1173
1174  assembler->fincstp();
1175  str << "fincstp\n";
1176
1177  assembler->fsin();
1178  str << "fsin\n";
1179
1180  assembler->fcos();
1181  str << "fcos\n";
1182
1183  assembler->fptan();
1184  str << "fptan\n";
1185
1186  return str.str();
1187}
1188
1189TEST_F(AssemblerX86_64Test, X87) {
1190  DriverFn(&x87_fn, "x87");
1191}
1192
1193TEST_F(AssemblerX86_64Test, FPUIntegerLoad) {
1194  GetAssembler()->filds(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 4));
1195  GetAssembler()->fildl(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 12));
1196  const char* expected =
1197      "fildl 0x4(%RSP)\n"
1198      "fildll 0xc(%RSP)\n";
1199  DriverStr(expected, "FPUIntegerLoad");
1200}
1201
1202TEST_F(AssemblerX86_64Test, FPUIntegerStore) {
1203  GetAssembler()->fistps(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 16));
1204  GetAssembler()->fistpl(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 24));
1205  const char* expected =
1206      "fistpl 0x10(%RSP)\n"
1207      "fistpll 0x18(%RSP)\n";
1208  DriverStr(expected, "FPUIntegerStore");
1209}
1210
1211////////////////
1212// CALL / JMP //
1213////////////////
1214
1215TEST_F(AssemblerX86_64Test, Call) {
1216  DriverStr(RepeatR(&x86_64::X86_64Assembler::call, "call *%{reg}"), "call");
1217}
1218
1219TEST_F(AssemblerX86_64Test, Jmp) {
1220  DriverStr(RepeatR(&x86_64::X86_64Assembler::jmp, "jmp *%{reg}"), "jmp");
1221}
1222
1223TEST_F(AssemblerX86_64Test, Enter) {
1224  DriverStr(RepeatI(&x86_64::X86_64Assembler::enter, 2U  /* 16b immediate */, "enter ${imm}, $0",
1225                    true  /* Only non-negative number */), "enter");
1226}
1227
1228TEST_F(AssemblerX86_64Test, RetImm) {
1229  DriverStr(RepeatI(&x86_64::X86_64Assembler::ret, 2U  /* 16b immediate */, "ret ${imm}",
1230                    true  /* Only non-negative number */), "reti");
1231}
1232
1233std::string ret_and_leave_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
1234                             x86_64::X86_64Assembler* assembler) {
1235  std::ostringstream str;
1236
1237  assembler->ret();
1238  str << "ret\n";
1239
1240  assembler->leave();
1241  str << "leave\n";
1242
1243  return str.str();
1244}
1245
1246TEST_F(AssemblerX86_64Test, RetAndLeave) {
1247  DriverFn(&ret_and_leave_fn, "retleave");
1248}
1249
1250//////////
1251// MISC //
1252//////////
1253
1254TEST_F(AssemblerX86_64Test, Bswapl) {
1255  DriverStr(Repeatr(&x86_64::X86_64Assembler::bswapl, "bswap %{reg}"), "bswapl");
1256}
1257
1258TEST_F(AssemblerX86_64Test, Bswapq) {
1259  DriverStr(RepeatR(&x86_64::X86_64Assembler::bswapq, "bswap %{reg}"), "bswapq");
1260}
1261
1262TEST_F(AssemblerX86_64Test, Bsfl) {
1263  DriverStr(Repeatrr(&x86_64::X86_64Assembler::bsfl, "bsfl %{reg2}, %{reg1}"), "bsfl");
1264}
1265
1266TEST_F(AssemblerX86_64Test, BsflAddress) {
1267  GetAssembler()->bsfl(x86_64::CpuRegister(x86_64::R10), x86_64::Address(
1268      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1269  GetAssembler()->bsfl(x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1270      x86_64::CpuRegister(x86_64::R10), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1271  GetAssembler()->bsfl(x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1272      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
1273  const char* expected =
1274    "bsfl 0xc(%RDI,%RBX,4), %R10d\n"
1275    "bsfl 0xc(%R10,%RBX,4), %edi\n"
1276    "bsfl 0xc(%RDI,%R9,4), %edi\n";
1277
1278  DriverStr(expected, "bsfl_address");
1279}
1280
1281TEST_F(AssemblerX86_64Test, Bsfq) {
1282  DriverStr(RepeatRR(&x86_64::X86_64Assembler::bsfq, "bsfq %{reg2}, %{reg1}"), "bsfq");
1283}
1284
1285TEST_F(AssemblerX86_64Test, BsfqAddress) {
1286  GetAssembler()->bsfq(x86_64::CpuRegister(x86_64::R10), x86_64::Address(
1287      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1288  GetAssembler()->bsfq(x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1289      x86_64::CpuRegister(x86_64::R10), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1290  GetAssembler()->bsfq(x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1291      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
1292  const char* expected =
1293    "bsfq 0xc(%RDI,%RBX,4), %R10\n"
1294    "bsfq 0xc(%R10,%RBX,4), %RDI\n"
1295    "bsfq 0xc(%RDI,%R9,4), %RDI\n";
1296
1297  DriverStr(expected, "bsfq_address");
1298}
1299
1300TEST_F(AssemblerX86_64Test, Bsrl) {
1301  DriverStr(Repeatrr(&x86_64::X86_64Assembler::bsrl, "bsrl %{reg2}, %{reg1}"), "bsrl");
1302}
1303
1304TEST_F(AssemblerX86_64Test, BsrlAddress) {
1305  GetAssembler()->bsrl(x86_64::CpuRegister(x86_64::R10), x86_64::Address(
1306      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1307  GetAssembler()->bsrl(x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1308      x86_64::CpuRegister(x86_64::R10), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1309  GetAssembler()->bsrl(x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1310      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
1311  const char* expected =
1312    "bsrl 0xc(%RDI,%RBX,4), %R10d\n"
1313    "bsrl 0xc(%R10,%RBX,4), %edi\n"
1314    "bsrl 0xc(%RDI,%R9,4), %edi\n";
1315
1316  DriverStr(expected, "bsrl_address");
1317}
1318
1319TEST_F(AssemblerX86_64Test, Bsrq) {
1320  DriverStr(RepeatRR(&x86_64::X86_64Assembler::bsrq, "bsrq %{reg2}, %{reg1}"), "bsrq");
1321}
1322
1323TEST_F(AssemblerX86_64Test, BsrqAddress) {
1324  GetAssembler()->bsrq(x86_64::CpuRegister(x86_64::R10), x86_64::Address(
1325      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1326  GetAssembler()->bsrq(x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1327      x86_64::CpuRegister(x86_64::R10), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1328  GetAssembler()->bsrq(x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1329      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
1330  const char* expected =
1331    "bsrq 0xc(%RDI,%RBX,4), %R10\n"
1332    "bsrq 0xc(%R10,%RBX,4), %RDI\n"
1333    "bsrq 0xc(%RDI,%R9,4), %RDI\n";
1334
1335  DriverStr(expected, "bsrq_address");
1336}
1337
1338TEST_F(AssemblerX86_64Test, Popcntl) {
1339  DriverStr(Repeatrr(&x86_64::X86_64Assembler::popcntl, "popcntl %{reg2}, %{reg1}"), "popcntl");
1340}
1341
1342TEST_F(AssemblerX86_64Test, PopcntlAddress) {
1343  GetAssembler()->popcntl(x86_64::CpuRegister(x86_64::R10), x86_64::Address(
1344      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1345  GetAssembler()->popcntl(x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1346      x86_64::CpuRegister(x86_64::R10), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1347  GetAssembler()->popcntl(x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1348      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
1349  const char* expected =
1350    "popcntl 0xc(%RDI,%RBX,4), %R10d\n"
1351    "popcntl 0xc(%R10,%RBX,4), %edi\n"
1352    "popcntl 0xc(%RDI,%R9,4), %edi\n";
1353
1354  DriverStr(expected, "popcntl_address");
1355}
1356
1357TEST_F(AssemblerX86_64Test, Popcntq) {
1358  DriverStr(RepeatRR(&x86_64::X86_64Assembler::popcntq, "popcntq %{reg2}, %{reg1}"), "popcntq");
1359}
1360
1361TEST_F(AssemblerX86_64Test, PopcntqAddress) {
1362  GetAssembler()->popcntq(x86_64::CpuRegister(x86_64::R10), x86_64::Address(
1363      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1364  GetAssembler()->popcntq(x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1365      x86_64::CpuRegister(x86_64::R10), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));
1366  GetAssembler()->popcntq(x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1367      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12));
1368  const char* expected =
1369    "popcntq 0xc(%RDI,%RBX,4), %R10\n"
1370    "popcntq 0xc(%R10,%RBX,4), %RDI\n"
1371    "popcntq 0xc(%RDI,%R9,4), %RDI\n";
1372
1373  DriverStr(expected, "popcntq_address");
1374}
1375
1376TEST_F(AssemblerX86_64Test, CmovlAddress) {
1377  GetAssembler()->cmov(x86_64::kEqual, x86_64::CpuRegister(x86_64::R10), x86_64::Address(
1378      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12), false);
1379  GetAssembler()->cmov(x86_64::kNotEqual, x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1380      x86_64::CpuRegister(x86_64::R10), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12), false);
1381  GetAssembler()->cmov(x86_64::kEqual, x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1382      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12), false);
1383  const char* expected =
1384    "cmovzl 0xc(%RDI,%RBX,4), %R10d\n"
1385    "cmovnzl 0xc(%R10,%RBX,4), %edi\n"
1386    "cmovzl 0xc(%RDI,%R9,4), %edi\n";
1387
1388  DriverStr(expected, "cmovl_address");
1389}
1390
1391TEST_F(AssemblerX86_64Test, CmovqAddress) {
1392  GetAssembler()->cmov(x86_64::kEqual, x86_64::CpuRegister(x86_64::R10), x86_64::Address(
1393      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12), true);
1394  GetAssembler()->cmov(x86_64::kNotEqual, x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1395      x86_64::CpuRegister(x86_64::R10), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12), true);
1396  GetAssembler()->cmov(x86_64::kEqual, x86_64::CpuRegister(x86_64::RDI), x86_64::Address(
1397      x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12), true);
1398  const char* expected =
1399    "cmovzq 0xc(%RDI,%RBX,4), %R10\n"
1400    "cmovnzq 0xc(%R10,%RBX,4), %rdi\n"
1401    "cmovzq 0xc(%RDI,%R9,4), %rdi\n";
1402
1403  DriverStr(expected, "cmovq_address");
1404}
1405
1406
1407/////////////////
1408// Near labels //
1409/////////////////
1410
1411TEST_F(AssemblerX86_64Test, Jrcxz) {
1412  x86_64::NearLabel target;
1413  GetAssembler()->jrcxz(&target);
1414  GetAssembler()->addl(x86_64::CpuRegister(x86_64::RDI),
1415                       x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 4));
1416  GetAssembler()->Bind(&target);
1417  const char* expected =
1418    "jrcxz 1f\n"
1419    "addl 4(%RSP),%EDI\n"
1420    "1:\n";
1421
1422  DriverStr(expected, "jrcxz");
1423}
1424
1425TEST_F(AssemblerX86_64Test, NearLabel) {
1426  // Test both forward and backward branches.
1427  x86_64::NearLabel start, target;
1428  GetAssembler()->Bind(&start);
1429  GetAssembler()->j(x86_64::kEqual, &target);
1430  GetAssembler()->jmp(&target);
1431  GetAssembler()->jrcxz(&target);
1432  GetAssembler()->addl(x86_64::CpuRegister(x86_64::RDI),
1433                       x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 4));
1434  GetAssembler()->Bind(&target);
1435  GetAssembler()->j(x86_64::kNotEqual, &start);
1436  GetAssembler()->jmp(&start);
1437  const char* expected =
1438    "1: je 2f\n"
1439    "jmp 2f\n"
1440    "jrcxz 2f\n"
1441    "addl 4(%RSP),%EDI\n"
1442    "2: jne 1b\n"
1443    "jmp 1b\n";
1444
1445  DriverStr(expected, "near_label");
1446}
1447
1448std::string setcc_test_fn(AssemblerX86_64Test::Base* assembler_test,
1449                          x86_64::X86_64Assembler* assembler) {
1450  // From Condition
1451  /*
1452  kOverflow     =  0,
1453  kNoOverflow   =  1,
1454  kBelow        =  2,
1455  kAboveEqual   =  3,
1456  kEqual        =  4,
1457  kNotEqual     =  5,
1458  kBelowEqual   =  6,
1459  kAbove        =  7,
1460  kSign         =  8,
1461  kNotSign      =  9,
1462  kParityEven   = 10,
1463  kParityOdd    = 11,
1464  kLess         = 12,
1465  kGreaterEqual = 13,
1466  kLessEqual    = 14,
1467  */
1468  std::string suffixes[15] = { "o", "no", "b", "ae", "e", "ne", "be", "a", "s", "ns", "pe", "po",
1469                               "l", "ge", "le" };
1470
1471  std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters();
1472  std::ostringstream str;
1473
1474  for (auto reg : registers) {
1475    for (size_t i = 0; i < 15; ++i) {
1476      assembler->setcc(static_cast<x86_64::Condition>(i), *reg);
1477      str << "set" << suffixes[i] << " %" << assembler_test->GetQuaternaryRegisterName(*reg) << "\n";
1478    }
1479  }
1480
1481  return str.str();
1482}
1483
1484TEST_F(AssemblerX86_64Test, SetCC) {
1485  DriverFn(&setcc_test_fn, "setcc");
1486}
1487
1488static x86_64::X86_64ManagedRegister ManagedFromCpu(x86_64::Register r) {
1489  return x86_64::X86_64ManagedRegister::FromCpuRegister(r);
1490}
1491
1492static x86_64::X86_64ManagedRegister ManagedFromFpu(x86_64::FloatRegister r) {
1493  return x86_64::X86_64ManagedRegister::FromXmmRegister(r);
1494}
1495
1496std::string buildframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
1497                               x86_64::X86_64Assembler* assembler) {
1498  // TODO: more interesting spill registers / entry spills.
1499
1500  // Two random spill regs.
1501  std::vector<ManagedRegister> spill_regs;
1502  spill_regs.push_back(ManagedFromCpu(x86_64::R10));
1503  spill_regs.push_back(ManagedFromCpu(x86_64::RSI));
1504
1505  // Three random entry spills.
1506  ManagedRegisterEntrySpills entry_spills;
1507  ManagedRegisterSpill spill(ManagedFromCpu(x86_64::RAX), 8, 0);
1508  entry_spills.push_back(spill);
1509  ManagedRegisterSpill spill2(ManagedFromCpu(x86_64::RBX), 8, 8);
1510  entry_spills.push_back(spill2);
1511  ManagedRegisterSpill spill3(ManagedFromFpu(x86_64::XMM1), 8, 16);
1512  entry_spills.push_back(spill3);
1513
1514  x86_64::X86_64ManagedRegister method_reg = ManagedFromCpu(x86_64::RDI);
1515
1516  size_t frame_size = 10 * kStackAlignment;
1517  assembler->BuildFrame(10 * kStackAlignment, method_reg, spill_regs, entry_spills);
1518
1519  // Construct assembly text counterpart.
1520  std::ostringstream str;
1521  // 1) Push the spill_regs.
1522  str << "pushq %rsi\n";
1523  str << "pushq %r10\n";
1524  // 2) Move down the stack pointer.
1525  ssize_t displacement = static_cast<ssize_t>(frame_size) - (spill_regs.size() * 8 + 8);
1526  str << "subq $" << displacement << ", %rsp\n";
1527  // 3) Store method reference.
1528  str << "movq %rdi, (%rsp)\n";
1529  // 4) Entry spills.
1530  str << "movq %rax, " << frame_size + 0 << "(%rsp)\n";
1531  str << "movq %rbx, " << frame_size + 8 << "(%rsp)\n";
1532  str << "movsd %xmm1, " << frame_size + 16 << "(%rsp)\n";
1533
1534  return str.str();
1535}
1536
1537TEST_F(AssemblerX86_64Test, BuildFrame) {
1538  DriverFn(&buildframe_test_fn, "BuildFrame");
1539}
1540
1541std::string removeframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
1542                                x86_64::X86_64Assembler* assembler) {
1543  // TODO: more interesting spill registers / entry spills.
1544
1545  // Two random spill regs.
1546  std::vector<ManagedRegister> spill_regs;
1547  spill_regs.push_back(ManagedFromCpu(x86_64::R10));
1548  spill_regs.push_back(ManagedFromCpu(x86_64::RSI));
1549
1550  size_t frame_size = 10 * kStackAlignment;
1551  assembler->RemoveFrame(10 * kStackAlignment, spill_regs);
1552
1553  // Construct assembly text counterpart.
1554  std::ostringstream str;
1555  // 1) Move up the stack pointer.
1556  ssize_t displacement = static_cast<ssize_t>(frame_size) - spill_regs.size() * 8 - 8;
1557  str << "addq $" << displacement << ", %rsp\n";
1558  // 2) Pop spill regs.
1559  str << "popq %r10\n";
1560  str << "popq %rsi\n";
1561  str << "ret\n";
1562
1563  return str.str();
1564}
1565
1566TEST_F(AssemblerX86_64Test, RemoveFrame) {
1567  DriverFn(&removeframe_test_fn, "RemoveFrame");
1568}
1569
1570std::string increaseframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
1571                                  x86_64::X86_64Assembler* assembler) {
1572  assembler->IncreaseFrameSize(0U);
1573  assembler->IncreaseFrameSize(kStackAlignment);
1574  assembler->IncreaseFrameSize(10 * kStackAlignment);
1575
1576  // Construct assembly text counterpart.
1577  std::ostringstream str;
1578  str << "addq $0, %rsp\n";
1579  str << "addq $-" << kStackAlignment << ", %rsp\n";
1580  str << "addq $-" << 10 * kStackAlignment << ", %rsp\n";
1581
1582  return str.str();
1583}
1584
1585TEST_F(AssemblerX86_64Test, IncreaseFrame) {
1586  DriverFn(&increaseframe_test_fn, "IncreaseFrame");
1587}
1588
1589std::string decreaseframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED,
1590                                  x86_64::X86_64Assembler* assembler) {
1591  assembler->DecreaseFrameSize(0U);
1592  assembler->DecreaseFrameSize(kStackAlignment);
1593  assembler->DecreaseFrameSize(10 * kStackAlignment);
1594
1595  // Construct assembly text counterpart.
1596  std::ostringstream str;
1597  str << "addq $0, %rsp\n";
1598  str << "addq $" << kStackAlignment << ", %rsp\n";
1599  str << "addq $" << 10 * kStackAlignment << ", %rsp\n";
1600
1601  return str.str();
1602}
1603
1604TEST_F(AssemblerX86_64Test, DecreaseFrame) {
1605  DriverFn(&decreaseframe_test_fn, "DecreaseFrame");
1606}
1607
1608TEST_F(AssemblerX86_64Test, MovzxbRegs) {
1609  DriverStr(Repeatrb(&x86_64::X86_64Assembler::movzxb, "movzbl %{reg2}, %{reg1}"), "movzxb");
1610}
1611
1612TEST_F(AssemblerX86_64Test, MovsxbRegs) {
1613  DriverStr(Repeatrb(&x86_64::X86_64Assembler::movsxb, "movsbl %{reg2}, %{reg1}"), "movsxb");
1614}
1615
1616TEST_F(AssemblerX86_64Test, Repnescasw) {
1617  GetAssembler()->repne_scasw();
1618  const char* expected = "repne scasw\n";
1619  DriverStr(expected, "Repnescasw");
1620}
1621
1622TEST_F(AssemblerX86_64Test, Repecmpsw) {
1623  GetAssembler()->repe_cmpsw();
1624  const char* expected = "repe cmpsw\n";
1625  DriverStr(expected, "Repecmpsw");
1626}
1627
1628TEST_F(AssemblerX86_64Test, Repecmpsl) {
1629  GetAssembler()->repe_cmpsl();
1630  const char* expected = "repe cmpsl\n";
1631  DriverStr(expected, "Repecmpsl");
1632}
1633
1634TEST_F(AssemblerX86_64Test, Repecmpsq) {
1635  GetAssembler()->repe_cmpsq();
1636  const char* expected = "repe cmpsq\n";
1637  DriverStr(expected, "Repecmpsq");
1638}
1639
1640}  // namespace art
1641