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 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 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 { 122 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, ... 135 std::string GetArchitectureString() OVERRIDE { 136 return "x86_64"; 137 } 138 139 std::string GetDisassembleParameters() OVERRIDE { 140 return " -D -bbinary -mi386:x86-64 -Mx86-64,addr64,data32 --no-show-raw-insn"; 141 } 142 143 void SetUpHelpers() OVERRIDE { 144 if (registers_.size() == 0) { 145 registers_.push_back(new x86_64::CpuRegister(x86_64::RAX)); 146 registers_.push_back(new x86_64::CpuRegister(x86_64::RBX)); 147 registers_.push_back(new x86_64::CpuRegister(x86_64::RCX)); 148 registers_.push_back(new x86_64::CpuRegister(x86_64::RDX)); 149 registers_.push_back(new x86_64::CpuRegister(x86_64::RBP)); 150 registers_.push_back(new x86_64::CpuRegister(x86_64::RSP)); 151 registers_.push_back(new x86_64::CpuRegister(x86_64::RSI)); 152 registers_.push_back(new x86_64::CpuRegister(x86_64::RDI)); 153 registers_.push_back(new x86_64::CpuRegister(x86_64::R8)); 154 registers_.push_back(new x86_64::CpuRegister(x86_64::R9)); 155 registers_.push_back(new x86_64::CpuRegister(x86_64::R10)); 156 registers_.push_back(new x86_64::CpuRegister(x86_64::R11)); 157 registers_.push_back(new x86_64::CpuRegister(x86_64::R12)); 158 registers_.push_back(new x86_64::CpuRegister(x86_64::R13)); 159 registers_.push_back(new x86_64::CpuRegister(x86_64::R14)); 160 registers_.push_back(new x86_64::CpuRegister(x86_64::R15)); 161 162 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RAX), "eax"); 163 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBX), "ebx"); 164 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RCX), "ecx"); 165 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDX), "edx"); 166 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBP), "ebp"); 167 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSP), "esp"); 168 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSI), "esi"); 169 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDI), "edi"); 170 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R8), "r8d"); 171 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R9), "r9d"); 172 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R10), "r10d"); 173 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R11), "r11d"); 174 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R12), "r12d"); 175 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R13), "r13d"); 176 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R14), "r14d"); 177 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R15), "r15d"); 178 179 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RAX), "ax"); 180 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBX), "bx"); 181 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RCX), "cx"); 182 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDX), "dx"); 183 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBP), "bp"); 184 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSP), "sp"); 185 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSI), "si"); 186 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDI), "di"); 187 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R8), "r8w"); 188 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R9), "r9w"); 189 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R10), "r10w"); 190 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R11), "r11w"); 191 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R12), "r12w"); 192 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R13), "r13w"); 193 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R14), "r14w"); 194 tertiary_register_names_.emplace(x86_64::CpuRegister(x86_64::R15), "r15w"); 195 196 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RAX), "al"); 197 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBX), "bl"); 198 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RCX), "cl"); 199 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDX), "dl"); 200 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBP), "bpl"); 201 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSP), "spl"); 202 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSI), "sil"); 203 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDI), "dil"); 204 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R8), "r8b"); 205 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R9), "r9b"); 206 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R10), "r10b"); 207 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R11), "r11b"); 208 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R12), "r12b"); 209 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R13), "r13b"); 210 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R14), "r14b"); 211 quaternary_register_names_.emplace(x86_64::CpuRegister(x86_64::R15), "r15b"); 212 213 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM0)); 214 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM1)); 215 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM2)); 216 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM3)); 217 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM4)); 218 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM5)); 219 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM6)); 220 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM7)); 221 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM8)); 222 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM9)); 223 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM10)); 224 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM11)); 225 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM12)); 226 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM13)); 227 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM14)); 228 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM15)); 229 } 230 } 231 232 void TearDown() OVERRIDE { 233 AssemblerTest::TearDown(); 234 STLDeleteElements(®isters_); 235 STLDeleteElements(&fp_registers_); 236 } 237 238 std::vector<x86_64::CpuRegister*> GetRegisters() OVERRIDE { 239 return registers_; 240 } 241 242 std::vector<x86_64::XmmRegister*> GetFPRegisters() OVERRIDE { 243 return fp_registers_; 244 } 245 246 x86_64::Immediate CreateImmediate(int64_t imm_value) OVERRIDE { 247 return x86_64::Immediate(imm_value); 248 } 249 250 std::string GetSecondaryRegisterName(const x86_64::CpuRegister& reg) OVERRIDE { 251 CHECK(secondary_register_names_.find(reg) != secondary_register_names_.end()); 252 return secondary_register_names_[reg]; 253 } 254 255 std::string GetTertiaryRegisterName(const x86_64::CpuRegister& reg) OVERRIDE { 256 CHECK(tertiary_register_names_.find(reg) != tertiary_register_names_.end()); 257 return tertiary_register_names_[reg]; 258 } 259 260 std::string GetQuaternaryRegisterName(const x86_64::CpuRegister& reg) OVERRIDE { 261 CHECK(quaternary_register_names_.find(reg) != quaternary_register_names_.end()); 262 return quaternary_register_names_[reg]; 263 } 264 265 private: 266 std::vector<x86_64::CpuRegister*> registers_; 267 std::map<x86_64::CpuRegister, std::string, X86_64CpuRegisterCompare> secondary_register_names_; 268 std::map<x86_64::CpuRegister, std::string, X86_64CpuRegisterCompare> tertiary_register_names_; 269 std::map<x86_64::CpuRegister, std::string, X86_64CpuRegisterCompare> quaternary_register_names_; 270 271 std::vector<x86_64::XmmRegister*> fp_registers_; 272 }; 273 274 275 TEST_F(AssemblerX86_64Test, Toolchain) { 276 EXPECT_TRUE(CheckTools()); 277 } 278 279 280 TEST_F(AssemblerX86_64Test, PushqRegs) { 281 DriverStr(RepeatR(&x86_64::X86_64Assembler::pushq, "pushq %{reg}"), "pushq"); 282 } 283 284 TEST_F(AssemblerX86_64Test, PushqImm) { 285 DriverStr(RepeatI(&x86_64::X86_64Assembler::pushq, 4U, "pushq ${imm}"), "pushqi"); 286 } 287 288 TEST_F(AssemblerX86_64Test, MovqRegs) { 289 DriverStr(RepeatRR(&x86_64::X86_64Assembler::movq, "movq %{reg2}, %{reg1}"), "movq"); 290 } 291 292 TEST_F(AssemblerX86_64Test, MovqImm) { 293 DriverStr(RepeatRI(&x86_64::X86_64Assembler::movq, 8U, "movq ${imm}, %{reg}"), "movqi"); 294 } 295 296 TEST_F(AssemblerX86_64Test, MovlRegs) { 297 DriverStr(Repeatrr(&x86_64::X86_64Assembler::movl, "mov %{reg2}, %{reg1}"), "movl"); 298 } 299 300 TEST_F(AssemblerX86_64Test, MovlImm) { 301 DriverStr(Repeatri(&x86_64::X86_64Assembler::movl, 4U, "mov ${imm}, %{reg}"), "movli"); 302 } 303 304 TEST_F(AssemblerX86_64Test, AddqRegs) { 305 DriverStr(RepeatRR(&x86_64::X86_64Assembler::addq, "addq %{reg2}, %{reg1}"), "addq"); 306 } 307 308 TEST_F(AssemblerX86_64Test, AddqImm) { 309 DriverStr(RepeatRI(&x86_64::X86_64Assembler::addq, 4U, "addq ${imm}, %{reg}"), "addqi"); 310 } 311 312 TEST_F(AssemblerX86_64Test, AddlRegs) { 313 DriverStr(Repeatrr(&x86_64::X86_64Assembler::addl, "add %{reg2}, %{reg1}"), "addl"); 314 } 315 316 TEST_F(AssemblerX86_64Test, AddlImm) { 317 DriverStr(Repeatri(&x86_64::X86_64Assembler::addl, 4U, "add ${imm}, %{reg}"), "addli"); 318 } 319 320 TEST_F(AssemblerX86_64Test, ImulqReg1) { 321 DriverStr(RepeatR(&x86_64::X86_64Assembler::imulq, "imulq %{reg}"), "imulq"); 322 } 323 324 TEST_F(AssemblerX86_64Test, ImulqRegs) { 325 DriverStr(RepeatRR(&x86_64::X86_64Assembler::imulq, "imulq %{reg2}, %{reg1}"), "imulq"); 326 } 327 328 TEST_F(AssemblerX86_64Test, ImulqImm) { 329 DriverStr(RepeatRI(&x86_64::X86_64Assembler::imulq, 4U, "imulq ${imm}, %{reg}, %{reg}"), 330 "imulqi"); 331 } 332 333 TEST_F(AssemblerX86_64Test, ImullRegs) { 334 DriverStr(Repeatrr(&x86_64::X86_64Assembler::imull, "imul %{reg2}, %{reg1}"), "imull"); 335 } 336 337 TEST_F(AssemblerX86_64Test, ImullImm) { 338 DriverStr(Repeatri(&x86_64::X86_64Assembler::imull, 4U, "imull ${imm}, %{reg}, %{reg}"), 339 "imulli"); 340 } 341 342 TEST_F(AssemblerX86_64Test, Mull) { 343 DriverStr(Repeatr(&x86_64::X86_64Assembler::mull, "mull %{reg}"), "mull"); 344 } 345 346 TEST_F(AssemblerX86_64Test, SubqRegs) { 347 DriverStr(RepeatRR(&x86_64::X86_64Assembler::subq, "subq %{reg2}, %{reg1}"), "subq"); 348 } 349 350 TEST_F(AssemblerX86_64Test, SubqImm) { 351 DriverStr(RepeatRI(&x86_64::X86_64Assembler::subq, 4U, "subq ${imm}, %{reg}"), "subqi"); 352 } 353 354 TEST_F(AssemblerX86_64Test, SublRegs) { 355 DriverStr(Repeatrr(&x86_64::X86_64Assembler::subl, "sub %{reg2}, %{reg1}"), "subl"); 356 } 357 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. 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 377 TEST_F(AssemblerX86_64Test, ShllReg) { 378 DriverFn(&shll_fn, "shll"); 379 } 380 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. 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 400 TEST_F(AssemblerX86_64Test, ShlqReg) { 401 DriverFn(&shlq_fn, "shlq"); 402 } 403 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. 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 423 TEST_F(AssemblerX86_64Test, ShrlReg) { 424 DriverFn(&shrl_fn, "shrl"); 425 } 426 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. 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 446 TEST_F(AssemblerX86_64Test, ShrqReg) { 447 DriverFn(&shrq_fn, "shrq"); 448 } 449 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. 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 469 TEST_F(AssemblerX86_64Test, SarlReg) { 470 DriverFn(&sarl_fn, "sarl"); 471 } 472 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. 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 492 TEST_F(AssemblerX86_64Test, SarqReg) { 493 DriverFn(&sarq_fn, "sarq"); 494 } 495 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. 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 515 TEST_F(AssemblerX86_64Test, RorlReg) { 516 DriverFn(&rorl_fn, "rorl"); 517 } 518 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. 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 538 TEST_F(AssemblerX86_64Test, RollReg) { 539 DriverFn(&roll_fn, "roll"); 540 } 541 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. 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 561 TEST_F(AssemblerX86_64Test, RorqReg) { 562 DriverFn(&rorq_fn, "rorq"); 563 } 564 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. 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 584 TEST_F(AssemblerX86_64Test, RolqReg) { 585 DriverFn(&rolq_fn, "rolq"); 586 } 587 588 TEST_F(AssemblerX86_64Test, RolqImm) { 589 DriverStr(RepeatRI(&x86_64::X86_64Assembler::rolq, 1U, "rolq ${imm}, %{reg}"), "rolqi"); 590 } 591 592 TEST_F(AssemblerX86_64Test, CmpqRegs) { 593 DriverStr(RepeatRR(&x86_64::X86_64Assembler::cmpq, "cmpq %{reg2}, %{reg1}"), "cmpq"); 594 } 595 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 601 TEST_F(AssemblerX86_64Test, CmplRegs) { 602 DriverStr(Repeatrr(&x86_64::X86_64Assembler::cmpl, "cmp %{reg2}, %{reg1}"), "cmpl"); 603 } 604 605 TEST_F(AssemblerX86_64Test, CmplImm) { 606 DriverStr(Repeatri(&x86_64::X86_64Assembler::cmpl, 4U, "cmpl ${imm}, %{reg}"), "cmpli"); 607 } 608 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 615 TEST_F(AssemblerX86_64Test, Negq) { 616 DriverStr(RepeatR(&x86_64::X86_64Assembler::negq, "negq %{reg}"), "negq"); 617 } 618 619 TEST_F(AssemblerX86_64Test, Negl) { 620 DriverStr(Repeatr(&x86_64::X86_64Assembler::negl, "negl %{reg}"), "negl"); 621 } 622 623 TEST_F(AssemblerX86_64Test, Notq) { 624 DriverStr(RepeatR(&x86_64::X86_64Assembler::notq, "notq %{reg}"), "notq"); 625 } 626 627 TEST_F(AssemblerX86_64Test, Notl) { 628 DriverStr(Repeatr(&x86_64::X86_64Assembler::notl, "notl %{reg}"), "notl"); 629 } 630 631 TEST_F(AssemblerX86_64Test, AndqRegs) { 632 DriverStr(RepeatRR(&x86_64::X86_64Assembler::andq, "andq %{reg2}, %{reg1}"), "andq"); 633 } 634 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 640 TEST_F(AssemblerX86_64Test, AndlRegs) { 641 DriverStr(Repeatrr(&x86_64::X86_64Assembler::andl, "andl %{reg2}, %{reg1}"), "andl"); 642 } 643 644 TEST_F(AssemblerX86_64Test, AndlImm) { 645 DriverStr(Repeatri(&x86_64::X86_64Assembler::andl, 4U, "andl ${imm}, %{reg}"), "andli"); 646 } 647 648 TEST_F(AssemblerX86_64Test, OrqRegs) { 649 DriverStr(RepeatRR(&x86_64::X86_64Assembler::orq, "orq %{reg2}, %{reg1}"), "orq"); 650 } 651 652 TEST_F(AssemblerX86_64Test, OrlRegs) { 653 DriverStr(Repeatrr(&x86_64::X86_64Assembler::orl, "orl %{reg2}, %{reg1}"), "orl"); 654 } 655 656 TEST_F(AssemblerX86_64Test, OrlImm) { 657 DriverStr(Repeatri(&x86_64::X86_64Assembler::orl, 4U, "orl ${imm}, %{reg}"), "orli"); 658 } 659 660 TEST_F(AssemblerX86_64Test, XorqRegs) { 661 DriverStr(RepeatRR(&x86_64::X86_64Assembler::xorq, "xorq %{reg2}, %{reg1}"), "xorq"); 662 } 663 664 TEST_F(AssemblerX86_64Test, XorqImm) { 665 DriverStr(RepeatRI(&x86_64::X86_64Assembler::xorq, 4U, "xorq ${imm}, %{reg}"), "xorqi"); 666 } 667 668 TEST_F(AssemblerX86_64Test, XorlRegs) { 669 DriverStr(Repeatrr(&x86_64::X86_64Assembler::xorl, "xor %{reg2}, %{reg1}"), "xorl"); 670 } 671 672 TEST_F(AssemblerX86_64Test, XorlImm) { 673 DriverStr(Repeatri(&x86_64::X86_64Assembler::xorl, 4U, "xor ${imm}, %{reg}"), "xorli"); 674 } 675 676 TEST_F(AssemblerX86_64Test, Xchgq) { 677 DriverStr(RepeatRR(&x86_64::X86_64Assembler::xchgq, "xchgq %{reg2}, %{reg1}"), "xchgq"); 678 } 679 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 957 TEST_F(AssemblerX86_64Test, RepneScasw) { 958 GetAssembler()->repne_scasw(); 959 const char* expected = "repne scasw\n"; 960 DriverStr(expected, "repne_scasw"); 961 } 962 963 TEST_F(AssemblerX86_64Test, RepMovsw) { 964 GetAssembler()->rep_movsw(); 965 const char* expected = "rep movsw\n"; 966 DriverStr(expected, "rep_movsw"); 967 } 968 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 977 TEST_F(AssemblerX86_64Test, Movaps) { 978 DriverStr(RepeatFF(&x86_64::X86_64Assembler::movaps, "movaps %{reg2}, %{reg1}"), "movaps"); 979 } 980 981 TEST_F(AssemblerX86_64Test, Movss) { 982 DriverStr(RepeatFF(&x86_64::X86_64Assembler::movss, "movss %{reg2}, %{reg1}"), "movss"); 983 } 984 985 TEST_F(AssemblerX86_64Test, Movsd) { 986 DriverStr(RepeatFF(&x86_64::X86_64Assembler::movsd, "movsd %{reg2}, %{reg1}"), "movsd"); 987 } 988 989 TEST_F(AssemblerX86_64Test, Movd1) { 990 DriverStr(RepeatFR(&x86_64::X86_64Assembler::movd, "movd %{reg2}, %{reg1}"), "movd.1"); 991 } 992 993 TEST_F(AssemblerX86_64Test, Movd2) { 994 DriverStr(RepeatRF(&x86_64::X86_64Assembler::movd, "movd %{reg2}, %{reg1}"), "movd.2"); 995 } 996 997 TEST_F(AssemblerX86_64Test, Addss) { 998 DriverStr(RepeatFF(&x86_64::X86_64Assembler::addss, "addss %{reg2}, %{reg1}"), "addss"); 999 } 1000 1001 TEST_F(AssemblerX86_64Test, Addsd) { 1002 DriverStr(RepeatFF(&x86_64::X86_64Assembler::addsd, "addsd %{reg2}, %{reg1}"), "addsd"); 1003 } 1004 1005 TEST_F(AssemblerX86_64Test, Subss) { 1006 DriverStr(RepeatFF(&x86_64::X86_64Assembler::subss, "subss %{reg2}, %{reg1}"), "subss"); 1007 } 1008 1009 TEST_F(AssemblerX86_64Test, Subsd) { 1010 DriverStr(RepeatFF(&x86_64::X86_64Assembler::subsd, "subsd %{reg2}, %{reg1}"), "subsd"); 1011 } 1012 1013 TEST_F(AssemblerX86_64Test, Mulss) { 1014 DriverStr(RepeatFF(&x86_64::X86_64Assembler::mulss, "mulss %{reg2}, %{reg1}"), "mulss"); 1015 } 1016 1017 TEST_F(AssemblerX86_64Test, Mulsd) { 1018 DriverStr(RepeatFF(&x86_64::X86_64Assembler::mulsd, "mulsd %{reg2}, %{reg1}"), "mulsd"); 1019 } 1020 1021 TEST_F(AssemblerX86_64Test, Divss) { 1022 DriverStr(RepeatFF(&x86_64::X86_64Assembler::divss, "divss %{reg2}, %{reg1}"), "divss"); 1023 } 1024 1025 TEST_F(AssemblerX86_64Test, Divsd) { 1026 DriverStr(RepeatFF(&x86_64::X86_64Assembler::divsd, "divsd %{reg2}, %{reg1}"), "divsd"); 1027 } 1028 1029 TEST_F(AssemblerX86_64Test, Cvtsi2ss) { 1030 DriverStr(RepeatFr(&x86_64::X86_64Assembler::cvtsi2ss, "cvtsi2ss %{reg2}, %{reg1}"), "cvtsi2ss"); 1031 } 1032 1033 TEST_F(AssemblerX86_64Test, Cvtsi2sd) { 1034 DriverStr(RepeatFr(&x86_64::X86_64Assembler::cvtsi2sd, "cvtsi2sd %{reg2}, %{reg1}"), "cvtsi2sd"); 1035 } 1036 1037 1038 TEST_F(AssemblerX86_64Test, Cvtss2si) { 1039 DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvtss2si, "cvtss2si %{reg2}, %{reg1}"), "cvtss2si"); 1040 } 1041 1042 1043 TEST_F(AssemblerX86_64Test, Cvtss2sd) { 1044 DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtss2sd, "cvtss2sd %{reg2}, %{reg1}"), "cvtss2sd"); 1045 } 1046 1047 1048 TEST_F(AssemblerX86_64Test, Cvtsd2si) { 1049 DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvtsd2si, "cvtsd2si %{reg2}, %{reg1}"), "cvtsd2si"); 1050 } 1051 1052 TEST_F(AssemblerX86_64Test, Cvttss2si) { 1053 DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvttss2si, "cvttss2si %{reg2}, %{reg1}"), 1054 "cvttss2si"); 1055 } 1056 1057 TEST_F(AssemblerX86_64Test, Cvttsd2si) { 1058 DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvttsd2si, "cvttsd2si %{reg2}, %{reg1}"), 1059 "cvttsd2si"); 1060 } 1061 1062 TEST_F(AssemblerX86_64Test, Cvtsd2ss) { 1063 DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtsd2ss, "cvtsd2ss %{reg2}, %{reg1}"), "cvtsd2ss"); 1064 } 1065 1066 TEST_F(AssemblerX86_64Test, Cvtdq2pd) { 1067 DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtdq2pd, "cvtdq2pd %{reg2}, %{reg1}"), "cvtdq2pd"); 1068 } 1069 1070 TEST_F(AssemblerX86_64Test, Comiss) { 1071 DriverStr(RepeatFF(&x86_64::X86_64Assembler::comiss, "comiss %{reg2}, %{reg1}"), "comiss"); 1072 } 1073 1074 TEST_F(AssemblerX86_64Test, Comisd) { 1075 DriverStr(RepeatFF(&x86_64::X86_64Assembler::comisd, "comisd %{reg2}, %{reg1}"), "comisd"); 1076 } 1077 1078 TEST_F(AssemblerX86_64Test, Ucomiss) { 1079 DriverStr(RepeatFF(&x86_64::X86_64Assembler::ucomiss, "ucomiss %{reg2}, %{reg1}"), "ucomiss"); 1080 } 1081 1082 TEST_F(AssemblerX86_64Test, Ucomisd) { 1083 DriverStr(RepeatFF(&x86_64::X86_64Assembler::ucomisd, "ucomisd %{reg2}, %{reg1}"), "ucomisd"); 1084 } 1085 1086 TEST_F(AssemblerX86_64Test, Sqrtss) { 1087 DriverStr(RepeatFF(&x86_64::X86_64Assembler::sqrtss, "sqrtss %{reg2}, %{reg1}"), "sqrtss"); 1088 } 1089 1090 TEST_F(AssemblerX86_64Test, Sqrtsd) { 1091 DriverStr(RepeatFF(&x86_64::X86_64Assembler::sqrtsd, "sqrtsd %{reg2}, %{reg1}"), "sqrtsd"); 1092 } 1093 1094 TEST_F(AssemblerX86_64Test, Roundss) { 1095 DriverStr(RepeatFFI(&x86_64::X86_64Assembler::roundss, 1, "roundss ${imm}, %{reg2}, %{reg1}"), "roundss"); 1096 } 1097 1098 TEST_F(AssemblerX86_64Test, Roundsd) { 1099 DriverStr(RepeatFFI(&x86_64::X86_64Assembler::roundsd, 1, "roundsd ${imm}, %{reg2}, %{reg1}"), "roundsd"); 1100 } 1101 1102 TEST_F(AssemblerX86_64Test, Xorps) { 1103 DriverStr(RepeatFF(&x86_64::X86_64Assembler::xorps, "xorps %{reg2}, %{reg1}"), "xorps"); 1104 } 1105 1106 TEST_F(AssemblerX86_64Test, Xorpd) { 1107 DriverStr(RepeatFF(&x86_64::X86_64Assembler::xorpd, "xorpd %{reg2}, %{reg1}"), "xorpd"); 1108 } 1109 1110 TEST_F(AssemblerX86_64Test, Andps) { 1111 DriverStr(RepeatFF(&x86_64::X86_64Assembler::andps, "andps %{reg2}, %{reg1}"), "andps"); 1112 } 1113 1114 TEST_F(AssemblerX86_64Test, Andpd) { 1115 DriverStr(RepeatFF(&x86_64::X86_64Assembler::andpd, "andpd %{reg2}, %{reg1}"), "andpd"); 1116 } 1117 1118 TEST_F(AssemblerX86_64Test, Orps) { 1119 DriverStr(RepeatFF(&x86_64::X86_64Assembler::orps, "orps %{reg2}, %{reg1}"), "orps"); 1120 } 1121 1122 TEST_F(AssemblerX86_64Test, Orpd) { 1123 DriverStr(RepeatFF(&x86_64::X86_64Assembler::orpd, "orpd %{reg2}, %{reg1}"), "orpd"); 1124 } 1125 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 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 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 1189 TEST_F(AssemblerX86_64Test, X87) { 1190 DriverFn(&x87_fn, "x87"); 1191 } 1192 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 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 1215 TEST_F(AssemblerX86_64Test, Call) { 1216 DriverStr(RepeatR(&x86_64::X86_64Assembler::call, "call *%{reg}"), "call"); 1217 } 1218 1219 TEST_F(AssemblerX86_64Test, Jmp) { 1220 DriverStr(RepeatR(&x86_64::X86_64Assembler::jmp, "jmp *%{reg}"), "jmp"); 1221 } 1222 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 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 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 1246 TEST_F(AssemblerX86_64Test, RetAndLeave) { 1247 DriverFn(&ret_and_leave_fn, "retleave"); 1248 } 1249 1250 ////////// 1251 // MISC // 1252 ////////// 1253 1254 TEST_F(AssemblerX86_64Test, Bswapl) { 1255 DriverStr(Repeatr(&x86_64::X86_64Assembler::bswapl, "bswap %{reg}"), "bswapl"); 1256 } 1257 1258 TEST_F(AssemblerX86_64Test, Bswapq) { 1259 DriverStr(RepeatR(&x86_64::X86_64Assembler::bswapq, "bswap %{reg}"), "bswapq"); 1260 } 1261 1262 TEST_F(AssemblerX86_64Test, Bsfl) { 1263 DriverStr(Repeatrr(&x86_64::X86_64Assembler::bsfl, "bsfl %{reg2}, %{reg1}"), "bsfl"); 1264 } 1265 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 1281 TEST_F(AssemblerX86_64Test, Bsfq) { 1282 DriverStr(RepeatRR(&x86_64::X86_64Assembler::bsfq, "bsfq %{reg2}, %{reg1}"), "bsfq"); 1283 } 1284 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 1300 TEST_F(AssemblerX86_64Test, Bsrl) { 1301 DriverStr(Repeatrr(&x86_64::X86_64Assembler::bsrl, "bsrl %{reg2}, %{reg1}"), "bsrl"); 1302 } 1303 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 1319 TEST_F(AssemblerX86_64Test, Bsrq) { 1320 DriverStr(RepeatRR(&x86_64::X86_64Assembler::bsrq, "bsrq %{reg2}, %{reg1}"), "bsrq"); 1321 } 1322 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 1338 TEST_F(AssemblerX86_64Test, Popcntl) { 1339 DriverStr(Repeatrr(&x86_64::X86_64Assembler::popcntl, "popcntl %{reg2}, %{reg1}"), "popcntl"); 1340 } 1341 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 1357 TEST_F(AssemblerX86_64Test, Popcntq) { 1358 DriverStr(RepeatRR(&x86_64::X86_64Assembler::popcntq, "popcntq %{reg2}, %{reg1}"), "popcntq"); 1359 } 1360 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 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 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 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 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 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 1484 TEST_F(AssemblerX86_64Test, SetCC) { 1485 DriverFn(&setcc_test_fn, "setcc"); 1486 } 1487 1488 static x86_64::X86_64ManagedRegister ManagedFromCpu(x86_64::Register r) { 1489 return x86_64::X86_64ManagedRegister::FromCpuRegister(r); 1490 } 1491 1492 static x86_64::X86_64ManagedRegister ManagedFromFpu(x86_64::FloatRegister r) { 1493 return x86_64::X86_64ManagedRegister::FromXmmRegister(r); 1494 } 1495 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 1537 TEST_F(AssemblerX86_64Test, BuildFrame) { 1538 DriverFn(&buildframe_test_fn, "BuildFrame"); 1539 } 1540 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 1566 TEST_F(AssemblerX86_64Test, RemoveFrame) { 1567 DriverFn(&removeframe_test_fn, "RemoveFrame"); 1568 } 1569 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 1585 TEST_F(AssemblerX86_64Test, IncreaseFrame) { 1586 DriverFn(&increaseframe_test_fn, "IncreaseFrame"); 1587 } 1588 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 1604 TEST_F(AssemblerX86_64Test, DecreaseFrame) { 1605 DriverFn(&decreaseframe_test_fn, "DecreaseFrame"); 1606 } 1607 1608 TEST_F(AssemblerX86_64Test, MovzxbRegs) { 1609 DriverStr(Repeatrb(&x86_64::X86_64Assembler::movzxb, "movzbl %{reg2}, %{reg1}"), "movzxb"); 1610 } 1611 1612 TEST_F(AssemblerX86_64Test, MovsxbRegs) { 1613 DriverStr(Repeatrb(&x86_64::X86_64Assembler::movsxb, "movsbl %{reg2}, %{reg1}"), "movsxb"); 1614 } 1615 1616 TEST_F(AssemblerX86_64Test, Repnescasw) { 1617 GetAssembler()->repne_scasw(); 1618 const char* expected = "repne scasw\n"; 1619 DriverStr(expected, "Repnescasw"); 1620 } 1621 1622 TEST_F(AssemblerX86_64Test, Repecmpsw) { 1623 GetAssembler()->repe_cmpsw(); 1624 const char* expected = "repe cmpsw\n"; 1625 DriverStr(expected, "Repecmpsw"); 1626 } 1627 1628 TEST_F(AssemblerX86_64Test, Repecmpsl) { 1629 GetAssembler()->repe_cmpsl(); 1630 const char* expected = "repe cmpsl\n"; 1631 DriverStr(expected, "Repecmpsl"); 1632 } 1633 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