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