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