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