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