assembler_arm.cc revision 1f359b08f5ad33ae72e4073b86a9257fe1ed11e5
1// Copyright 2011 Google Inc. All Rights Reserved. 2 3#include "src/assembler.h" 4#include "src/logging.h" 5 6namespace art { 7 8// Instruction encoding bits. 9enum { 10 H = 1 << 5, // halfword (or byte) 11 L = 1 << 20, // load (or store) 12 S = 1 << 20, // set condition code (or leave unchanged) 13 W = 1 << 21, // writeback base register (or leave unchanged) 14 A = 1 << 21, // accumulate in multiply instruction (or not) 15 B = 1 << 22, // unsigned byte (or word) 16 N = 1 << 22, // long (or short) 17 U = 1 << 23, // positive (or negative) offset/index 18 P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing) 19 I = 1 << 25, // immediate shifter operand (or not) 20 21 B0 = 1, 22 B1 = 1 << 1, 23 B2 = 1 << 2, 24 B3 = 1 << 3, 25 B4 = 1 << 4, 26 B5 = 1 << 5, 27 B6 = 1 << 6, 28 B7 = 1 << 7, 29 B8 = 1 << 8, 30 B9 = 1 << 9, 31 B10 = 1 << 10, 32 B11 = 1 << 11, 33 B12 = 1 << 12, 34 B16 = 1 << 16, 35 B17 = 1 << 17, 36 B18 = 1 << 18, 37 B19 = 1 << 19, 38 B20 = 1 << 20, 39 B21 = 1 << 21, 40 B22 = 1 << 22, 41 B23 = 1 << 23, 42 B24 = 1 << 24, 43 B25 = 1 << 25, 44 B26 = 1 << 26, 45 B27 = 1 << 27, 46 47 // Instruction bit masks. 48 RdMask = 15 << 12, // in str instruction 49 CondMask = 15 << 28, 50 CoprocessorMask = 15 << 8, 51 OpCodeMask = 15 << 21, // in data-processing instructions 52 Imm24Mask = (1 << 24) - 1, 53 Off12Mask = (1 << 12) - 1, 54 55 // ldrex/strex register field encodings. 56 kLdExRnShift = 16, 57 kLdExRtShift = 12, 58 kStrExRnShift = 16, 59 kStrExRdShift = 12, 60 kStrExRtShift = 0, 61}; 62 63 64static const char* kRegisterNames[] = { 65 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", 66 "fp", "ip", "sp", "lr", "pc" 67}; 68std::ostream& operator<<(std::ostream& os, const Register& rhs) { 69 if (rhs >= R0 && rhs <= PC) { 70 os << kRegisterNames[rhs]; 71 } else { 72 os << "Register[" << int(rhs) << "]"; 73 } 74 return os; 75} 76 77 78std::ostream& operator<<(std::ostream& os, const SRegister& rhs) { 79 if (rhs >= S0 && rhs < kNumberOfSRegisters) { 80 os << "s" << int(rhs); 81 } else { 82 os << "SRegister[" << int(rhs) << "]"; 83 } 84 return os; 85} 86 87 88std::ostream& operator<<(std::ostream& os, const DRegister& rhs) { 89 if (rhs >= D0 && rhs < kNumberOfDRegisters) { 90 os << "d" << int(rhs); 91 } else { 92 os << "DRegister[" << int(rhs) << "]"; 93 } 94 return os; 95} 96 97 98static const char* kConditionNames[] = { 99 "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "AL", 100}; 101std::ostream& operator<<(std::ostream& os, const Condition& rhs) { 102 if (rhs >= EQ && rhs <= AL) { 103 os << kConditionNames[rhs]; 104 } else { 105 os << "Condition[" << int(rhs) << "]"; 106 } 107 return os; 108} 109 110 111void Assembler::Emit(int32_t value) { 112 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 113 buffer_.Emit<int32_t>(value); 114} 115 116 117void Assembler::EmitType01(Condition cond, 118 int type, 119 Opcode opcode, 120 int set_cc, 121 Register rn, 122 Register rd, 123 ShifterOperand so) { 124 CHECK_NE(rd, kNoRegister); 125 CHECK_NE(cond, kNoCondition); 126 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 127 type << kTypeShift | 128 static_cast<int32_t>(opcode) << kOpcodeShift | 129 set_cc << kSShift | 130 static_cast<int32_t>(rn) << kRnShift | 131 static_cast<int32_t>(rd) << kRdShift | 132 so.encoding(); 133 Emit(encoding); 134} 135 136 137void Assembler::EmitType5(Condition cond, int offset, bool link) { 138 CHECK_NE(cond, kNoCondition); 139 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 140 5 << kTypeShift | 141 (link ? 1 : 0) << kLinkShift; 142 Emit(Assembler::EncodeBranchOffset(offset, encoding)); 143} 144 145 146void Assembler::EmitMemOp(Condition cond, 147 bool load, 148 bool byte, 149 Register rd, 150 Address ad) { 151 CHECK_NE(rd, kNoRegister); 152 CHECK_NE(cond, kNoCondition); 153 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 154 B26 | 155 (load ? L : 0) | 156 (byte ? B : 0) | 157 (static_cast<int32_t>(rd) << kRdShift) | 158 ad.encoding(); 159 Emit(encoding); 160} 161 162 163void Assembler::EmitMemOpAddressMode3(Condition cond, 164 int32_t mode, 165 Register rd, 166 Address ad) { 167 CHECK_NE(rd, kNoRegister); 168 CHECK_NE(cond, kNoCondition); 169 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 170 B22 | 171 mode | 172 (static_cast<int32_t>(rd) << kRdShift) | 173 ad.encoding3(); 174 Emit(encoding); 175} 176 177 178void Assembler::EmitMultiMemOp(Condition cond, 179 BlockAddressMode am, 180 bool load, 181 Register base, 182 RegList regs) { 183 CHECK_NE(base, kNoRegister); 184 CHECK_NE(cond, kNoCondition); 185 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 186 B27 | 187 am | 188 (load ? L : 0) | 189 (static_cast<int32_t>(base) << kRnShift) | 190 regs; 191 Emit(encoding); 192} 193 194 195void Assembler::EmitShiftImmediate(Condition cond, 196 Shift opcode, 197 Register rd, 198 Register rm, 199 ShifterOperand so) { 200 CHECK_NE(cond, kNoCondition); 201 CHECK_EQ(so.type(), 1U); 202 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 203 static_cast<int32_t>(MOV) << kOpcodeShift | 204 static_cast<int32_t>(rd) << kRdShift | 205 so.encoding() << kShiftImmShift | 206 static_cast<int32_t>(opcode) << kShiftShift | 207 static_cast<int32_t>(rm); 208 Emit(encoding); 209} 210 211 212void Assembler::EmitShiftRegister(Condition cond, 213 Shift opcode, 214 Register rd, 215 Register rm, 216 ShifterOperand so) { 217 CHECK_NE(cond, kNoCondition); 218 CHECK_EQ(so.type(), 0U); 219 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 220 static_cast<int32_t>(MOV) << kOpcodeShift | 221 static_cast<int32_t>(rd) << kRdShift | 222 so.encoding() << kShiftRegisterShift | 223 static_cast<int32_t>(opcode) << kShiftShift | 224 B4 | 225 static_cast<int32_t>(rm); 226 Emit(encoding); 227} 228 229 230void Assembler::EmitBranch(Condition cond, Label* label, bool link) { 231 if (label->IsBound()) { 232 EmitType5(cond, label->Position() - buffer_.Size(), link); 233 } else { 234 int position = buffer_.Size(); 235 // Use the offset field of the branch instruction for linking the sites. 236 EmitType5(cond, label->position_, link); 237 label->LinkTo(position); 238 } 239} 240 241 242void Assembler::and_(Register rd, Register rn, ShifterOperand so, 243 Condition cond) { 244 EmitType01(cond, so.type(), AND, 0, rn, rd, so); 245} 246 247 248void Assembler::eor(Register rd, Register rn, ShifterOperand so, 249 Condition cond) { 250 EmitType01(cond, so.type(), EOR, 0, rn, rd, so); 251} 252 253 254void Assembler::sub(Register rd, Register rn, ShifterOperand so, 255 Condition cond) { 256 EmitType01(cond, so.type(), SUB, 0, rn, rd, so); 257} 258 259void Assembler::rsb(Register rd, Register rn, ShifterOperand so, 260 Condition cond) { 261 EmitType01(cond, so.type(), RSB, 0, rn, rd, so); 262} 263 264void Assembler::rsbs(Register rd, Register rn, ShifterOperand so, 265 Condition cond) { 266 EmitType01(cond, so.type(), RSB, 1, rn, rd, so); 267} 268 269 270void Assembler::add(Register rd, Register rn, ShifterOperand so, 271 Condition cond) { 272 EmitType01(cond, so.type(), ADD, 0, rn, rd, so); 273} 274 275 276void Assembler::adds(Register rd, Register rn, ShifterOperand so, 277 Condition cond) { 278 EmitType01(cond, so.type(), ADD, 1, rn, rd, so); 279} 280 281 282void Assembler::subs(Register rd, Register rn, ShifterOperand so, 283 Condition cond) { 284 EmitType01(cond, so.type(), SUB, 1, rn, rd, so); 285} 286 287 288void Assembler::adc(Register rd, Register rn, ShifterOperand so, 289 Condition cond) { 290 EmitType01(cond, so.type(), ADC, 0, rn, rd, so); 291} 292 293 294void Assembler::sbc(Register rd, Register rn, ShifterOperand so, 295 Condition cond) { 296 EmitType01(cond, so.type(), SBC, 0, rn, rd, so); 297} 298 299 300void Assembler::rsc(Register rd, Register rn, ShifterOperand so, 301 Condition cond) { 302 EmitType01(cond, so.type(), RSC, 0, rn, rd, so); 303} 304 305 306void Assembler::tst(Register rn, ShifterOperand so, Condition cond) { 307 CHECK_NE(rn, PC); // Reserve tst pc instruction for exception handler marker. 308 EmitType01(cond, so.type(), TST, 1, rn, R0, so); 309} 310 311 312void Assembler::teq(Register rn, ShifterOperand so, Condition cond) { 313 CHECK_NE(rn, PC); // Reserve teq pc instruction for exception handler marker. 314 EmitType01(cond, so.type(), TEQ, 1, rn, R0, so); 315} 316 317 318void Assembler::cmp(Register rn, ShifterOperand so, Condition cond) { 319 EmitType01(cond, so.type(), CMP, 1, rn, R0, so); 320} 321 322 323void Assembler::cmn(Register rn, ShifterOperand so, Condition cond) { 324 EmitType01(cond, so.type(), CMN, 1, rn, R0, so); 325} 326 327 328void Assembler::orr(Register rd, Register rn, 329 ShifterOperand so, Condition cond) { 330 EmitType01(cond, so.type(), ORR, 0, rn, rd, so); 331} 332 333 334void Assembler::orrs(Register rd, Register rn, 335 ShifterOperand so, Condition cond) { 336 EmitType01(cond, so.type(), ORR, 1, rn, rd, so); 337} 338 339 340void Assembler::mov(Register rd, ShifterOperand so, Condition cond) { 341 EmitType01(cond, so.type(), MOV, 0, R0, rd, so); 342} 343 344 345void Assembler::movs(Register rd, ShifterOperand so, Condition cond) { 346 EmitType01(cond, so.type(), MOV, 1, R0, rd, so); 347} 348 349 350void Assembler::bic(Register rd, Register rn, ShifterOperand so, 351 Condition cond) { 352 EmitType01(cond, so.type(), BIC, 0, rn, rd, so); 353} 354 355 356void Assembler::mvn(Register rd, ShifterOperand so, Condition cond) { 357 EmitType01(cond, so.type(), MVN, 0, R0, rd, so); 358} 359 360 361void Assembler::mvns(Register rd, ShifterOperand so, Condition cond) { 362 EmitType01(cond, so.type(), MVN, 1, R0, rd, so); 363} 364 365 366void Assembler::clz(Register rd, Register rm, Condition cond) { 367 CHECK_NE(rd, kNoRegister); 368 CHECK_NE(rm, kNoRegister); 369 CHECK_NE(cond, kNoCondition); 370 CHECK_NE(rd, PC); 371 CHECK_NE(rm, PC); 372 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 373 B24 | B22 | B21 | (0xf << 16) | 374 (static_cast<int32_t>(rd) << kRdShift) | 375 (0xf << 8) | B4 | static_cast<int32_t>(rm); 376 Emit(encoding); 377} 378 379 380void Assembler::movw(Register rd, uint16_t imm16, Condition cond) { 381 CHECK_NE(cond, kNoCondition); 382 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 383 B25 | B24 | ((imm16 >> 12) << 16) | 384 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 385 Emit(encoding); 386} 387 388 389void Assembler::movt(Register rd, uint16_t imm16, Condition cond) { 390 CHECK_NE(cond, kNoCondition); 391 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 392 B25 | B24 | B22 | ((imm16 >> 12) << 16) | 393 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 394 Emit(encoding); 395} 396 397 398void Assembler::EmitMulOp(Condition cond, int32_t opcode, 399 Register rd, Register rn, 400 Register rm, Register rs) { 401 CHECK_NE(rd, kNoRegister); 402 CHECK_NE(rn, kNoRegister); 403 CHECK_NE(rm, kNoRegister); 404 CHECK_NE(rs, kNoRegister); 405 CHECK_NE(cond, kNoCondition); 406 int32_t encoding = opcode | 407 (static_cast<int32_t>(cond) << kConditionShift) | 408 (static_cast<int32_t>(rn) << kRnShift) | 409 (static_cast<int32_t>(rd) << kRdShift) | 410 (static_cast<int32_t>(rs) << kRsShift) | 411 B7 | B4 | 412 (static_cast<int32_t>(rm) << kRmShift); 413 Emit(encoding); 414} 415 416 417void Assembler::mul(Register rd, Register rn, 418 Register rm, Condition cond) { 419 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 420 EmitMulOp(cond, 0, R0, rd, rn, rm); 421} 422 423 424void Assembler::mla(Register rd, Register rn, 425 Register rm, Register ra, Condition cond) { 426 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 427 EmitMulOp(cond, B21, ra, rd, rn, rm); 428} 429 430 431void Assembler::mls(Register rd, Register rn, 432 Register rm, Register ra, Condition cond) { 433 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 434 EmitMulOp(cond, B22 | B21, ra, rd, rn, rm); 435} 436 437 438void Assembler::umull(Register rd_lo, Register rd_hi, 439 Register rn, Register rm, Condition cond) { 440 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 441 EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm); 442} 443 444 445void Assembler::ldr(Register rd, Address ad, Condition cond) { 446 EmitMemOp(cond, true, false, rd, ad); 447} 448 449 450void Assembler::str(Register rd, Address ad, Condition cond) { 451 EmitMemOp(cond, false, false, rd, ad); 452} 453 454 455void Assembler::ldrb(Register rd, Address ad, Condition cond) { 456 EmitMemOp(cond, true, true, rd, ad); 457} 458 459 460void Assembler::strb(Register rd, Address ad, Condition cond) { 461 EmitMemOp(cond, false, true, rd, ad); 462} 463 464 465void Assembler::ldrh(Register rd, Address ad, Condition cond) { 466 EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad); 467} 468 469 470void Assembler::strh(Register rd, Address ad, Condition cond) { 471 EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad); 472} 473 474 475void Assembler::ldrsb(Register rd, Address ad, Condition cond) { 476 EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad); 477} 478 479 480void Assembler::ldrsh(Register rd, Address ad, Condition cond) { 481 EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad); 482} 483 484 485void Assembler::ldrd(Register rd, Address ad, Condition cond) { 486 CHECK_EQ(rd % 2, 0); 487 EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad); 488} 489 490 491void Assembler::strd(Register rd, Address ad, Condition cond) { 492 CHECK_EQ(rd % 2, 0); 493 EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad); 494} 495 496 497void Assembler::ldm(BlockAddressMode am, 498 Register base, 499 RegList regs, 500 Condition cond) { 501 EmitMultiMemOp(cond, am, true, base, regs); 502} 503 504 505void Assembler::stm(BlockAddressMode am, 506 Register base, 507 RegList regs, 508 Condition cond) { 509 EmitMultiMemOp(cond, am, false, base, regs); 510} 511 512 513void Assembler::ldrex(Register rt, Register rn, Condition cond) { 514 CHECK_NE(rn, kNoRegister); 515 CHECK_NE(rt, kNoRegister); 516 CHECK_NE(cond, kNoCondition); 517 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 518 B24 | 519 B23 | 520 L | 521 (static_cast<int32_t>(rn) << kLdExRnShift) | 522 (static_cast<int32_t>(rt) << kLdExRtShift) | 523 B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0; 524 Emit(encoding); 525} 526 527 528void Assembler::strex(Register rd, 529 Register rt, 530 Register rn, 531 Condition cond) { 532 CHECK_NE(rn, kNoRegister); 533 CHECK_NE(rd, kNoRegister); 534 CHECK_NE(rt, kNoRegister); 535 CHECK_NE(cond, kNoCondition); 536 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 537 B24 | 538 B23 | 539 (static_cast<int32_t>(rn) << kStrExRnShift) | 540 (static_cast<int32_t>(rd) << kStrExRdShift) | 541 B11 | B10 | B9 | B8 | B7 | B4 | 542 (static_cast<int32_t>(rt) << kStrExRtShift); 543 Emit(encoding); 544} 545 546 547void Assembler::clrex() { 548 int32_t encoding = (kSpecialCondition << kConditionShift) | 549 B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf; 550 Emit(encoding); 551} 552 553 554void Assembler::nop(Condition cond) { 555 CHECK_NE(cond, kNoCondition); 556 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 557 B25 | B24 | B21 | (0xf << 12); 558 Emit(encoding); 559} 560 561 562void Assembler::vmovsr(SRegister sn, Register rt, Condition cond) { 563 CHECK_NE(sn, kNoSRegister); 564 CHECK_NE(rt, kNoRegister); 565 CHECK_NE(rt, SP); 566 CHECK_NE(rt, PC); 567 CHECK_NE(cond, kNoCondition); 568 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 569 B27 | B26 | B25 | 570 ((static_cast<int32_t>(sn) >> 1)*B16) | 571 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 572 ((static_cast<int32_t>(sn) & 1)*B7) | B4; 573 Emit(encoding); 574} 575 576 577void Assembler::vmovrs(Register rt, SRegister sn, Condition cond) { 578 CHECK_NE(sn, kNoSRegister); 579 CHECK_NE(rt, kNoRegister); 580 CHECK_NE(rt, SP); 581 CHECK_NE(rt, PC); 582 CHECK_NE(cond, kNoCondition); 583 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 584 B27 | B26 | B25 | B20 | 585 ((static_cast<int32_t>(sn) >> 1)*B16) | 586 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 587 ((static_cast<int32_t>(sn) & 1)*B7) | B4; 588 Emit(encoding); 589} 590 591 592void Assembler::vmovsrr(SRegister sm, Register rt, Register rt2, 593 Condition cond) { 594 CHECK_NE(sm, kNoSRegister); 595 CHECK_NE(sm, S31); 596 CHECK_NE(rt, kNoRegister); 597 CHECK_NE(rt, SP); 598 CHECK_NE(rt, PC); 599 CHECK_NE(rt2, kNoRegister); 600 CHECK_NE(rt2, SP); 601 CHECK_NE(rt2, PC); 602 CHECK_NE(cond, kNoCondition); 603 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 604 B27 | B26 | B22 | 605 (static_cast<int32_t>(rt2)*B16) | 606 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 607 ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 608 (static_cast<int32_t>(sm) >> 1); 609 Emit(encoding); 610} 611 612 613void Assembler::vmovrrs(Register rt, Register rt2, SRegister sm, 614 Condition cond) { 615 CHECK_NE(sm, kNoSRegister); 616 CHECK_NE(sm, S31); 617 CHECK_NE(rt, kNoRegister); 618 CHECK_NE(rt, SP); 619 CHECK_NE(rt, PC); 620 CHECK_NE(rt2, kNoRegister); 621 CHECK_NE(rt2, SP); 622 CHECK_NE(rt2, PC); 623 CHECK_NE(rt, rt2); 624 CHECK_NE(cond, kNoCondition); 625 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 626 B27 | B26 | B22 | B20 | 627 (static_cast<int32_t>(rt2)*B16) | 628 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 629 ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 630 (static_cast<int32_t>(sm) >> 1); 631 Emit(encoding); 632} 633 634 635void Assembler::vmovdrr(DRegister dm, Register rt, Register rt2, 636 Condition cond) { 637 CHECK_NE(dm, kNoDRegister); 638 CHECK_NE(rt, kNoRegister); 639 CHECK_NE(rt, SP); 640 CHECK_NE(rt, PC); 641 CHECK_NE(rt2, kNoRegister); 642 CHECK_NE(rt2, SP); 643 CHECK_NE(rt2, PC); 644 CHECK_NE(cond, kNoCondition); 645 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 646 B27 | B26 | B22 | 647 (static_cast<int32_t>(rt2)*B16) | 648 (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 649 ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 650 (static_cast<int32_t>(dm) & 0xf); 651 Emit(encoding); 652} 653 654 655void Assembler::vmovrrd(Register rt, Register rt2, DRegister dm, 656 Condition cond) { 657 CHECK_NE(dm, kNoDRegister); 658 CHECK_NE(rt, kNoRegister); 659 CHECK_NE(rt, SP); 660 CHECK_NE(rt, PC); 661 CHECK_NE(rt2, kNoRegister); 662 CHECK_NE(rt2, SP); 663 CHECK_NE(rt2, PC); 664 CHECK_NE(rt, rt2); 665 CHECK_NE(cond, kNoCondition); 666 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 667 B27 | B26 | B22 | B20 | 668 (static_cast<int32_t>(rt2)*B16) | 669 (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 670 ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 671 (static_cast<int32_t>(dm) & 0xf); 672 Emit(encoding); 673} 674 675 676void Assembler::vldrs(SRegister sd, Address ad, Condition cond) { 677 CHECK_NE(sd, kNoSRegister); 678 CHECK_NE(cond, kNoCondition); 679 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 680 B27 | B26 | B24 | B20 | 681 ((static_cast<int32_t>(sd) & 1)*B22) | 682 ((static_cast<int32_t>(sd) >> 1)*B12) | 683 B11 | B9 | ad.vencoding(); 684 Emit(encoding); 685} 686 687 688void Assembler::vstrs(SRegister sd, Address ad, Condition cond) { 689 CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC); 690 CHECK_NE(sd, kNoSRegister); 691 CHECK_NE(cond, kNoCondition); 692 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 693 B27 | B26 | B24 | 694 ((static_cast<int32_t>(sd) & 1)*B22) | 695 ((static_cast<int32_t>(sd) >> 1)*B12) | 696 B11 | B9 | ad.vencoding(); 697 Emit(encoding); 698} 699 700 701void Assembler::vldrd(DRegister dd, Address ad, Condition cond) { 702 CHECK_NE(dd, kNoDRegister); 703 CHECK_NE(cond, kNoCondition); 704 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 705 B27 | B26 | B24 | B20 | 706 ((static_cast<int32_t>(dd) >> 4)*B22) | 707 ((static_cast<int32_t>(dd) & 0xf)*B12) | 708 B11 | B9 | B8 | ad.vencoding(); 709 Emit(encoding); 710} 711 712 713void Assembler::vstrd(DRegister dd, Address ad, Condition cond) { 714 CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC); 715 CHECK_NE(dd, kNoDRegister); 716 CHECK_NE(cond, kNoCondition); 717 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 718 B27 | B26 | B24 | 719 ((static_cast<int32_t>(dd) >> 4)*B22) | 720 ((static_cast<int32_t>(dd) & 0xf)*B12) | 721 B11 | B9 | B8 | ad.vencoding(); 722 Emit(encoding); 723} 724 725 726void Assembler::EmitVFPsss(Condition cond, int32_t opcode, 727 SRegister sd, SRegister sn, SRegister sm) { 728 CHECK_NE(sd, kNoSRegister); 729 CHECK_NE(sn, kNoSRegister); 730 CHECK_NE(sm, kNoSRegister); 731 CHECK_NE(cond, kNoCondition); 732 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 733 B27 | B26 | B25 | B11 | B9 | opcode | 734 ((static_cast<int32_t>(sd) & 1)*B22) | 735 ((static_cast<int32_t>(sn) >> 1)*B16) | 736 ((static_cast<int32_t>(sd) >> 1)*B12) | 737 ((static_cast<int32_t>(sn) & 1)*B7) | 738 ((static_cast<int32_t>(sm) & 1)*B5) | 739 (static_cast<int32_t>(sm) >> 1); 740 Emit(encoding); 741} 742 743 744void Assembler::EmitVFPddd(Condition cond, int32_t opcode, 745 DRegister dd, DRegister dn, DRegister dm) { 746 CHECK_NE(dd, kNoDRegister); 747 CHECK_NE(dn, kNoDRegister); 748 CHECK_NE(dm, kNoDRegister); 749 CHECK_NE(cond, kNoCondition); 750 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 751 B27 | B26 | B25 | B11 | B9 | B8 | opcode | 752 ((static_cast<int32_t>(dd) >> 4)*B22) | 753 ((static_cast<int32_t>(dn) & 0xf)*B16) | 754 ((static_cast<int32_t>(dd) & 0xf)*B12) | 755 ((static_cast<int32_t>(dn) >> 4)*B7) | 756 ((static_cast<int32_t>(dm) >> 4)*B5) | 757 (static_cast<int32_t>(dm) & 0xf); 758 Emit(encoding); 759} 760 761 762void Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) { 763 EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm); 764} 765 766 767void Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) { 768 EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm); 769} 770 771 772bool Assembler::vmovs(SRegister sd, float s_imm, Condition cond) { 773 uint32_t imm32 = bit_cast<uint32_t, float>(s_imm); 774 if (((imm32 & ((1 << 19) - 1)) == 0) && 775 ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) || 776 (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) { 777 uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) | 778 ((imm32 >> 19) & ((1 << 6) -1)); 779 EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf), 780 sd, S0, S0); 781 return true; 782 } 783 return false; 784} 785 786 787bool Assembler::vmovd(DRegister dd, double d_imm, Condition cond) { 788 uint64_t imm64 = bit_cast<uint64_t, double>(d_imm); 789 if (((imm64 & ((1LL << 48) - 1)) == 0) && 790 ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) || 791 (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) { 792 uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) | 793 ((imm64 >> 48) & ((1 << 6) -1)); 794 EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf), 795 dd, D0, D0); 796 return true; 797 } 798 return false; 799} 800 801 802void Assembler::vadds(SRegister sd, SRegister sn, SRegister sm, 803 Condition cond) { 804 EmitVFPsss(cond, B21 | B20, sd, sn, sm); 805} 806 807 808void Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm, 809 Condition cond) { 810 EmitVFPddd(cond, B21 | B20, dd, dn, dm); 811} 812 813 814void Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm, 815 Condition cond) { 816 EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm); 817} 818 819 820void Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm, 821 Condition cond) { 822 EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm); 823} 824 825 826void Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm, 827 Condition cond) { 828 EmitVFPsss(cond, B21, sd, sn, sm); 829} 830 831 832void Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm, 833 Condition cond) { 834 EmitVFPddd(cond, B21, dd, dn, dm); 835} 836 837 838void Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm, 839 Condition cond) { 840 EmitVFPsss(cond, 0, sd, sn, sm); 841} 842 843 844void Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm, 845 Condition cond) { 846 EmitVFPddd(cond, 0, dd, dn, dm); 847} 848 849 850void Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm, 851 Condition cond) { 852 EmitVFPsss(cond, B6, sd, sn, sm); 853} 854 855 856void Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm, 857 Condition cond) { 858 EmitVFPddd(cond, B6, dd, dn, dm); 859} 860 861 862void Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm, 863 Condition cond) { 864 EmitVFPsss(cond, B23, sd, sn, sm); 865} 866 867 868void Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm, 869 Condition cond) { 870 EmitVFPddd(cond, B23, dd, dn, dm); 871} 872 873 874void Assembler::vabss(SRegister sd, SRegister sm, Condition cond) { 875 EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm); 876} 877 878 879void Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) { 880 EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm); 881} 882 883 884void Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) { 885 EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm); 886} 887 888 889void Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) { 890 EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm); 891} 892 893 894void Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) { 895 EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm); 896} 897 898void Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) { 899 EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm); 900} 901 902 903void Assembler::EmitVFPsd(Condition cond, int32_t opcode, 904 SRegister sd, DRegister dm) { 905 CHECK_NE(sd, kNoSRegister); 906 CHECK_NE(dm, kNoDRegister); 907 CHECK_NE(cond, kNoCondition); 908 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 909 B27 | B26 | B25 | B11 | B9 | opcode | 910 ((static_cast<int32_t>(sd) & 1)*B22) | 911 ((static_cast<int32_t>(sd) >> 1)*B12) | 912 ((static_cast<int32_t>(dm) >> 4)*B5) | 913 (static_cast<int32_t>(dm) & 0xf); 914 Emit(encoding); 915} 916 917 918void Assembler::EmitVFPds(Condition cond, int32_t opcode, 919 DRegister dd, SRegister sm) { 920 CHECK_NE(dd, kNoDRegister); 921 CHECK_NE(sm, kNoSRegister); 922 CHECK_NE(cond, kNoCondition); 923 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 924 B27 | B26 | B25 | B11 | B9 | opcode | 925 ((static_cast<int32_t>(dd) >> 4)*B22) | 926 ((static_cast<int32_t>(dd) & 0xf)*B12) | 927 ((static_cast<int32_t>(sm) & 1)*B5) | 928 (static_cast<int32_t>(sm) >> 1); 929 Emit(encoding); 930} 931 932 933void Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) { 934 EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm); 935} 936 937 938void Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) { 939 EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm); 940} 941 942 943void Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) { 944 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm); 945} 946 947 948void Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) { 949 EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm); 950} 951 952 953void Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) { 954 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm); 955} 956 957 958void Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) { 959 EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm); 960} 961 962 963void Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) { 964 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm); 965} 966 967 968void Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) { 969 EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm); 970} 971 972 973void Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) { 974 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm); 975} 976 977 978void Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) { 979 EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm); 980} 981 982 983void Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) { 984 EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm); 985} 986 987 988void Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) { 989 EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm); 990} 991 992 993void Assembler::vcmpsz(SRegister sd, Condition cond) { 994 EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0); 995} 996 997 998void Assembler::vcmpdz(DRegister dd, Condition cond) { 999 EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0); 1000} 1001 1002 1003void Assembler::vmstat(Condition cond) { // VMRS APSR_nzcv, FPSCR 1004 CHECK_NE(cond, kNoCondition); 1005 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1006 B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 | 1007 (static_cast<int32_t>(PC)*B12) | 1008 B11 | B9 | B4; 1009 Emit(encoding); 1010} 1011 1012 1013void Assembler::svc(uint32_t imm24) { 1014 CHECK(IsUint(24, imm24)); 1015 int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24; 1016 Emit(encoding); 1017} 1018 1019 1020void Assembler::bkpt(uint16_t imm16) { 1021 int32_t encoding = (AL << kConditionShift) | B24 | B21 | 1022 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); 1023 Emit(encoding); 1024} 1025 1026 1027void Assembler::b(Label* label, Condition cond) { 1028 EmitBranch(cond, label, false); 1029} 1030 1031 1032void Assembler::bl(Label* label, Condition cond) { 1033 EmitBranch(cond, label, true); 1034} 1035 1036 1037void Assembler::blx(Register rm, Condition cond) { 1038 CHECK_NE(rm, kNoRegister); 1039 CHECK_NE(cond, kNoCondition); 1040 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1041 B24 | B21 | (0xfff << 8) | B5 | B4 | 1042 (static_cast<int32_t>(rm) << kRmShift); 1043 Emit(encoding); 1044} 1045 1046 1047void Assembler::MarkExceptionHandler(Label* label) { 1048 EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); 1049 Label l; 1050 b(&l); 1051 EmitBranch(AL, label, false); 1052 Bind(&l); 1053} 1054 1055 1056void Assembler::Bind(Label* label) { 1057 CHECK(!label->IsBound()); 1058 int bound_pc = buffer_.Size(); 1059 while (label->IsLinked()) { 1060 int32_t position = label->Position(); 1061 int32_t next = buffer_.Load<int32_t>(position); 1062 int32_t encoded = Assembler::EncodeBranchOffset(bound_pc - position, next); 1063 buffer_.Store<int32_t>(position, encoded); 1064 label->position_ = Assembler::DecodeBranchOffset(next); 1065 } 1066 label->BindTo(bound_pc); 1067} 1068 1069 1070void Assembler::EncodeUint32InTstInstructions(uint32_t data) { 1071 // TODO: Consider using movw ip, <16 bits>. 1072 while (!IsUint(8, data)) { 1073 tst(R0, ShifterOperand(data & 0xFF), VS); 1074 data >>= 8; 1075 } 1076 tst(R0, ShifterOperand(data), MI); 1077} 1078 1079int32_t Assembler::EncodeBranchOffset(int offset, int32_t inst) { 1080 // The offset is off by 8 due to the way the ARM CPUs read PC. 1081 offset -= 8; 1082 CHECK(IsAligned(offset, 4)); 1083 CHECK(IsInt(CountOneBits(kBranchOffsetMask), offset)); 1084 1085 // Properly preserve only the bits supported in the instruction. 1086 offset >>= 2; 1087 offset &= kBranchOffsetMask; 1088 return (inst & ~kBranchOffsetMask) | offset; 1089} 1090 1091 1092int Assembler::DecodeBranchOffset(int32_t inst) { 1093 // Sign-extend, left-shift by 2, then add 8. 1094 return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8); 1095} 1096 1097} // namespace art 1098