assembler_x86_64_test.cc revision 71fb52fee246b7d511f520febbd73dc7a9bbca79
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(IsInt32(8, i)) << i; 48 } 49 for (int32_t i = 128; i < 255; i++) { 50 EXPECT_FALSE(IsInt32(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(IsInt32(8, value)) << value; 59 } 60 61 // Negative ones. 62 for (int32_t i = -1; i >= -128; i--) { 63 EXPECT_TRUE(IsInt32(8, i)) << i; 64 } 65 66 for (int32_t i = -129; i > -256; i--) { 67 EXPECT_FALSE(IsInt32(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(IsInt32(8, value)) << value; 75 } 76 77 // 64bit. 78 for (int64_t i = 0; i < 128; i++) { 79 EXPECT_TRUE(IsInt64(8, i)) << i; 80 } 81 for (int32_t i = 128; i < 255; i++) { 82 EXPECT_FALSE(IsInt64(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(IsInt64(8, value)) << value; 89 } 90 91 // Negative ones. 92 for (int64_t i = -1; i >= -128; i--) { 93 EXPECT_TRUE(IsInt64(8, i)) << i; 94 } 95 96 for (int64_t i = -129; i > -256; i--) { 97 EXPECT_FALSE(IsInt64(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(IsInt64(8, value)) << value; 105 } 106} 107 108struct X86_64CpuRegisterCompare { 109 bool operator()(const x86_64::CpuRegister& a, const x86_64::CpuRegister& b) const { 110 return a.AsRegister() < b.AsRegister(); 111 } 112}; 113 114class AssemblerX86_64Test : public AssemblerTest<x86_64::X86_64Assembler, x86_64::CpuRegister, 115 x86_64::XmmRegister, x86_64::Immediate> { 116 public: 117 typedef AssemblerTest<x86_64::X86_64Assembler, x86_64::CpuRegister, 118 x86_64::XmmRegister, x86_64::Immediate> Base; 119 120 protected: 121 // Get the typically used name for this architecture, e.g., aarch64, x86-64, ... 122 std::string GetArchitectureString() OVERRIDE { 123 return "x86_64"; 124 } 125 126 std::string GetDisassembleParameters() OVERRIDE { 127 return " -D -bbinary -mi386:x86-64 -Mx86-64,addr64,data32 --no-show-raw-insn"; 128 } 129 130 void SetUpHelpers() OVERRIDE { 131 if (registers_.size() == 0) { 132 registers_.push_back(new x86_64::CpuRegister(x86_64::RAX)); 133 registers_.push_back(new x86_64::CpuRegister(x86_64::RBX)); 134 registers_.push_back(new x86_64::CpuRegister(x86_64::RCX)); 135 registers_.push_back(new x86_64::CpuRegister(x86_64::RDX)); 136 registers_.push_back(new x86_64::CpuRegister(x86_64::RBP)); 137 registers_.push_back(new x86_64::CpuRegister(x86_64::RSP)); 138 registers_.push_back(new x86_64::CpuRegister(x86_64::RSI)); 139 registers_.push_back(new x86_64::CpuRegister(x86_64::RDI)); 140 registers_.push_back(new x86_64::CpuRegister(x86_64::R8)); 141 registers_.push_back(new x86_64::CpuRegister(x86_64::R9)); 142 registers_.push_back(new x86_64::CpuRegister(x86_64::R10)); 143 registers_.push_back(new x86_64::CpuRegister(x86_64::R11)); 144 registers_.push_back(new x86_64::CpuRegister(x86_64::R12)); 145 registers_.push_back(new x86_64::CpuRegister(x86_64::R13)); 146 registers_.push_back(new x86_64::CpuRegister(x86_64::R14)); 147 registers_.push_back(new x86_64::CpuRegister(x86_64::R15)); 148 149 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RAX), "eax"); 150 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBX), "ebx"); 151 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RCX), "ecx"); 152 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDX), "edx"); 153 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RBP), "ebp"); 154 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSP), "esp"); 155 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RSI), "esi"); 156 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::RDI), "edi"); 157 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R8), "r8d"); 158 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R9), "r9d"); 159 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R10), "r10d"); 160 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R11), "r11d"); 161 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R12), "r12d"); 162 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R13), "r13d"); 163 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R14), "r14d"); 164 secondary_register_names_.emplace(x86_64::CpuRegister(x86_64::R15), "r15d"); 165 166 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM0)); 167 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM1)); 168 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM2)); 169 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM3)); 170 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM4)); 171 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM5)); 172 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM6)); 173 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM7)); 174 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM8)); 175 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM9)); 176 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM10)); 177 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM11)); 178 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM12)); 179 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM13)); 180 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM14)); 181 fp_registers_.push_back(new x86_64::XmmRegister(x86_64::XMM15)); 182 } 183 } 184 185 void TearDown() OVERRIDE { 186 AssemblerTest::TearDown(); 187 STLDeleteElements(®isters_); 188 STLDeleteElements(&fp_registers_); 189 } 190 191 std::vector<x86_64::CpuRegister*> GetRegisters() OVERRIDE { 192 return registers_; 193 } 194 195 std::vector<x86_64::XmmRegister*> GetFPRegisters() OVERRIDE { 196 return fp_registers_; 197 } 198 199 x86_64::Immediate CreateImmediate(int64_t imm_value) OVERRIDE { 200 return x86_64::Immediate(imm_value); 201 } 202 203 std::string GetSecondaryRegisterName(const x86_64::CpuRegister& reg) OVERRIDE { 204 CHECK(secondary_register_names_.find(reg) != secondary_register_names_.end()); 205 return secondary_register_names_[reg]; 206 } 207 208 private: 209 std::vector<x86_64::CpuRegister*> registers_; 210 std::map<x86_64::CpuRegister, std::string, X86_64CpuRegisterCompare> secondary_register_names_; 211 212 std::vector<x86_64::XmmRegister*> fp_registers_; 213}; 214 215 216TEST_F(AssemblerX86_64Test, Toolchain) { 217 EXPECT_TRUE(CheckTools()); 218} 219 220 221TEST_F(AssemblerX86_64Test, PushqRegs) { 222 DriverStr(RepeatR(&x86_64::X86_64Assembler::pushq, "pushq %{reg}"), "pushq"); 223} 224 225TEST_F(AssemblerX86_64Test, PushqImm) { 226 DriverStr(RepeatI(&x86_64::X86_64Assembler::pushq, 4U, "pushq ${imm}"), "pushqi"); 227} 228 229TEST_F(AssemblerX86_64Test, MovqRegs) { 230 DriverStr(RepeatRR(&x86_64::X86_64Assembler::movq, "movq %{reg2}, %{reg1}"), "movq"); 231} 232 233TEST_F(AssemblerX86_64Test, MovqImm) { 234 DriverStr(RepeatRI(&x86_64::X86_64Assembler::movq, 8U, "movq ${imm}, %{reg}"), "movqi"); 235} 236 237TEST_F(AssemblerX86_64Test, MovlRegs) { 238 DriverStr(Repeatrr(&x86_64::X86_64Assembler::movl, "mov %{reg2}, %{reg1}"), "movl"); 239} 240 241TEST_F(AssemblerX86_64Test, MovlImm) { 242 DriverStr(Repeatri(&x86_64::X86_64Assembler::movl, 4U, "mov ${imm}, %{reg}"), "movli"); 243} 244 245TEST_F(AssemblerX86_64Test, AddqRegs) { 246 DriverStr(RepeatRR(&x86_64::X86_64Assembler::addq, "addq %{reg2}, %{reg1}"), "addq"); 247} 248 249TEST_F(AssemblerX86_64Test, AddqImm) { 250 DriverStr(RepeatRI(&x86_64::X86_64Assembler::addq, 4U, "addq ${imm}, %{reg}"), "addqi"); 251} 252 253TEST_F(AssemblerX86_64Test, AddlRegs) { 254 DriverStr(Repeatrr(&x86_64::X86_64Assembler::addl, "add %{reg2}, %{reg1}"), "addl"); 255} 256 257TEST_F(AssemblerX86_64Test, AddlImm) { 258 DriverStr(Repeatri(&x86_64::X86_64Assembler::addl, 4U, "add ${imm}, %{reg}"), "addli"); 259} 260 261TEST_F(AssemblerX86_64Test, ImulqRegs) { 262 DriverStr(RepeatRR(&x86_64::X86_64Assembler::imulq, "imulq %{reg2}, %{reg1}"), "imulq"); 263} 264 265TEST_F(AssemblerX86_64Test, ImulqImm) { 266 DriverStr(RepeatRI(&x86_64::X86_64Assembler::imulq, 4U, "imulq ${imm}, %{reg}, %{reg}"), 267 "imulqi"); 268} 269 270TEST_F(AssemblerX86_64Test, ImullRegs) { 271 DriverStr(Repeatrr(&x86_64::X86_64Assembler::imull, "imul %{reg2}, %{reg1}"), "imull"); 272} 273 274TEST_F(AssemblerX86_64Test, ImullImm) { 275 DriverStr(Repeatri(&x86_64::X86_64Assembler::imull, 4U, "imull ${imm}, %{reg}, %{reg}"), 276 "imulli"); 277} 278 279TEST_F(AssemblerX86_64Test, Mull) { 280 DriverStr(Repeatr(&x86_64::X86_64Assembler::mull, "mull %{reg}"), "mull"); 281} 282 283TEST_F(AssemblerX86_64Test, SubqRegs) { 284 DriverStr(RepeatRR(&x86_64::X86_64Assembler::subq, "subq %{reg2}, %{reg1}"), "subq"); 285} 286 287TEST_F(AssemblerX86_64Test, SubqImm) { 288 DriverStr(RepeatRI(&x86_64::X86_64Assembler::subq, 4U, "subq ${imm}, %{reg}"), "subqi"); 289} 290 291TEST_F(AssemblerX86_64Test, SublRegs) { 292 DriverStr(Repeatrr(&x86_64::X86_64Assembler::subl, "sub %{reg2}, %{reg1}"), "subl"); 293} 294 295TEST_F(AssemblerX86_64Test, SublImm) { 296 DriverStr(Repeatri(&x86_64::X86_64Assembler::subl, 4U, "sub ${imm}, %{reg}"), "subli"); 297} 298 299// Shll only allows CL as the shift count. 300std::string shll_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) { 301 std::ostringstream str; 302 303 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters(); 304 305 x86_64::CpuRegister shifter(x86_64::RCX); 306 for (auto reg : registers) { 307 assembler->shll(*reg, shifter); 308 str << "shll %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n"; 309 } 310 311 return str.str(); 312} 313 314TEST_F(AssemblerX86_64Test, ShllReg) { 315 DriverFn(&shll_fn, "shll"); 316} 317 318TEST_F(AssemblerX86_64Test, ShllImm) { 319 DriverStr(Repeatri(&x86_64::X86_64Assembler::shll, 1U, "shll ${imm}, %{reg}"), "shlli"); 320} 321 322// Shlq only allows CL as the shift count. 323std::string shlq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) { 324 std::ostringstream str; 325 326 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters(); 327 328 x86_64::CpuRegister shifter(x86_64::RCX); 329 for (auto reg : registers) { 330 assembler->shlq(*reg, shifter); 331 str << "shlq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n"; 332 } 333 334 return str.str(); 335} 336 337TEST_F(AssemblerX86_64Test, ShlqReg) { 338 DriverFn(&shlq_fn, "shlq"); 339} 340 341TEST_F(AssemblerX86_64Test, ShlqImm) { 342 DriverStr(RepeatRI(&x86_64::X86_64Assembler::shlq, 1U, "shlq ${imm}, %{reg}"), "shlqi"); 343} 344 345// Shrl only allows CL as the shift count. 346std::string shrl_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) { 347 std::ostringstream str; 348 349 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters(); 350 351 x86_64::CpuRegister shifter(x86_64::RCX); 352 for (auto reg : registers) { 353 assembler->shrl(*reg, shifter); 354 str << "shrl %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n"; 355 } 356 357 return str.str(); 358} 359 360TEST_F(AssemblerX86_64Test, ShrlReg) { 361 DriverFn(&shrl_fn, "shrl"); 362} 363 364TEST_F(AssemblerX86_64Test, ShrlImm) { 365 DriverStr(Repeatri(&x86_64::X86_64Assembler::shrl, 1U, "shrl ${imm}, %{reg}"), "shrli"); 366} 367 368// Shrq only allows CL as the shift count. 369std::string shrq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) { 370 std::ostringstream str; 371 372 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters(); 373 374 x86_64::CpuRegister shifter(x86_64::RCX); 375 for (auto reg : registers) { 376 assembler->shrq(*reg, shifter); 377 str << "shrq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n"; 378 } 379 380 return str.str(); 381} 382 383TEST_F(AssemblerX86_64Test, ShrqReg) { 384 DriverFn(&shrq_fn, "shrq"); 385} 386 387TEST_F(AssemblerX86_64Test, ShrqImm) { 388 DriverStr(RepeatRI(&x86_64::X86_64Assembler::shrq, 1U, "shrq ${imm}, %{reg}"), "shrqi"); 389} 390 391// Sarl only allows CL as the shift count. 392std::string sarl_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) { 393 std::ostringstream str; 394 395 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters(); 396 397 x86_64::CpuRegister shifter(x86_64::RCX); 398 for (auto reg : registers) { 399 assembler->sarl(*reg, shifter); 400 str << "sarl %cl, %" << assembler_test->GetSecondaryRegisterName(*reg) << "\n"; 401 } 402 403 return str.str(); 404} 405 406TEST_F(AssemblerX86_64Test, SarlReg) { 407 DriverFn(&sarl_fn, "sarl"); 408} 409 410TEST_F(AssemblerX86_64Test, SarlImm) { 411 DriverStr(Repeatri(&x86_64::X86_64Assembler::sarl, 1U, "sarl ${imm}, %{reg}"), "sarli"); 412} 413 414// Sarq only allows CL as the shift count. 415std::string sarq_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) { 416 std::ostringstream str; 417 418 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters(); 419 420 x86_64::CpuRegister shifter(x86_64::RCX); 421 for (auto reg : registers) { 422 assembler->sarq(*reg, shifter); 423 str << "sarq %cl, %" << assembler_test->GetRegisterName(*reg) << "\n"; 424 } 425 426 return str.str(); 427} 428 429TEST_F(AssemblerX86_64Test, SarqReg) { 430 DriverFn(&sarq_fn, "sarq"); 431} 432 433TEST_F(AssemblerX86_64Test, SarqImm) { 434 DriverStr(RepeatRI(&x86_64::X86_64Assembler::sarq, 1U, "sarq ${imm}, %{reg}"), "sarqi"); 435} 436 437TEST_F(AssemblerX86_64Test, CmpqRegs) { 438 DriverStr(RepeatRR(&x86_64::X86_64Assembler::cmpq, "cmpq %{reg2}, %{reg1}"), "cmpq"); 439} 440 441TEST_F(AssemblerX86_64Test, CmpqImm) { 442 DriverStr(RepeatRI(&x86_64::X86_64Assembler::cmpq, 4U /* cmpq only supports 32b imm */, 443 "cmpq ${imm}, %{reg}"), "cmpqi"); 444} 445 446TEST_F(AssemblerX86_64Test, CmplRegs) { 447 DriverStr(Repeatrr(&x86_64::X86_64Assembler::cmpl, "cmp %{reg2}, %{reg1}"), "cmpl"); 448} 449 450TEST_F(AssemblerX86_64Test, CmplImm) { 451 DriverStr(Repeatri(&x86_64::X86_64Assembler::cmpl, 4U, "cmpl ${imm}, %{reg}"), "cmpli"); 452} 453 454TEST_F(AssemblerX86_64Test, Testl) { 455 // Note: uses different order for GCC than usual. This makes GCC happy, and doesn't have an 456 // impact on functional correctness. 457 DriverStr(Repeatrr(&x86_64::X86_64Assembler::testl, "testl %{reg1}, %{reg2}"), "testl"); 458} 459 460TEST_F(AssemblerX86_64Test, Negq) { 461 DriverStr(RepeatR(&x86_64::X86_64Assembler::negq, "negq %{reg}"), "negq"); 462} 463 464TEST_F(AssemblerX86_64Test, Negl) { 465 DriverStr(Repeatr(&x86_64::X86_64Assembler::negl, "negl %{reg}"), "negl"); 466} 467 468TEST_F(AssemblerX86_64Test, Notq) { 469 DriverStr(RepeatR(&x86_64::X86_64Assembler::notq, "notq %{reg}"), "notq"); 470} 471 472TEST_F(AssemblerX86_64Test, Notl) { 473 DriverStr(Repeatr(&x86_64::X86_64Assembler::notl, "notl %{reg}"), "notl"); 474} 475 476TEST_F(AssemblerX86_64Test, AndqRegs) { 477 DriverStr(RepeatRR(&x86_64::X86_64Assembler::andq, "andq %{reg2}, %{reg1}"), "andq"); 478} 479 480TEST_F(AssemblerX86_64Test, AndqImm) { 481 DriverStr(RepeatRI(&x86_64::X86_64Assembler::andq, 4U /* andq only supports 32b imm */, 482 "andq ${imm}, %{reg}"), "andqi"); 483} 484 485TEST_F(AssemblerX86_64Test, AndlRegs) { 486 DriverStr(Repeatrr(&x86_64::X86_64Assembler::andl, "andl %{reg2}, %{reg1}"), "andl"); 487} 488 489TEST_F(AssemblerX86_64Test, AndlImm) { 490 DriverStr(Repeatri(&x86_64::X86_64Assembler::andl, 4U, "andl ${imm}, %{reg}"), "andli"); 491} 492 493TEST_F(AssemblerX86_64Test, OrqRegs) { 494 DriverStr(RepeatRR(&x86_64::X86_64Assembler::orq, "orq %{reg2}, %{reg1}"), "orq"); 495} 496 497TEST_F(AssemblerX86_64Test, OrlRegs) { 498 DriverStr(Repeatrr(&x86_64::X86_64Assembler::orl, "orl %{reg2}, %{reg1}"), "orl"); 499} 500 501TEST_F(AssemblerX86_64Test, OrlImm) { 502 DriverStr(Repeatri(&x86_64::X86_64Assembler::orl, 4U, "orl ${imm}, %{reg}"), "orli"); 503} 504 505TEST_F(AssemblerX86_64Test, XorqRegs) { 506 DriverStr(RepeatRR(&x86_64::X86_64Assembler::xorq, "xorq %{reg2}, %{reg1}"), "xorq"); 507} 508 509TEST_F(AssemblerX86_64Test, XorqImm) { 510 DriverStr(RepeatRI(&x86_64::X86_64Assembler::xorq, 4U, "xorq ${imm}, %{reg}"), "xorqi"); 511} 512 513TEST_F(AssemblerX86_64Test, XorlRegs) { 514 DriverStr(Repeatrr(&x86_64::X86_64Assembler::xorl, "xor %{reg2}, %{reg1}"), "xorl"); 515} 516 517TEST_F(AssemblerX86_64Test, XorlImm) { 518 DriverStr(Repeatri(&x86_64::X86_64Assembler::xorl, 4U, "xor ${imm}, %{reg}"), "xorli"); 519} 520 521TEST_F(AssemblerX86_64Test, Xchgq) { 522 DriverStr(RepeatRR(&x86_64::X86_64Assembler::xchgq, "xchgq %{reg2}, %{reg1}"), "xchgq"); 523} 524 525TEST_F(AssemblerX86_64Test, Xchgl) { 526 // Test is disabled because GCC generates 0x87 0xC0 for xchgl eax, eax. All other cases are the 527 // same. Anyone know why it doesn't emit a simple 0x90? It does so for xchgq rax, rax... 528 // DriverStr(Repeatrr(&x86_64::X86_64Assembler::xchgl, "xchgl %{reg2}, %{reg1}"), "xchgl"); 529} 530 531TEST_F(AssemblerX86_64Test, Movl) { 532 GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address( 533 x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12)); 534 GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address( 535 x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12)); 536 GetAssembler()->movl(x86_64::CpuRegister(x86_64::R8), x86_64::Address( 537 x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12)); 538 GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address( 539 x86_64::CpuRegister(x86_64::R13), 0)); 540 GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address( 541 x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0)); 542 const char* expected = 543 "movl 0xc(%RDI,%RBX,4), %EAX\n" 544 "movl 0xc(%RDI,%R9,4), %EAX\n" 545 "movl 0xc(%RDI,%R9,4), %R8d\n" 546 "movl (%R13), %EAX\n" 547 "movl (%R13,%R9,1), %EAX\n"; 548 549 DriverStr(expected, "movl"); 550} 551 552TEST_F(AssemblerX86_64Test, Movw) { 553 GetAssembler()->movw(x86_64::Address(x86_64::CpuRegister(x86_64::RAX), 0), 554 x86_64::CpuRegister(x86_64::R9)); 555 const char* expected = "movw %R9w, 0(%RAX)\n"; 556 DriverStr(expected, "movw"); 557} 558 559TEST_F(AssemblerX86_64Test, Movsxd) { 560 DriverStr(RepeatRr(&x86_64::X86_64Assembler::movsxd, "movsxd %{reg2}, %{reg1}"), "movsxd"); 561} 562 563/////////////////// 564// FP Operations // 565/////////////////// 566 567TEST_F(AssemblerX86_64Test, Movaps) { 568 DriverStr(RepeatFF(&x86_64::X86_64Assembler::movaps, "movaps %{reg2}, %{reg1}"), "movaps"); 569} 570 571TEST_F(AssemblerX86_64Test, Movss) { 572 DriverStr(RepeatFF(&x86_64::X86_64Assembler::movss, "movss %{reg2}, %{reg1}"), "movss"); 573} 574 575TEST_F(AssemblerX86_64Test, Movsd) { 576 DriverStr(RepeatFF(&x86_64::X86_64Assembler::movsd, "movsd %{reg2}, %{reg1}"), "movsd"); 577} 578 579TEST_F(AssemblerX86_64Test, Movd1) { 580 DriverStr(RepeatFR(&x86_64::X86_64Assembler::movd, "movd %{reg2}, %{reg1}"), "movd.1"); 581} 582 583TEST_F(AssemblerX86_64Test, Movd2) { 584 DriverStr(RepeatRF(&x86_64::X86_64Assembler::movd, "movd %{reg2}, %{reg1}"), "movd.2"); 585} 586 587TEST_F(AssemblerX86_64Test, Addss) { 588 DriverStr(RepeatFF(&x86_64::X86_64Assembler::addss, "addss %{reg2}, %{reg1}"), "addss"); 589} 590 591TEST_F(AssemblerX86_64Test, Addsd) { 592 DriverStr(RepeatFF(&x86_64::X86_64Assembler::addsd, "addsd %{reg2}, %{reg1}"), "addsd"); 593} 594 595TEST_F(AssemblerX86_64Test, Subss) { 596 DriverStr(RepeatFF(&x86_64::X86_64Assembler::subss, "subss %{reg2}, %{reg1}"), "subss"); 597} 598 599TEST_F(AssemblerX86_64Test, Subsd) { 600 DriverStr(RepeatFF(&x86_64::X86_64Assembler::subsd, "subsd %{reg2}, %{reg1}"), "subsd"); 601} 602 603TEST_F(AssemblerX86_64Test, Mulss) { 604 DriverStr(RepeatFF(&x86_64::X86_64Assembler::mulss, "mulss %{reg2}, %{reg1}"), "mulss"); 605} 606 607TEST_F(AssemblerX86_64Test, Mulsd) { 608 DriverStr(RepeatFF(&x86_64::X86_64Assembler::mulsd, "mulsd %{reg2}, %{reg1}"), "mulsd"); 609} 610 611TEST_F(AssemblerX86_64Test, Divss) { 612 DriverStr(RepeatFF(&x86_64::X86_64Assembler::divss, "divss %{reg2}, %{reg1}"), "divss"); 613} 614 615TEST_F(AssemblerX86_64Test, Divsd) { 616 DriverStr(RepeatFF(&x86_64::X86_64Assembler::divsd, "divsd %{reg2}, %{reg1}"), "divsd"); 617} 618 619TEST_F(AssemblerX86_64Test, Cvtsi2ss) { 620 DriverStr(RepeatFr(&x86_64::X86_64Assembler::cvtsi2ss, "cvtsi2ss %{reg2}, %{reg1}"), "cvtsi2ss"); 621} 622 623TEST_F(AssemblerX86_64Test, Cvtsi2sd) { 624 DriverStr(RepeatFr(&x86_64::X86_64Assembler::cvtsi2sd, "cvtsi2sd %{reg2}, %{reg1}"), "cvtsi2sd"); 625} 626 627 628TEST_F(AssemblerX86_64Test, Cvtss2si) { 629 DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvtss2si, "cvtss2si %{reg2}, %{reg1}"), "cvtss2si"); 630} 631 632 633TEST_F(AssemblerX86_64Test, Cvtss2sd) { 634 DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtss2sd, "cvtss2sd %{reg2}, %{reg1}"), "cvtss2sd"); 635} 636 637 638TEST_F(AssemblerX86_64Test, Cvtsd2si) { 639 DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvtsd2si, "cvtsd2si %{reg2}, %{reg1}"), "cvtsd2si"); 640} 641 642TEST_F(AssemblerX86_64Test, Cvttss2si) { 643 DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvttss2si, "cvttss2si %{reg2}, %{reg1}"), 644 "cvttss2si"); 645} 646 647TEST_F(AssemblerX86_64Test, Cvttsd2si) { 648 DriverStr(RepeatrF(&x86_64::X86_64Assembler::cvttsd2si, "cvttsd2si %{reg2}, %{reg1}"), 649 "cvttsd2si"); 650} 651 652TEST_F(AssemblerX86_64Test, Cvtsd2ss) { 653 DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtsd2ss, "cvtsd2ss %{reg2}, %{reg1}"), "cvtsd2ss"); 654} 655 656TEST_F(AssemblerX86_64Test, Cvtdq2pd) { 657 DriverStr(RepeatFF(&x86_64::X86_64Assembler::cvtdq2pd, "cvtdq2pd %{reg2}, %{reg1}"), "cvtdq2pd"); 658} 659 660TEST_F(AssemblerX86_64Test, Comiss) { 661 DriverStr(RepeatFF(&x86_64::X86_64Assembler::comiss, "comiss %{reg2}, %{reg1}"), "comiss"); 662} 663 664TEST_F(AssemblerX86_64Test, Comisd) { 665 DriverStr(RepeatFF(&x86_64::X86_64Assembler::comisd, "comisd %{reg2}, %{reg1}"), "comisd"); 666} 667 668TEST_F(AssemblerX86_64Test, Ucomiss) { 669 DriverStr(RepeatFF(&x86_64::X86_64Assembler::ucomiss, "ucomiss %{reg2}, %{reg1}"), "ucomiss"); 670} 671 672TEST_F(AssemblerX86_64Test, Ucomisd) { 673 DriverStr(RepeatFF(&x86_64::X86_64Assembler::ucomisd, "ucomisd %{reg2}, %{reg1}"), "ucomisd"); 674} 675 676TEST_F(AssemblerX86_64Test, Sqrtss) { 677 DriverStr(RepeatFF(&x86_64::X86_64Assembler::sqrtss, "sqrtss %{reg2}, %{reg1}"), "sqrtss"); 678} 679 680TEST_F(AssemblerX86_64Test, Sqrtsd) { 681 DriverStr(RepeatFF(&x86_64::X86_64Assembler::sqrtsd, "sqrtsd %{reg2}, %{reg1}"), "sqrtsd"); 682} 683 684TEST_F(AssemblerX86_64Test, Xorps) { 685 DriverStr(RepeatFF(&x86_64::X86_64Assembler::xorps, "xorps %{reg2}, %{reg1}"), "xorps"); 686} 687 688TEST_F(AssemblerX86_64Test, Xorpd) { 689 DriverStr(RepeatFF(&x86_64::X86_64Assembler::xorpd, "xorpd %{reg2}, %{reg1}"), "xorpd"); 690} 691 692TEST_F(AssemblerX86_64Test, Andps) { 693 DriverStr(RepeatFF(&x86_64::X86_64Assembler::andps, "andps %{reg2}, %{reg1}"), "andps"); 694} 695 696TEST_F(AssemblerX86_64Test, Andpd) { 697 DriverStr(RepeatFF(&x86_64::X86_64Assembler::andpd, "andpd %{reg2}, %{reg1}"), "andpd"); 698} 699 700TEST_F(AssemblerX86_64Test, Orps) { 701 DriverStr(RepeatFF(&x86_64::X86_64Assembler::orps, "orps %{reg2}, %{reg1}"), "orps"); 702} 703 704TEST_F(AssemblerX86_64Test, Orpd) { 705 DriverStr(RepeatFF(&x86_64::X86_64Assembler::orpd, "orpd %{reg2}, %{reg1}"), "orpd"); 706} 707 708// X87 709 710std::string x87_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED, 711 x86_64::X86_64Assembler* assembler) { 712 std::ostringstream str; 713 714 assembler->fincstp(); 715 str << "fincstp\n"; 716 717 assembler->fsin(); 718 str << "fsin\n"; 719 720 assembler->fcos(); 721 str << "fcos\n"; 722 723 assembler->fptan(); 724 str << "fptan\n"; 725 726 return str.str(); 727} 728 729TEST_F(AssemblerX86_64Test, X87) { 730 DriverFn(&x87_fn, "x87"); 731} 732 733//////////////// 734// CALL / JMP // 735//////////////// 736 737TEST_F(AssemblerX86_64Test, Call) { 738 DriverStr(RepeatR(&x86_64::X86_64Assembler::call, "call *%{reg}"), "call"); 739} 740 741TEST_F(AssemblerX86_64Test, Jmp) { 742 DriverStr(RepeatR(&x86_64::X86_64Assembler::jmp, "jmp *%{reg}"), "jmp"); 743} 744 745TEST_F(AssemblerX86_64Test, Enter) { 746 DriverStr(RepeatI(&x86_64::X86_64Assembler::enter, 2U /* 16b immediate */, "enter ${imm}, $0", 747 true /* Only non-negative number */), "enter"); 748} 749 750TEST_F(AssemblerX86_64Test, RetImm) { 751 DriverStr(RepeatI(&x86_64::X86_64Assembler::ret, 2U /* 16b immediate */, "ret ${imm}", 752 true /* Only non-negative number */), "reti"); 753} 754 755std::string ret_and_leave_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED, 756 x86_64::X86_64Assembler* assembler) { 757 std::ostringstream str; 758 759 assembler->ret(); 760 str << "ret\n"; 761 762 assembler->leave(); 763 str << "leave\n"; 764 765 return str.str(); 766} 767 768TEST_F(AssemblerX86_64Test, RetAndLeave) { 769 DriverFn(&ret_and_leave_fn, "retleave"); 770} 771 772////////// 773// MISC // 774////////// 775 776TEST_F(AssemblerX86_64Test, Bswapl) { 777 DriverStr(Repeatr(&x86_64::X86_64Assembler::bswapl, "bswap %{reg}"), "bswapl"); 778} 779 780TEST_F(AssemblerX86_64Test, Bswapq) { 781 DriverStr(RepeatR(&x86_64::X86_64Assembler::bswapq, "bswap %{reg}"), "bswapq"); 782} 783 784std::string setcc_test_fn(AssemblerX86_64Test::Base* assembler_test, 785 x86_64::X86_64Assembler* assembler) { 786 // From Condition 787 /* 788 kOverflow = 0, 789 kNoOverflow = 1, 790 kBelow = 2, 791 kAboveEqual = 3, 792 kEqual = 4, 793 kNotEqual = 5, 794 kBelowEqual = 6, 795 kAbove = 7, 796 kSign = 8, 797 kNotSign = 9, 798 kParityEven = 10, 799 kParityOdd = 11, 800 kLess = 12, 801 kGreaterEqual = 13, 802 kLessEqual = 14, 803 */ 804 std::string suffixes[15] = { "o", "no", "b", "ae", "e", "ne", "be", "a", "s", "ns", "pe", "po", 805 "l", "ge", "le" }; 806 807 std::vector<x86_64::CpuRegister*> registers = assembler_test->GetRegisters(); 808 809 std::string byte_regs[16]; 810 byte_regs[x86_64::RAX] = "al"; 811 byte_regs[x86_64::RBX] = "bl"; 812 byte_regs[x86_64::RCX] = "cl"; 813 byte_regs[x86_64::RDX] = "dl"; 814 byte_regs[x86_64::RBP] = "bpl"; 815 byte_regs[x86_64::RSP] = "spl"; 816 byte_regs[x86_64::RSI] = "sil"; 817 byte_regs[x86_64::RDI] = "dil"; 818 byte_regs[x86_64::R8] = "r8b"; 819 byte_regs[x86_64::R9] = "r9b"; 820 byte_regs[x86_64::R10] = "r10b"; 821 byte_regs[x86_64::R11] = "r11b"; 822 byte_regs[x86_64::R12] = "r12b"; 823 byte_regs[x86_64::R13] = "r13b"; 824 byte_regs[x86_64::R14] = "r14b"; 825 byte_regs[x86_64::R15] = "r15b"; 826 827 std::ostringstream str; 828 829 for (auto reg : registers) { 830 for (size_t i = 0; i < 15; ++i) { 831 assembler->setcc(static_cast<x86_64::Condition>(i), *reg); 832 str << "set" << suffixes[i] << " %" << byte_regs[reg->AsRegister()] << "\n"; 833 } 834 } 835 836 return str.str(); 837} 838 839TEST_F(AssemblerX86_64Test, SetCC) { 840 DriverFn(&setcc_test_fn, "setcc"); 841} 842 843static x86_64::X86_64ManagedRegister ManagedFromCpu(x86_64::Register r) { 844 return x86_64::X86_64ManagedRegister::FromCpuRegister(r); 845} 846 847static x86_64::X86_64ManagedRegister ManagedFromFpu(x86_64::FloatRegister r) { 848 return x86_64::X86_64ManagedRegister::FromXmmRegister(r); 849} 850 851std::string buildframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED, 852 x86_64::X86_64Assembler* assembler) { 853 // TODO: more interesting spill registers / entry spills. 854 855 // Two random spill regs. 856 std::vector<ManagedRegister> spill_regs; 857 spill_regs.push_back(ManagedFromCpu(x86_64::R10)); 858 spill_regs.push_back(ManagedFromCpu(x86_64::RSI)); 859 860 // Three random entry spills. 861 ManagedRegisterEntrySpills entry_spills; 862 ManagedRegisterSpill spill(ManagedFromCpu(x86_64::RAX), 8, 0); 863 entry_spills.push_back(spill); 864 ManagedRegisterSpill spill2(ManagedFromCpu(x86_64::RBX), 8, 8); 865 entry_spills.push_back(spill2); 866 ManagedRegisterSpill spill3(ManagedFromFpu(x86_64::XMM1), 8, 16); 867 entry_spills.push_back(spill3); 868 869 x86_64::X86_64ManagedRegister method_reg = ManagedFromCpu(x86_64::RDI); 870 871 size_t frame_size = 10 * kStackAlignment; 872 assembler->BuildFrame(10 * kStackAlignment, method_reg, spill_regs, entry_spills); 873 874 // Construct assembly text counterpart. 875 std::ostringstream str; 876 // 1) Push the spill_regs. 877 str << "pushq %rsi\n"; 878 str << "pushq %r10\n"; 879 // 2) Move down the stack pointer. 880 ssize_t displacement = static_cast<ssize_t>(frame_size) - (spill_regs.size() * 8 + 8); 881 str << "subq $" << displacement << ", %rsp\n"; 882 // 3) Store method reference. 883 str << "movl %edi, (%rsp)\n"; 884 // 4) Entry spills. 885 str << "movq %rax, " << frame_size + 0 << "(%rsp)\n"; 886 str << "movq %rbx, " << frame_size + 8 << "(%rsp)\n"; 887 str << "movsd %xmm1, " << frame_size + 16 << "(%rsp)\n"; 888 889 return str.str(); 890} 891 892TEST_F(AssemblerX86_64Test, BuildFrame) { 893 DriverFn(&buildframe_test_fn, "BuildFrame"); 894} 895 896std::string removeframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED, 897 x86_64::X86_64Assembler* assembler) { 898 // TODO: more interesting spill registers / entry spills. 899 900 // Two random spill regs. 901 std::vector<ManagedRegister> spill_regs; 902 spill_regs.push_back(ManagedFromCpu(x86_64::R10)); 903 spill_regs.push_back(ManagedFromCpu(x86_64::RSI)); 904 905 size_t frame_size = 10 * kStackAlignment; 906 assembler->RemoveFrame(10 * kStackAlignment, spill_regs); 907 908 // Construct assembly text counterpart. 909 std::ostringstream str; 910 // 1) Move up the stack pointer. 911 ssize_t displacement = static_cast<ssize_t>(frame_size) - spill_regs.size() * 8 - 8; 912 str << "addq $" << displacement << ", %rsp\n"; 913 // 2) Pop spill regs. 914 str << "popq %r10\n"; 915 str << "popq %rsi\n"; 916 str << "ret\n"; 917 918 return str.str(); 919} 920 921TEST_F(AssemblerX86_64Test, RemoveFrame) { 922 DriverFn(&removeframe_test_fn, "RemoveFrame"); 923} 924 925std::string increaseframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED, 926 x86_64::X86_64Assembler* assembler) { 927 assembler->IncreaseFrameSize(0U); 928 assembler->IncreaseFrameSize(kStackAlignment); 929 assembler->IncreaseFrameSize(10 * kStackAlignment); 930 931 // Construct assembly text counterpart. 932 std::ostringstream str; 933 str << "addq $0, %rsp\n"; 934 str << "addq $-" << kStackAlignment << ", %rsp\n"; 935 str << "addq $-" << 10 * kStackAlignment << ", %rsp\n"; 936 937 return str.str(); 938} 939 940TEST_F(AssemblerX86_64Test, IncreaseFrame) { 941 DriverFn(&increaseframe_test_fn, "IncreaseFrame"); 942} 943 944std::string decreaseframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBUTE_UNUSED, 945 x86_64::X86_64Assembler* assembler) { 946 assembler->DecreaseFrameSize(0U); 947 assembler->DecreaseFrameSize(kStackAlignment); 948 assembler->DecreaseFrameSize(10 * kStackAlignment); 949 950 // Construct assembly text counterpart. 951 std::ostringstream str; 952 str << "addq $0, %rsp\n"; 953 str << "addq $" << kStackAlignment << ", %rsp\n"; 954 str << "addq $" << 10 * kStackAlignment << ", %rsp\n"; 955 956 return str.str(); 957} 958 959TEST_F(AssemblerX86_64Test, DecreaseFrame) { 960 DriverFn(&decreaseframe_test_fn, "DecreaseFrame"); 961} 962 963} // namespace art 964