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