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