1 // Copyright 2015, ARM Limited 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are met: 6 // 7 // * Redistributions of source code must retain the above copyright notice, 8 // this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above copyright notice, 10 // this list of conditions and the following disclaimer in the documentation 11 // and/or other materials provided with the distribution. 12 // * Neither the name of ARM Limited nor the names of its contributors may be 13 // used to endorse or promote products derived from this software without 14 // specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27 #ifndef VIXL_A64_MACRO_ASSEMBLER_A64_H_ 28 #define VIXL_A64_MACRO_ASSEMBLER_A64_H_ 29 30 #include <algorithm> 31 #include <limits> 32 33 #include "vixl/globals.h" 34 #include "vixl/a64/assembler-a64.h" 35 #include "vixl/a64/debugger-a64.h" 36 37 38 #define LS_MACRO_LIST(V) \ 39 V(Ldrb, Register&, rt, LDRB_w) \ 40 V(Strb, Register&, rt, STRB_w) \ 41 V(Ldrsb, Register&, rt, rt.Is64Bits() ? LDRSB_x : LDRSB_w) \ 42 V(Ldrh, Register&, rt, LDRH_w) \ 43 V(Strh, Register&, rt, STRH_w) \ 44 V(Ldrsh, Register&, rt, rt.Is64Bits() ? LDRSH_x : LDRSH_w) \ 45 V(Ldr, CPURegister&, rt, LoadOpFor(rt)) \ 46 V(Str, CPURegister&, rt, StoreOpFor(rt)) \ 47 V(Ldrsw, Register&, rt, LDRSW_x) 48 49 50 #define LSPAIR_MACRO_LIST(V) \ 51 V(Ldp, CPURegister&, rt, rt2, LoadPairOpFor(rt, rt2)) \ 52 V(Stp, CPURegister&, rt, rt2, StorePairOpFor(rt, rt2)) \ 53 V(Ldpsw, CPURegister&, rt, rt2, LDPSW_x) 54 55 namespace vixl { 56 57 // Forward declaration 58 class MacroAssembler; 59 class UseScratchRegisterScope; 60 61 class Pool { 62 public: 63 explicit Pool(MacroAssembler* masm) 64 : checkpoint_(kNoCheckpointRequired), masm_(masm) { 65 Reset(); 66 } 67 68 void Reset() { 69 checkpoint_ = kNoCheckpointRequired; 70 monitor_ = 0; 71 } 72 73 void Block() { monitor_++; } 74 void Release(); 75 bool IsBlocked() const { return monitor_ != 0; } 76 77 static const ptrdiff_t kNoCheckpointRequired = PTRDIFF_MAX; 78 79 void SetNextCheckpoint(ptrdiff_t checkpoint); 80 ptrdiff_t checkpoint() const { return checkpoint_; } 81 82 enum EmitOption { 83 kBranchRequired, 84 kNoBranchRequired 85 }; 86 87 protected: 88 // Next buffer offset at which a check is required for this pool. 89 ptrdiff_t checkpoint_; 90 // Indicates whether the emission of this pool is blocked. 91 int monitor_; 92 // The MacroAssembler using this pool. 93 MacroAssembler* masm_; 94 }; 95 96 97 class LiteralPool : public Pool { 98 public: 99 explicit LiteralPool(MacroAssembler* masm); 100 ~LiteralPool(); 101 void Reset(); 102 103 template <typename T> 104 RawLiteral* Add(T imm) { 105 return AddEntry(new Literal<T>(imm)); 106 } 107 template <typename T> 108 RawLiteral* Add(T high64, T low64) { 109 return AddEntry(new Literal<T>(high64, low64)); 110 } 111 RawLiteral* AddEntry(RawLiteral* literal); 112 bool IsEmpty() const { return entries_.empty(); } 113 size_t Size() const; 114 size_t MaxSize() const; 115 size_t OtherPoolsMaxSize() const; 116 117 void CheckEmitFor(size_t amount, EmitOption option = kBranchRequired); 118 void Emit(EmitOption option = kNoBranchRequired); 119 120 void SetNextRecommendedCheckpoint(ptrdiff_t offset); 121 ptrdiff_t NextRecommendedCheckpoint(); 122 123 // Recommended not exact since the pool can be blocked for short periods. 124 static const ptrdiff_t kRecommendedLiteralPoolRange = 128 * KBytes; 125 126 private: 127 std::vector<RawLiteral*> entries_; 128 size_t size_; 129 ptrdiff_t first_use_; 130 // The parent class `Pool` provides a `checkpoint_`, which is the buffer 131 // offset before which a check *must* occur. This recommended checkpoint 132 // indicates when we would like to start emitting the constant pool. The 133 // MacroAssembler can, but does not have to, check the buffer when the 134 // checkpoint is reached. 135 ptrdiff_t recommended_checkpoint_; 136 }; 137 138 139 inline size_t LiteralPool::Size() const { 140 // Account for the pool header. 141 return size_ + kInstructionSize; 142 } 143 144 145 inline size_t LiteralPool::MaxSize() const { 146 // Account for the potential branch over the pool. 147 return Size() + kInstructionSize; 148 } 149 150 151 inline ptrdiff_t LiteralPool::NextRecommendedCheckpoint() { 152 return first_use_ + kRecommendedLiteralPoolRange; 153 } 154 155 156 class VeneerPool : public Pool { 157 public: 158 explicit VeneerPool(MacroAssembler* masm) : Pool(masm) {} 159 160 void Reset(); 161 162 void Block() { monitor_++; } 163 void Release(); 164 bool IsBlocked() const { return monitor_ != 0; } 165 bool IsEmpty() const { return unresolved_branches_.empty(); } 166 167 class BranchInfo { 168 public: 169 BranchInfo() 170 : max_reachable_pc_(0), pc_offset_(0), 171 label_(NULL), branch_type_(UnknownBranchType) {} 172 BranchInfo(ptrdiff_t offset, Label* label, ImmBranchType branch_type) 173 : pc_offset_(offset), label_(label), branch_type_(branch_type) { 174 max_reachable_pc_ = 175 pc_offset_ + Instruction::ImmBranchForwardRange(branch_type_); 176 } 177 178 static bool IsValidComparison(const BranchInfo& branch_1, 179 const BranchInfo& branch_2) { 180 // BranchInfo are always compared against against other objects with 181 // the same branch type. 182 if (branch_1.branch_type_ != branch_2.branch_type_) { 183 return false; 184 } 185 // Since we should never have two branch infos with the same offsets, it 186 // first looks like we should check that offsets are different. However 187 // the operators may also be used to *search* for a branch info in the 188 // set. 189 bool same_offsets = (branch_1.pc_offset_ == branch_2.pc_offset_); 190 return (!same_offsets || 191 ((branch_1.label_ == branch_2.label_) && 192 (branch_1.max_reachable_pc_ == branch_2.max_reachable_pc_))); 193 } 194 195 // We must provide comparison operators to work with InvalSet. 196 bool operator==(const BranchInfo& other) const { 197 VIXL_ASSERT(IsValidComparison(*this, other)); 198 return pc_offset_ == other.pc_offset_; 199 } 200 bool operator<(const BranchInfo& other) const { 201 VIXL_ASSERT(IsValidComparison(*this, other)); 202 return pc_offset_ < other.pc_offset_; 203 } 204 bool operator<=(const BranchInfo& other) const { 205 VIXL_ASSERT(IsValidComparison(*this, other)); 206 return pc_offset_ <= other.pc_offset_; 207 } 208 bool operator>(const BranchInfo& other) const { 209 VIXL_ASSERT(IsValidComparison(*this, other)); 210 return pc_offset_ > other.pc_offset_; 211 } 212 213 // Maximum position reachable by the branch using a positive branch offset. 214 ptrdiff_t max_reachable_pc_; 215 // Offset of the branch in the code generation buffer. 216 ptrdiff_t pc_offset_; 217 // The label branched to. 218 Label* label_; 219 ImmBranchType branch_type_; 220 }; 221 222 bool BranchTypeUsesVeneers(ImmBranchType type) { 223 return (type != UnknownBranchType) && (type != UncondBranchType); 224 } 225 226 void RegisterUnresolvedBranch(ptrdiff_t branch_pos, 227 Label* label, 228 ImmBranchType branch_type); 229 void DeleteUnresolvedBranchInfoForLabel(Label* label); 230 231 bool ShouldEmitVeneer(int max_reachable_pc, size_t amount); 232 bool ShouldEmitVeneers(size_t amount) { 233 return ShouldEmitVeneer(unresolved_branches_.FirstLimit(), amount); 234 } 235 236 void CheckEmitFor(size_t amount, EmitOption option = kBranchRequired); 237 void Emit(EmitOption option, size_t margin); 238 239 // The code size generated for a veneer. Currently one branch instruction. 240 // This is for code size checking purposes, and can be extended in the future 241 // for example if we decide to add nops between the veneers. 242 static const int kVeneerCodeSize = 1 * kInstructionSize; 243 // The maximum size of code other than veneers that can be generated when 244 // emitting a veneer pool. Currently there can be an additional branch to jump 245 // over the pool. 246 static const int kPoolNonVeneerCodeSize = 1 * kInstructionSize; 247 248 void UpdateNextCheckPoint() { 249 SetNextCheckpoint(NextCheckPoint()); 250 } 251 252 int NumberOfPotentialVeneers() const { 253 return unresolved_branches_.size(); 254 } 255 256 size_t MaxSize() const { 257 return 258 kPoolNonVeneerCodeSize + unresolved_branches_.size() * kVeneerCodeSize; 259 } 260 261 size_t OtherPoolsMaxSize() const; 262 263 static const int kNPreallocatedInfos = 4; 264 static const ptrdiff_t kInvalidOffset = PTRDIFF_MAX; 265 static const size_t kReclaimFrom = 128; 266 static const size_t kReclaimFactor = 16; 267 268 private: 269 typedef InvalSet<BranchInfo, 270 kNPreallocatedInfos, 271 ptrdiff_t, 272 kInvalidOffset, 273 kReclaimFrom, 274 kReclaimFactor> BranchInfoTypedSetBase; 275 typedef InvalSetIterator<BranchInfoTypedSetBase> BranchInfoTypedSetIterBase; 276 277 class BranchInfoTypedSet : public BranchInfoTypedSetBase { 278 public: 279 BranchInfoTypedSet() : BranchInfoTypedSetBase() {} 280 281 ptrdiff_t FirstLimit() { 282 if (empty()) { 283 return kInvalidOffset; 284 } 285 return min_element_key(); 286 } 287 }; 288 289 class BranchInfoTypedSetIterator : public BranchInfoTypedSetIterBase { 290 public: 291 BranchInfoTypedSetIterator() : BranchInfoTypedSetIterBase(NULL) {} 292 explicit BranchInfoTypedSetIterator(BranchInfoTypedSet* typed_set) 293 : BranchInfoTypedSetIterBase(typed_set) {} 294 }; 295 296 class BranchInfoSet { 297 public: 298 void insert(BranchInfo branch_info) { 299 ImmBranchType type = branch_info.branch_type_; 300 VIXL_ASSERT(IsValidBranchType(type)); 301 typed_set_[BranchIndexFromType(type)].insert(branch_info); 302 } 303 304 void erase(BranchInfo branch_info) { 305 if (IsValidBranchType(branch_info.branch_type_)) { 306 int index = 307 BranchInfoSet::BranchIndexFromType(branch_info.branch_type_); 308 typed_set_[index].erase(branch_info); 309 } 310 } 311 312 size_t size() const { 313 size_t res = 0; 314 for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) { 315 res += typed_set_[i].size(); 316 } 317 return res; 318 } 319 320 bool empty() const { 321 for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) { 322 if (!typed_set_[i].empty()) { 323 return false; 324 } 325 } 326 return true; 327 } 328 329 ptrdiff_t FirstLimit() { 330 ptrdiff_t res = kInvalidOffset; 331 for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) { 332 res = std::min(res, typed_set_[i].FirstLimit()); 333 } 334 return res; 335 } 336 337 void Reset() { 338 for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) { 339 typed_set_[i].clear(); 340 } 341 } 342 343 static ImmBranchType BranchTypeFromIndex(int index) { 344 switch (index) { 345 case 0: 346 return CondBranchType; 347 case 1: 348 return CompareBranchType; 349 case 2: 350 return TestBranchType; 351 default: 352 VIXL_UNREACHABLE(); 353 return UnknownBranchType; 354 } 355 } 356 static int BranchIndexFromType(ImmBranchType branch_type) { 357 switch (branch_type) { 358 case CondBranchType: 359 return 0; 360 case CompareBranchType: 361 return 1; 362 case TestBranchType: 363 return 2; 364 default: 365 VIXL_UNREACHABLE(); 366 return 0; 367 } 368 } 369 370 bool IsValidBranchType(ImmBranchType branch_type) { 371 return (branch_type != UnknownBranchType) && 372 (branch_type != UncondBranchType); 373 } 374 375 private: 376 static const int kNumberOfTrackedBranchTypes = 3; 377 BranchInfoTypedSet typed_set_[kNumberOfTrackedBranchTypes]; 378 379 friend class VeneerPool; 380 friend class BranchInfoSetIterator; 381 }; 382 383 class BranchInfoSetIterator { 384 public: 385 explicit BranchInfoSetIterator(BranchInfoSet* set) : set_(set) { 386 for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) { 387 new(&sub_iterator_[i]) 388 BranchInfoTypedSetIterator(&(set_->typed_set_[i])); 389 } 390 } 391 392 VeneerPool::BranchInfo* Current() { 393 for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) { 394 if (!sub_iterator_[i].Done()) { 395 return sub_iterator_[i].Current(); 396 } 397 } 398 VIXL_UNREACHABLE(); 399 return NULL; 400 } 401 402 void Advance() { 403 VIXL_ASSERT(!Done()); 404 for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) { 405 if (!sub_iterator_[i].Done()) { 406 sub_iterator_[i].Advance(); 407 return; 408 } 409 } 410 VIXL_UNREACHABLE(); 411 } 412 413 bool Done() const { 414 for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) { 415 if (!sub_iterator_[i].Done()) return false; 416 } 417 return true; 418 } 419 420 void AdvanceToNextType() { 421 VIXL_ASSERT(!Done()); 422 for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) { 423 if (!sub_iterator_[i].Done()) { 424 sub_iterator_[i].Finish(); 425 return; 426 } 427 } 428 VIXL_UNREACHABLE(); 429 } 430 431 void DeleteCurrentAndAdvance() { 432 for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) { 433 if (!sub_iterator_[i].Done()) { 434 sub_iterator_[i].DeleteCurrentAndAdvance(); 435 return; 436 } 437 } 438 } 439 440 private: 441 BranchInfoSet* set_; 442 BranchInfoTypedSetIterator 443 sub_iterator_[BranchInfoSet::kNumberOfTrackedBranchTypes]; 444 }; 445 446 ptrdiff_t NextCheckPoint() { 447 if (unresolved_branches_.empty()) { 448 return kNoCheckpointRequired; 449 } else { 450 return unresolved_branches_.FirstLimit(); 451 } 452 } 453 454 // Information about unresolved (forward) branches. 455 BranchInfoSet unresolved_branches_; 456 }; 457 458 459 // Required InvalSet template specialisations. 460 template<> 461 inline ptrdiff_t InvalSet<VeneerPool::BranchInfo, 462 VeneerPool::kNPreallocatedInfos, 463 ptrdiff_t, 464 VeneerPool::kInvalidOffset, 465 VeneerPool::kReclaimFrom, 466 VeneerPool::kReclaimFactor>::Key( 467 const VeneerPool::BranchInfo& branch_info) { 468 return branch_info.max_reachable_pc_; 469 } 470 template<> 471 inline void InvalSet<VeneerPool::BranchInfo, 472 VeneerPool::kNPreallocatedInfos, 473 ptrdiff_t, 474 VeneerPool::kInvalidOffset, 475 VeneerPool::kReclaimFrom, 476 VeneerPool::kReclaimFactor>::SetKey( 477 VeneerPool::BranchInfo* branch_info, ptrdiff_t key) { 478 branch_info->max_reachable_pc_ = key; 479 } 480 481 482 // This scope has the following purposes: 483 // * Acquire/Release the underlying assembler's code buffer. 484 // * This is mandatory before emitting. 485 // * Emit the literal pool if necessary before emitting the macro-instruction. 486 // * Ensure there is enough space to emit the macro-instruction. 487 class EmissionCheckScope { 488 public: 489 EmissionCheckScope(MacroAssembler* masm, size_t size); 490 ~EmissionCheckScope(); 491 492 protected: 493 #ifdef VIXL_DEBUG 494 MacroAssembler* masm_; 495 Label start_; 496 size_t size_; 497 #endif 498 }; 499 500 501 // Helper for common Emission checks. 502 // The macro-instruction maps to a single instruction. 503 class SingleEmissionCheckScope : public EmissionCheckScope { 504 public: 505 explicit SingleEmissionCheckScope(MacroAssembler* masm) 506 : EmissionCheckScope(masm, kInstructionSize) {} 507 }; 508 509 510 // The macro instruction is a "typical" macro-instruction. Typical macro- 511 // instruction only emit a few instructions, a few being defined as 8 here. 512 class MacroEmissionCheckScope : public EmissionCheckScope { 513 public: 514 explicit MacroEmissionCheckScope(MacroAssembler* masm) 515 : EmissionCheckScope(masm, kTypicalMacroInstructionMaxSize) {} 516 517 private: 518 static const size_t kTypicalMacroInstructionMaxSize = 8 * kInstructionSize; 519 }; 520 521 522 enum BranchType { 523 // Copies of architectural conditions. 524 // The associated conditions can be used in place of those, the code will 525 // take care of reinterpreting them with the correct type. 526 integer_eq = eq, 527 integer_ne = ne, 528 integer_hs = hs, 529 integer_lo = lo, 530 integer_mi = mi, 531 integer_pl = pl, 532 integer_vs = vs, 533 integer_vc = vc, 534 integer_hi = hi, 535 integer_ls = ls, 536 integer_ge = ge, 537 integer_lt = lt, 538 integer_gt = gt, 539 integer_le = le, 540 integer_al = al, 541 integer_nv = nv, 542 543 // These two are *different* from the architectural codes al and nv. 544 // 'always' is used to generate unconditional branches. 545 // 'never' is used to not generate a branch (generally as the inverse 546 // branch type of 'always). 547 always, never, 548 // cbz and cbnz 549 reg_zero, reg_not_zero, 550 // tbz and tbnz 551 reg_bit_clear, reg_bit_set, 552 553 // Aliases. 554 kBranchTypeFirstCondition = eq, 555 kBranchTypeLastCondition = nv, 556 kBranchTypeFirstUsingReg = reg_zero, 557 kBranchTypeFirstUsingBit = reg_bit_clear 558 }; 559 560 561 enum DiscardMoveMode { kDontDiscardForSameWReg, kDiscardForSameWReg }; 562 563 564 class MacroAssembler : public Assembler { 565 public: 566 MacroAssembler(size_t capacity, 567 PositionIndependentCodeOption pic = PositionIndependentCode); 568 MacroAssembler(byte * buffer, size_t capacity, 569 PositionIndependentCodeOption pic = PositionIndependentCode); 570 ~MacroAssembler(); 571 572 // Start generating code from the beginning of the buffer, discarding any code 573 // and data that has already been emitted into the buffer. 574 // 575 // In order to avoid any accidental transfer of state, Reset ASSERTs that the 576 // constant pool is not blocked. 577 void Reset(); 578 579 // Finalize a code buffer of generated instructions. This function must be 580 // called before executing or copying code from the buffer. 581 void FinalizeCode(); 582 583 584 // Constant generation helpers. 585 // These functions return the number of instructions required to move the 586 // immediate into the destination register. Also, if the masm pointer is 587 // non-null, it generates the code to do so. 588 // The two features are implemented using one function to avoid duplication of 589 // the logic. 590 // The function can be used to evaluate the cost of synthesizing an 591 // instruction using 'mov immediate' instructions. A user might prefer loading 592 // a constant using the literal pool instead of using multiple 'mov immediate' 593 // instructions. 594 static int MoveImmediateHelper(MacroAssembler* masm, 595 const Register &rd, 596 uint64_t imm); 597 static bool OneInstrMoveImmediateHelper(MacroAssembler* masm, 598 const Register& dst, 599 int64_t imm); 600 601 602 // Logical macros. 603 void And(const Register& rd, 604 const Register& rn, 605 const Operand& operand); 606 void Ands(const Register& rd, 607 const Register& rn, 608 const Operand& operand); 609 void Bic(const Register& rd, 610 const Register& rn, 611 const Operand& operand); 612 void Bics(const Register& rd, 613 const Register& rn, 614 const Operand& operand); 615 void Orr(const Register& rd, 616 const Register& rn, 617 const Operand& operand); 618 void Orn(const Register& rd, 619 const Register& rn, 620 const Operand& operand); 621 void Eor(const Register& rd, 622 const Register& rn, 623 const Operand& operand); 624 void Eon(const Register& rd, 625 const Register& rn, 626 const Operand& operand); 627 void Tst(const Register& rn, const Operand& operand); 628 void LogicalMacro(const Register& rd, 629 const Register& rn, 630 const Operand& operand, 631 LogicalOp op); 632 633 // Add and sub macros. 634 void Add(const Register& rd, 635 const Register& rn, 636 const Operand& operand, 637 FlagsUpdate S = LeaveFlags); 638 void Adds(const Register& rd, 639 const Register& rn, 640 const Operand& operand); 641 void Sub(const Register& rd, 642 const Register& rn, 643 const Operand& operand, 644 FlagsUpdate S = LeaveFlags); 645 void Subs(const Register& rd, 646 const Register& rn, 647 const Operand& operand); 648 void Cmn(const Register& rn, const Operand& operand); 649 void Cmp(const Register& rn, const Operand& operand); 650 void Neg(const Register& rd, 651 const Operand& operand); 652 void Negs(const Register& rd, 653 const Operand& operand); 654 655 void AddSubMacro(const Register& rd, 656 const Register& rn, 657 const Operand& operand, 658 FlagsUpdate S, 659 AddSubOp op); 660 661 // Add/sub with carry macros. 662 void Adc(const Register& rd, 663 const Register& rn, 664 const Operand& operand); 665 void Adcs(const Register& rd, 666 const Register& rn, 667 const Operand& operand); 668 void Sbc(const Register& rd, 669 const Register& rn, 670 const Operand& operand); 671 void Sbcs(const Register& rd, 672 const Register& rn, 673 const Operand& operand); 674 void Ngc(const Register& rd, 675 const Operand& operand); 676 void Ngcs(const Register& rd, 677 const Operand& operand); 678 void AddSubWithCarryMacro(const Register& rd, 679 const Register& rn, 680 const Operand& operand, 681 FlagsUpdate S, 682 AddSubWithCarryOp op); 683 684 // Move macros. 685 void Mov(const Register& rd, uint64_t imm); 686 void Mov(const Register& rd, 687 const Operand& operand, 688 DiscardMoveMode discard_mode = kDontDiscardForSameWReg); 689 void Mvn(const Register& rd, uint64_t imm) { 690 Mov(rd, (rd.size() == kXRegSize) ? ~imm : (~imm & kWRegMask)); 691 } 692 void Mvn(const Register& rd, const Operand& operand); 693 694 // Try to move an immediate into the destination register in a single 695 // instruction. Returns true for success, and updates the contents of dst. 696 // Returns false, otherwise. 697 bool TryOneInstrMoveImmediate(const Register& dst, int64_t imm); 698 699 // Move an immediate into register dst, and return an Operand object for 700 // use with a subsequent instruction that accepts a shift. The value moved 701 // into dst is not necessarily equal to imm; it may have had a shifting 702 // operation applied to it that will be subsequently undone by the shift 703 // applied in the Operand. 704 Operand MoveImmediateForShiftedOp(const Register& dst, int64_t imm); 705 706 // Synthesises the address represented by a MemOperand into a register. 707 void ComputeAddress(const Register& dst, const MemOperand& mem_op); 708 709 // Conditional macros. 710 void Ccmp(const Register& rn, 711 const Operand& operand, 712 StatusFlags nzcv, 713 Condition cond); 714 void Ccmn(const Register& rn, 715 const Operand& operand, 716 StatusFlags nzcv, 717 Condition cond); 718 void ConditionalCompareMacro(const Register& rn, 719 const Operand& operand, 720 StatusFlags nzcv, 721 Condition cond, 722 ConditionalCompareOp op); 723 void Csel(const Register& rd, 724 const Register& rn, 725 const Operand& operand, 726 Condition cond); 727 728 // Load/store macros. 729 #define DECLARE_FUNCTION(FN, REGTYPE, REG, OP) \ 730 void FN(const REGTYPE REG, const MemOperand& addr); 731 LS_MACRO_LIST(DECLARE_FUNCTION) 732 #undef DECLARE_FUNCTION 733 734 void LoadStoreMacro(const CPURegister& rt, 735 const MemOperand& addr, 736 LoadStoreOp op); 737 738 #define DECLARE_FUNCTION(FN, REGTYPE, REG, REG2, OP) \ 739 void FN(const REGTYPE REG, const REGTYPE REG2, const MemOperand& addr); 740 LSPAIR_MACRO_LIST(DECLARE_FUNCTION) 741 #undef DECLARE_FUNCTION 742 743 void LoadStorePairMacro(const CPURegister& rt, 744 const CPURegister& rt2, 745 const MemOperand& addr, 746 LoadStorePairOp op); 747 748 void Prfm(PrefetchOperation op, const MemOperand& addr); 749 750 // Push or pop up to 4 registers of the same width to or from the stack, 751 // using the current stack pointer as set by SetStackPointer. 752 // 753 // If an argument register is 'NoReg', all further arguments are also assumed 754 // to be 'NoReg', and are thus not pushed or popped. 755 // 756 // Arguments are ordered such that "Push(a, b);" is functionally equivalent 757 // to "Push(a); Push(b);". 758 // 759 // It is valid to push the same register more than once, and there is no 760 // restriction on the order in which registers are specified. 761 // 762 // It is not valid to pop into the same register more than once in one 763 // operation, not even into the zero register. 764 // 765 // If the current stack pointer (as set by SetStackPointer) is sp, then it 766 // must be aligned to 16 bytes on entry and the total size of the specified 767 // registers must also be a multiple of 16 bytes. 768 // 769 // Even if the current stack pointer is not the system stack pointer (sp), 770 // Push (and derived methods) will still modify the system stack pointer in 771 // order to comply with ABI rules about accessing memory below the system 772 // stack pointer. 773 // 774 // Other than the registers passed into Pop, the stack pointer and (possibly) 775 // the system stack pointer, these methods do not modify any other registers. 776 void Push(const CPURegister& src0, const CPURegister& src1 = NoReg, 777 const CPURegister& src2 = NoReg, const CPURegister& src3 = NoReg); 778 void Pop(const CPURegister& dst0, const CPURegister& dst1 = NoReg, 779 const CPURegister& dst2 = NoReg, const CPURegister& dst3 = NoReg); 780 781 // Alternative forms of Push and Pop, taking a RegList or CPURegList that 782 // specifies the registers that are to be pushed or popped. Higher-numbered 783 // registers are associated with higher memory addresses (as in the A32 push 784 // and pop instructions). 785 // 786 // (Push|Pop)SizeRegList allow you to specify the register size as a 787 // parameter. Only kXRegSize, kWRegSize, kDRegSize and kSRegSize are 788 // supported. 789 // 790 // Otherwise, (Push|Pop)(CPU|X|W|D|S)RegList is preferred. 791 void PushCPURegList(CPURegList registers); 792 void PopCPURegList(CPURegList registers); 793 794 void PushSizeRegList(RegList registers, unsigned reg_size, 795 CPURegister::RegisterType type = CPURegister::kRegister) { 796 PushCPURegList(CPURegList(type, reg_size, registers)); 797 } 798 void PopSizeRegList(RegList registers, unsigned reg_size, 799 CPURegister::RegisterType type = CPURegister::kRegister) { 800 PopCPURegList(CPURegList(type, reg_size, registers)); 801 } 802 void PushXRegList(RegList regs) { 803 PushSizeRegList(regs, kXRegSize); 804 } 805 void PopXRegList(RegList regs) { 806 PopSizeRegList(regs, kXRegSize); 807 } 808 void PushWRegList(RegList regs) { 809 PushSizeRegList(regs, kWRegSize); 810 } 811 void PopWRegList(RegList regs) { 812 PopSizeRegList(regs, kWRegSize); 813 } 814 void PushDRegList(RegList regs) { 815 PushSizeRegList(regs, kDRegSize, CPURegister::kVRegister); 816 } 817 void PopDRegList(RegList regs) { 818 PopSizeRegList(regs, kDRegSize, CPURegister::kVRegister); 819 } 820 void PushSRegList(RegList regs) { 821 PushSizeRegList(regs, kSRegSize, CPURegister::kVRegister); 822 } 823 void PopSRegList(RegList regs) { 824 PopSizeRegList(regs, kSRegSize, CPURegister::kVRegister); 825 } 826 827 // Push the specified register 'count' times. 828 void PushMultipleTimes(int count, Register src); 829 830 // Poke 'src' onto the stack. The offset is in bytes. 831 // 832 // If the current stack pointer (as set by SetStackPointer) is sp, then sp 833 // must be aligned to 16 bytes. 834 void Poke(const Register& src, const Operand& offset); 835 836 // Peek at a value on the stack, and put it in 'dst'. The offset is in bytes. 837 // 838 // If the current stack pointer (as set by SetStackPointer) is sp, then sp 839 // must be aligned to 16 bytes. 840 void Peek(const Register& dst, const Operand& offset); 841 842 // Alternative forms of Peek and Poke, taking a RegList or CPURegList that 843 // specifies the registers that are to be pushed or popped. Higher-numbered 844 // registers are associated with higher memory addresses. 845 // 846 // (Peek|Poke)SizeRegList allow you to specify the register size as a 847 // parameter. Only kXRegSize, kWRegSize, kDRegSize and kSRegSize are 848 // supported. 849 // 850 // Otherwise, (Peek|Poke)(CPU|X|W|D|S)RegList is preferred. 851 void PeekCPURegList(CPURegList registers, int64_t offset) { 852 LoadCPURegList(registers, MemOperand(StackPointer(), offset)); 853 } 854 void PokeCPURegList(CPURegList registers, int64_t offset) { 855 StoreCPURegList(registers, MemOperand(StackPointer(), offset)); 856 } 857 858 void PeekSizeRegList(RegList registers, int64_t offset, unsigned reg_size, 859 CPURegister::RegisterType type = CPURegister::kRegister) { 860 PeekCPURegList(CPURegList(type, reg_size, registers), offset); 861 } 862 void PokeSizeRegList(RegList registers, int64_t offset, unsigned reg_size, 863 CPURegister::RegisterType type = CPURegister::kRegister) { 864 PokeCPURegList(CPURegList(type, reg_size, registers), offset); 865 } 866 void PeekXRegList(RegList regs, int64_t offset) { 867 PeekSizeRegList(regs, offset, kXRegSize); 868 } 869 void PokeXRegList(RegList regs, int64_t offset) { 870 PokeSizeRegList(regs, offset, kXRegSize); 871 } 872 void PeekWRegList(RegList regs, int64_t offset) { 873 PeekSizeRegList(regs, offset, kWRegSize); 874 } 875 void PokeWRegList(RegList regs, int64_t offset) { 876 PokeSizeRegList(regs, offset, kWRegSize); 877 } 878 void PeekDRegList(RegList regs, int64_t offset) { 879 PeekSizeRegList(regs, offset, kDRegSize, CPURegister::kVRegister); 880 } 881 void PokeDRegList(RegList regs, int64_t offset) { 882 PokeSizeRegList(regs, offset, kDRegSize, CPURegister::kVRegister); 883 } 884 void PeekSRegList(RegList regs, int64_t offset) { 885 PeekSizeRegList(regs, offset, kSRegSize, CPURegister::kVRegister); 886 } 887 void PokeSRegList(RegList regs, int64_t offset) { 888 PokeSizeRegList(regs, offset, kSRegSize, CPURegister::kVRegister); 889 } 890 891 892 // Claim or drop stack space without actually accessing memory. 893 // 894 // If the current stack pointer (as set by SetStackPointer) is sp, then it 895 // must be aligned to 16 bytes and the size claimed or dropped must be a 896 // multiple of 16 bytes. 897 void Claim(const Operand& size); 898 void Drop(const Operand& size); 899 900 // Preserve the callee-saved registers (as defined by AAPCS64). 901 // 902 // Higher-numbered registers are pushed before lower-numbered registers, and 903 // thus get higher addresses. 904 // Floating-point registers are pushed before general-purpose registers, and 905 // thus get higher addresses. 906 // 907 // This method must not be called unless StackPointer() is sp, and it is 908 // aligned to 16 bytes. 909 void PushCalleeSavedRegisters(); 910 911 // Restore the callee-saved registers (as defined by AAPCS64). 912 // 913 // Higher-numbered registers are popped after lower-numbered registers, and 914 // thus come from higher addresses. 915 // Floating-point registers are popped after general-purpose registers, and 916 // thus come from higher addresses. 917 // 918 // This method must not be called unless StackPointer() is sp, and it is 919 // aligned to 16 bytes. 920 void PopCalleeSavedRegisters(); 921 922 void LoadCPURegList(CPURegList registers, const MemOperand& src); 923 void StoreCPURegList(CPURegList registers, const MemOperand& dst); 924 925 // Remaining instructions are simple pass-through calls to the assembler. 926 void Adr(const Register& rd, Label* label) { 927 VIXL_ASSERT(allow_macro_instructions_); 928 VIXL_ASSERT(!rd.IsZero()); 929 SingleEmissionCheckScope guard(this); 930 adr(rd, label); 931 } 932 void Adrp(const Register& rd, Label* label) { 933 VIXL_ASSERT(allow_macro_instructions_); 934 VIXL_ASSERT(!rd.IsZero()); 935 SingleEmissionCheckScope guard(this); 936 adrp(rd, label); 937 } 938 void Asr(const Register& rd, const Register& rn, unsigned shift) { 939 VIXL_ASSERT(allow_macro_instructions_); 940 VIXL_ASSERT(!rd.IsZero()); 941 VIXL_ASSERT(!rn.IsZero()); 942 SingleEmissionCheckScope guard(this); 943 asr(rd, rn, shift); 944 } 945 void Asr(const Register& rd, const Register& rn, const Register& rm) { 946 VIXL_ASSERT(allow_macro_instructions_); 947 VIXL_ASSERT(!rd.IsZero()); 948 VIXL_ASSERT(!rn.IsZero()); 949 VIXL_ASSERT(!rm.IsZero()); 950 SingleEmissionCheckScope guard(this); 951 asrv(rd, rn, rm); 952 } 953 954 // Branch type inversion relies on these relations. 955 VIXL_STATIC_ASSERT((reg_zero == (reg_not_zero ^ 1)) && 956 (reg_bit_clear == (reg_bit_set ^ 1)) && 957 (always == (never ^ 1))); 958 959 BranchType InvertBranchType(BranchType type) { 960 if (kBranchTypeFirstCondition <= type && type <= kBranchTypeLastCondition) { 961 return static_cast<BranchType>( 962 InvertCondition(static_cast<Condition>(type))); 963 } else { 964 return static_cast<BranchType>(type ^ 1); 965 } 966 } 967 968 void B(Label* label, BranchType type, Register reg = NoReg, int bit = -1); 969 970 void B(Label* label); 971 void B(Label* label, Condition cond); 972 void B(Condition cond, Label* label) { 973 B(label, cond); 974 } 975 void Bfm(const Register& rd, 976 const Register& rn, 977 unsigned immr, 978 unsigned imms) { 979 VIXL_ASSERT(allow_macro_instructions_); 980 VIXL_ASSERT(!rd.IsZero()); 981 VIXL_ASSERT(!rn.IsZero()); 982 SingleEmissionCheckScope guard(this); 983 bfm(rd, rn, immr, imms); 984 } 985 void Bfi(const Register& rd, 986 const Register& rn, 987 unsigned lsb, 988 unsigned width) { 989 VIXL_ASSERT(allow_macro_instructions_); 990 VIXL_ASSERT(!rd.IsZero()); 991 VIXL_ASSERT(!rn.IsZero()); 992 SingleEmissionCheckScope guard(this); 993 bfi(rd, rn, lsb, width); 994 } 995 void Bfxil(const Register& rd, 996 const Register& rn, 997 unsigned lsb, 998 unsigned width) { 999 VIXL_ASSERT(allow_macro_instructions_); 1000 VIXL_ASSERT(!rd.IsZero()); 1001 VIXL_ASSERT(!rn.IsZero()); 1002 SingleEmissionCheckScope guard(this); 1003 bfxil(rd, rn, lsb, width); 1004 } 1005 void Bind(Label* label); 1006 // Bind a label to a specified offset from the start of the buffer. 1007 void BindToOffset(Label* label, ptrdiff_t offset); 1008 void Bl(Label* label) { 1009 VIXL_ASSERT(allow_macro_instructions_); 1010 SingleEmissionCheckScope guard(this); 1011 bl(label); 1012 } 1013 void Blr(const Register& xn) { 1014 VIXL_ASSERT(allow_macro_instructions_); 1015 VIXL_ASSERT(!xn.IsZero()); 1016 SingleEmissionCheckScope guard(this); 1017 blr(xn); 1018 } 1019 void Br(const Register& xn) { 1020 VIXL_ASSERT(allow_macro_instructions_); 1021 VIXL_ASSERT(!xn.IsZero()); 1022 SingleEmissionCheckScope guard(this); 1023 br(xn); 1024 } 1025 void Brk(int code = 0) { 1026 VIXL_ASSERT(allow_macro_instructions_); 1027 SingleEmissionCheckScope guard(this); 1028 brk(code); 1029 } 1030 void Cbnz(const Register& rt, Label* label); 1031 void Cbz(const Register& rt, Label* label); 1032 void Cinc(const Register& rd, const Register& rn, Condition cond) { 1033 VIXL_ASSERT(allow_macro_instructions_); 1034 VIXL_ASSERT(!rd.IsZero()); 1035 VIXL_ASSERT(!rn.IsZero()); 1036 SingleEmissionCheckScope guard(this); 1037 cinc(rd, rn, cond); 1038 } 1039 void Cinv(const Register& rd, const Register& rn, Condition cond) { 1040 VIXL_ASSERT(allow_macro_instructions_); 1041 VIXL_ASSERT(!rd.IsZero()); 1042 VIXL_ASSERT(!rn.IsZero()); 1043 SingleEmissionCheckScope guard(this); 1044 cinv(rd, rn, cond); 1045 } 1046 void Clrex() { 1047 VIXL_ASSERT(allow_macro_instructions_); 1048 SingleEmissionCheckScope guard(this); 1049 clrex(); 1050 } 1051 void Cls(const Register& rd, const Register& rn) { 1052 VIXL_ASSERT(allow_macro_instructions_); 1053 VIXL_ASSERT(!rd.IsZero()); 1054 VIXL_ASSERT(!rn.IsZero()); 1055 SingleEmissionCheckScope guard(this); 1056 cls(rd, rn); 1057 } 1058 void Clz(const Register& rd, const Register& rn) { 1059 VIXL_ASSERT(allow_macro_instructions_); 1060 VIXL_ASSERT(!rd.IsZero()); 1061 VIXL_ASSERT(!rn.IsZero()); 1062 SingleEmissionCheckScope guard(this); 1063 clz(rd, rn); 1064 } 1065 void Cneg(const Register& rd, const Register& rn, Condition cond) { 1066 VIXL_ASSERT(allow_macro_instructions_); 1067 VIXL_ASSERT(!rd.IsZero()); 1068 VIXL_ASSERT(!rn.IsZero()); 1069 SingleEmissionCheckScope guard(this); 1070 cneg(rd, rn, cond); 1071 } 1072 void Cset(const Register& rd, Condition cond) { 1073 VIXL_ASSERT(allow_macro_instructions_); 1074 VIXL_ASSERT(!rd.IsZero()); 1075 SingleEmissionCheckScope guard(this); 1076 cset(rd, cond); 1077 } 1078 void Csetm(const Register& rd, Condition cond) { 1079 VIXL_ASSERT(allow_macro_instructions_); 1080 VIXL_ASSERT(!rd.IsZero()); 1081 SingleEmissionCheckScope guard(this); 1082 csetm(rd, cond); 1083 } 1084 void Csinc(const Register& rd, 1085 const Register& rn, 1086 const Register& rm, 1087 Condition cond) { 1088 VIXL_ASSERT(allow_macro_instructions_); 1089 VIXL_ASSERT(!rd.IsZero()); 1090 VIXL_ASSERT(!rn.IsZero()); 1091 VIXL_ASSERT(!rm.IsZero()); 1092 VIXL_ASSERT((cond != al) && (cond != nv)); 1093 SingleEmissionCheckScope guard(this); 1094 csinc(rd, rn, rm, cond); 1095 } 1096 void Csinv(const Register& rd, 1097 const Register& rn, 1098 const Register& rm, 1099 Condition cond) { 1100 VIXL_ASSERT(allow_macro_instructions_); 1101 VIXL_ASSERT(!rd.IsZero()); 1102 VIXL_ASSERT(!rn.IsZero()); 1103 VIXL_ASSERT(!rm.IsZero()); 1104 VIXL_ASSERT((cond != al) && (cond != nv)); 1105 SingleEmissionCheckScope guard(this); 1106 csinv(rd, rn, rm, cond); 1107 } 1108 void Csneg(const Register& rd, 1109 const Register& rn, 1110 const Register& rm, 1111 Condition cond) { 1112 VIXL_ASSERT(allow_macro_instructions_); 1113 VIXL_ASSERT(!rd.IsZero()); 1114 VIXL_ASSERT(!rn.IsZero()); 1115 VIXL_ASSERT(!rm.IsZero()); 1116 VIXL_ASSERT((cond != al) && (cond != nv)); 1117 SingleEmissionCheckScope guard(this); 1118 csneg(rd, rn, rm, cond); 1119 } 1120 void Dmb(BarrierDomain domain, BarrierType type) { 1121 VIXL_ASSERT(allow_macro_instructions_); 1122 SingleEmissionCheckScope guard(this); 1123 dmb(domain, type); 1124 } 1125 void Dsb(BarrierDomain domain, BarrierType type) { 1126 VIXL_ASSERT(allow_macro_instructions_); 1127 SingleEmissionCheckScope guard(this); 1128 dsb(domain, type); 1129 } 1130 void Extr(const Register& rd, 1131 const Register& rn, 1132 const Register& rm, 1133 unsigned lsb) { 1134 VIXL_ASSERT(allow_macro_instructions_); 1135 VIXL_ASSERT(!rd.IsZero()); 1136 VIXL_ASSERT(!rn.IsZero()); 1137 VIXL_ASSERT(!rm.IsZero()); 1138 SingleEmissionCheckScope guard(this); 1139 extr(rd, rn, rm, lsb); 1140 } 1141 void Fadd(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1142 VIXL_ASSERT(allow_macro_instructions_); 1143 SingleEmissionCheckScope guard(this); 1144 fadd(vd, vn, vm); 1145 } 1146 void Fccmp(const VRegister& vn, 1147 const VRegister& vm, 1148 StatusFlags nzcv, 1149 Condition cond, 1150 FPTrapFlags trap = DisableTrap) { 1151 VIXL_ASSERT(allow_macro_instructions_); 1152 VIXL_ASSERT((cond != al) && (cond != nv)); 1153 SingleEmissionCheckScope guard(this); 1154 FPCCompareMacro(vn, vm, nzcv, cond, trap); 1155 } 1156 void Fccmpe(const VRegister& vn, 1157 const VRegister& vm, 1158 StatusFlags nzcv, 1159 Condition cond) { 1160 Fccmp(vn, vm, nzcv, cond, EnableTrap); 1161 } 1162 void Fcmp(const VRegister& vn, const VRegister& vm, 1163 FPTrapFlags trap = DisableTrap) { 1164 VIXL_ASSERT(allow_macro_instructions_); 1165 SingleEmissionCheckScope guard(this); 1166 FPCompareMacro(vn, vm, trap); 1167 } 1168 void Fcmp(const VRegister& vn, double value, 1169 FPTrapFlags trap = DisableTrap); 1170 void Fcmpe(const VRegister& vn, double value); 1171 void Fcmpe(const VRegister& vn, const VRegister& vm) { 1172 Fcmp(vn, vm, EnableTrap); 1173 } 1174 void Fcsel(const VRegister& vd, 1175 const VRegister& vn, 1176 const VRegister& vm, 1177 Condition cond) { 1178 VIXL_ASSERT(allow_macro_instructions_); 1179 VIXL_ASSERT((cond != al) && (cond != nv)); 1180 SingleEmissionCheckScope guard(this); 1181 fcsel(vd, vn, vm, cond); 1182 } 1183 void Fcvt(const VRegister& vd, const VRegister& vn) { 1184 VIXL_ASSERT(allow_macro_instructions_); 1185 SingleEmissionCheckScope guard(this); 1186 fcvt(vd, vn); 1187 } 1188 void Fcvtl(const VRegister& vd, const VRegister& vn) { 1189 VIXL_ASSERT(allow_macro_instructions_); 1190 SingleEmissionCheckScope guard(this); 1191 fcvtl(vd, vn); 1192 } 1193 void Fcvtl2(const VRegister& vd, const VRegister& vn) { 1194 VIXL_ASSERT(allow_macro_instructions_); 1195 SingleEmissionCheckScope guard(this); 1196 fcvtl2(vd, vn); 1197 } 1198 void Fcvtn(const VRegister& vd, const VRegister& vn) { 1199 VIXL_ASSERT(allow_macro_instructions_); 1200 SingleEmissionCheckScope guard(this); 1201 fcvtn(vd, vn); 1202 } 1203 void Fcvtn2(const VRegister& vd, const VRegister& vn) { 1204 VIXL_ASSERT(allow_macro_instructions_); 1205 SingleEmissionCheckScope guard(this); 1206 fcvtn2(vd, vn); 1207 } 1208 void Fcvtxn(const VRegister& vd, const VRegister& vn) { 1209 VIXL_ASSERT(allow_macro_instructions_); 1210 SingleEmissionCheckScope guard(this); 1211 fcvtxn(vd, vn); 1212 } 1213 void Fcvtxn2(const VRegister& vd, const VRegister& vn) { 1214 VIXL_ASSERT(allow_macro_instructions_); 1215 SingleEmissionCheckScope guard(this); 1216 fcvtxn2(vd, vn); 1217 } 1218 void Fcvtas(const Register& rd, const VRegister& vn) { 1219 VIXL_ASSERT(allow_macro_instructions_); 1220 VIXL_ASSERT(!rd.IsZero()); 1221 SingleEmissionCheckScope guard(this); 1222 fcvtas(rd, vn); 1223 } 1224 void Fcvtau(const Register& rd, const VRegister& vn) { 1225 VIXL_ASSERT(allow_macro_instructions_); 1226 VIXL_ASSERT(!rd.IsZero()); 1227 SingleEmissionCheckScope guard(this); 1228 fcvtau(rd, vn); 1229 } 1230 void Fcvtms(const Register& rd, const VRegister& vn) { 1231 VIXL_ASSERT(allow_macro_instructions_); 1232 VIXL_ASSERT(!rd.IsZero()); 1233 SingleEmissionCheckScope guard(this); 1234 fcvtms(rd, vn); 1235 } 1236 void Fcvtmu(const Register& rd, const VRegister& vn) { 1237 VIXL_ASSERT(allow_macro_instructions_); 1238 VIXL_ASSERT(!rd.IsZero()); 1239 SingleEmissionCheckScope guard(this); 1240 fcvtmu(rd, vn); 1241 } 1242 void Fcvtns(const Register& rd, const VRegister& vn) { 1243 VIXL_ASSERT(allow_macro_instructions_); 1244 VIXL_ASSERT(!rd.IsZero()); 1245 SingleEmissionCheckScope guard(this); 1246 fcvtns(rd, vn); 1247 } 1248 void Fcvtnu(const Register& rd, const VRegister& vn) { 1249 VIXL_ASSERT(allow_macro_instructions_); 1250 VIXL_ASSERT(!rd.IsZero()); 1251 SingleEmissionCheckScope guard(this); 1252 fcvtnu(rd, vn); 1253 } 1254 void Fcvtps(const Register& rd, const VRegister& vn) { 1255 VIXL_ASSERT(allow_macro_instructions_); 1256 VIXL_ASSERT(!rd.IsZero()); 1257 SingleEmissionCheckScope guard(this); 1258 fcvtps(rd, vn); 1259 } 1260 void Fcvtpu(const Register& rd, const VRegister& vn) { 1261 VIXL_ASSERT(allow_macro_instructions_); 1262 VIXL_ASSERT(!rd.IsZero()); 1263 SingleEmissionCheckScope guard(this); 1264 fcvtpu(rd, vn); 1265 } 1266 void Fcvtzs(const Register& rd, const VRegister& vn, int fbits = 0) { 1267 VIXL_ASSERT(allow_macro_instructions_); 1268 VIXL_ASSERT(!rd.IsZero()); 1269 SingleEmissionCheckScope guard(this); 1270 fcvtzs(rd, vn, fbits); 1271 } 1272 void Fcvtzu(const Register& rd, const VRegister& vn, int fbits = 0) { 1273 VIXL_ASSERT(allow_macro_instructions_); 1274 VIXL_ASSERT(!rd.IsZero()); 1275 SingleEmissionCheckScope guard(this); 1276 fcvtzu(rd, vn, fbits); 1277 } 1278 void Fdiv(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1279 VIXL_ASSERT(allow_macro_instructions_); 1280 SingleEmissionCheckScope guard(this); 1281 fdiv(vd, vn, vm); 1282 } 1283 void Fmax(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1284 VIXL_ASSERT(allow_macro_instructions_); 1285 SingleEmissionCheckScope guard(this); 1286 fmax(vd, vn, vm); 1287 } 1288 void Fmaxnm(const VRegister& vd, 1289 const VRegister& vn, 1290 const VRegister& vm) { 1291 VIXL_ASSERT(allow_macro_instructions_); 1292 SingleEmissionCheckScope guard(this); 1293 fmaxnm(vd, vn, vm); 1294 } 1295 void Fmin(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1296 VIXL_ASSERT(allow_macro_instructions_); 1297 SingleEmissionCheckScope guard(this); 1298 fmin(vd, vn, vm); 1299 } 1300 void Fminnm(const VRegister& vd, 1301 const VRegister& vn, 1302 const VRegister& vm) { 1303 VIXL_ASSERT(allow_macro_instructions_); 1304 SingleEmissionCheckScope guard(this); 1305 fminnm(vd, vn, vm); 1306 } 1307 void Fmov(VRegister vd, VRegister vn) { 1308 VIXL_ASSERT(allow_macro_instructions_); 1309 SingleEmissionCheckScope guard(this); 1310 // Only emit an instruction if vd and vn are different, and they are both D 1311 // registers. fmov(s0, s0) is not a no-op because it clears the top word of 1312 // d0. Technically, fmov(d0, d0) is not a no-op either because it clears 1313 // the top of q0, but VRegister does not currently support Q registers. 1314 if (!vd.Is(vn) || !vd.Is64Bits()) { 1315 fmov(vd, vn); 1316 } 1317 } 1318 void Fmov(VRegister vd, Register rn) { 1319 VIXL_ASSERT(allow_macro_instructions_); 1320 VIXL_ASSERT(!rn.IsZero()); 1321 SingleEmissionCheckScope guard(this); 1322 fmov(vd, rn); 1323 } 1324 void Fmov(const VRegister& vd, int index, const Register& rn) { 1325 VIXL_ASSERT(allow_macro_instructions_); 1326 SingleEmissionCheckScope guard(this); 1327 fmov(vd, index, rn); 1328 } 1329 void Fmov(const Register& rd, const VRegister& vn, int index) { 1330 VIXL_ASSERT(allow_macro_instructions_); 1331 SingleEmissionCheckScope guard(this); 1332 fmov(rd, vn, index); 1333 } 1334 1335 // Provide explicit double and float interfaces for FP immediate moves, rather 1336 // than relying on implicit C++ casts. This allows signalling NaNs to be 1337 // preserved when the immediate matches the format of vd. Most systems convert 1338 // signalling NaNs to quiet NaNs when converting between float and double. 1339 void Fmov(VRegister vd, double imm); 1340 void Fmov(VRegister vd, float imm); 1341 // Provide a template to allow other types to be converted automatically. 1342 template<typename T> 1343 void Fmov(VRegister vd, T imm) { 1344 VIXL_ASSERT(allow_macro_instructions_); 1345 Fmov(vd, static_cast<double>(imm)); 1346 } 1347 void Fmov(Register rd, VRegister vn) { 1348 VIXL_ASSERT(allow_macro_instructions_); 1349 VIXL_ASSERT(!rd.IsZero()); 1350 SingleEmissionCheckScope guard(this); 1351 fmov(rd, vn); 1352 } 1353 void Fmul(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1354 VIXL_ASSERT(allow_macro_instructions_); 1355 SingleEmissionCheckScope guard(this); 1356 fmul(vd, vn, vm); 1357 } 1358 void Fnmul(const VRegister& vd, const VRegister& vn, 1359 const VRegister& vm) { 1360 VIXL_ASSERT(allow_macro_instructions_); 1361 SingleEmissionCheckScope guard(this); 1362 fnmul(vd, vn, vm); 1363 } 1364 void Fmadd(const VRegister& vd, 1365 const VRegister& vn, 1366 const VRegister& vm, 1367 const VRegister& va) { 1368 VIXL_ASSERT(allow_macro_instructions_); 1369 SingleEmissionCheckScope guard(this); 1370 fmadd(vd, vn, vm, va); 1371 } 1372 void Fmsub(const VRegister& vd, 1373 const VRegister& vn, 1374 const VRegister& vm, 1375 const VRegister& va) { 1376 VIXL_ASSERT(allow_macro_instructions_); 1377 SingleEmissionCheckScope guard(this); 1378 fmsub(vd, vn, vm, va); 1379 } 1380 void Fnmadd(const VRegister& vd, 1381 const VRegister& vn, 1382 const VRegister& vm, 1383 const VRegister& va) { 1384 VIXL_ASSERT(allow_macro_instructions_); 1385 SingleEmissionCheckScope guard(this); 1386 fnmadd(vd, vn, vm, va); 1387 } 1388 void Fnmsub(const VRegister& vd, 1389 const VRegister& vn, 1390 const VRegister& vm, 1391 const VRegister& va) { 1392 VIXL_ASSERT(allow_macro_instructions_); 1393 SingleEmissionCheckScope guard(this); 1394 fnmsub(vd, vn, vm, va); 1395 } 1396 void Fsub(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1397 VIXL_ASSERT(allow_macro_instructions_); 1398 SingleEmissionCheckScope guard(this); 1399 fsub(vd, vn, vm); 1400 } 1401 void Hint(SystemHint code) { 1402 VIXL_ASSERT(allow_macro_instructions_); 1403 SingleEmissionCheckScope guard(this); 1404 hint(code); 1405 } 1406 void Hlt(int code) { 1407 VIXL_ASSERT(allow_macro_instructions_); 1408 SingleEmissionCheckScope guard(this); 1409 hlt(code); 1410 } 1411 void Isb() { 1412 VIXL_ASSERT(allow_macro_instructions_); 1413 SingleEmissionCheckScope guard(this); 1414 isb(); 1415 } 1416 void Ldar(const Register& rt, const MemOperand& src) { 1417 VIXL_ASSERT(allow_macro_instructions_); 1418 SingleEmissionCheckScope guard(this); 1419 ldar(rt, src); 1420 } 1421 void Ldarb(const Register& rt, const MemOperand& src) { 1422 VIXL_ASSERT(allow_macro_instructions_); 1423 SingleEmissionCheckScope guard(this); 1424 ldarb(rt, src); 1425 } 1426 void Ldarh(const Register& rt, const MemOperand& src) { 1427 VIXL_ASSERT(allow_macro_instructions_); 1428 SingleEmissionCheckScope guard(this); 1429 ldarh(rt, src); 1430 } 1431 void Ldaxp(const Register& rt, const Register& rt2, const MemOperand& src) { 1432 VIXL_ASSERT(allow_macro_instructions_); 1433 VIXL_ASSERT(!rt.Aliases(rt2)); 1434 SingleEmissionCheckScope guard(this); 1435 ldaxp(rt, rt2, src); 1436 } 1437 void Ldaxr(const Register& rt, const MemOperand& src) { 1438 VIXL_ASSERT(allow_macro_instructions_); 1439 SingleEmissionCheckScope guard(this); 1440 ldaxr(rt, src); 1441 } 1442 void Ldaxrb(const Register& rt, const MemOperand& src) { 1443 VIXL_ASSERT(allow_macro_instructions_); 1444 SingleEmissionCheckScope guard(this); 1445 ldaxrb(rt, src); 1446 } 1447 void Ldaxrh(const Register& rt, const MemOperand& src) { 1448 VIXL_ASSERT(allow_macro_instructions_); 1449 SingleEmissionCheckScope guard(this); 1450 ldaxrh(rt, src); 1451 } 1452 void Ldnp(const CPURegister& rt, 1453 const CPURegister& rt2, 1454 const MemOperand& src) { 1455 VIXL_ASSERT(allow_macro_instructions_); 1456 SingleEmissionCheckScope guard(this); 1457 ldnp(rt, rt2, src); 1458 } 1459 // Provide both double and float interfaces for FP immediate loads, rather 1460 // than relying on implicit C++ casts. This allows signalling NaNs to be 1461 // preserved when the immediate matches the format of fd. Most systems convert 1462 // signalling NaNs to quiet NaNs when converting between float and double. 1463 void Ldr(const VRegister& vt, double imm) { 1464 VIXL_ASSERT(allow_macro_instructions_); 1465 SingleEmissionCheckScope guard(this); 1466 RawLiteral* literal; 1467 if (vt.IsD()) { 1468 literal = literal_pool_.Add(imm); 1469 } else { 1470 literal = literal_pool_.Add(static_cast<float>(imm)); 1471 } 1472 ldr(vt, literal); 1473 } 1474 void Ldr(const VRegister& vt, float imm) { 1475 VIXL_ASSERT(allow_macro_instructions_); 1476 SingleEmissionCheckScope guard(this); 1477 RawLiteral* literal; 1478 if (vt.IsS()) { 1479 literal = literal_pool_.Add(imm); 1480 } else { 1481 literal = literal_pool_.Add(static_cast<double>(imm)); 1482 } 1483 ldr(vt, literal); 1484 } 1485 void Ldr(const VRegister& vt, uint64_t high64, uint64_t low64) { 1486 VIXL_ASSERT(allow_macro_instructions_); 1487 VIXL_ASSERT(vt.IsQ()); 1488 SingleEmissionCheckScope guard(this); 1489 ldr(vt, literal_pool_.Add(high64, low64)); 1490 } 1491 void Ldr(const Register& rt, uint64_t imm) { 1492 VIXL_ASSERT(allow_macro_instructions_); 1493 VIXL_ASSERT(!rt.IsZero()); 1494 SingleEmissionCheckScope guard(this); 1495 RawLiteral* literal; 1496 if (rt.Is64Bits()) { 1497 literal = literal_pool_.Add(imm); 1498 } else { 1499 VIXL_ASSERT(rt.Is32Bits()); 1500 VIXL_ASSERT(is_uint32(imm) || is_int32(imm)); 1501 literal = literal_pool_.Add(static_cast<uint32_t>(imm)); 1502 } 1503 ldr(rt, literal); 1504 } 1505 void Ldrsw(const Register& rt, uint32_t imm) { 1506 VIXL_ASSERT(allow_macro_instructions_); 1507 VIXL_ASSERT(!rt.IsZero()); 1508 SingleEmissionCheckScope guard(this); 1509 RawLiteral* literal = literal_pool_.Add(imm); 1510 ldrsw(rt, literal); 1511 } 1512 void Ldxp(const Register& rt, const Register& rt2, const MemOperand& src) { 1513 VIXL_ASSERT(allow_macro_instructions_); 1514 VIXL_ASSERT(!rt.Aliases(rt2)); 1515 SingleEmissionCheckScope guard(this); 1516 ldxp(rt, rt2, src); 1517 } 1518 void Ldxr(const Register& rt, const MemOperand& src) { 1519 VIXL_ASSERT(allow_macro_instructions_); 1520 SingleEmissionCheckScope guard(this); 1521 ldxr(rt, src); 1522 } 1523 void Ldxrb(const Register& rt, const MemOperand& src) { 1524 VIXL_ASSERT(allow_macro_instructions_); 1525 SingleEmissionCheckScope guard(this); 1526 ldxrb(rt, src); 1527 } 1528 void Ldxrh(const Register& rt, const MemOperand& src) { 1529 VIXL_ASSERT(allow_macro_instructions_); 1530 SingleEmissionCheckScope guard(this); 1531 ldxrh(rt, src); 1532 } 1533 void Lsl(const Register& rd, const Register& rn, unsigned shift) { 1534 VIXL_ASSERT(allow_macro_instructions_); 1535 VIXL_ASSERT(!rd.IsZero()); 1536 VIXL_ASSERT(!rn.IsZero()); 1537 SingleEmissionCheckScope guard(this); 1538 lsl(rd, rn, shift); 1539 } 1540 void Lsl(const Register& rd, const Register& rn, const Register& rm) { 1541 VIXL_ASSERT(allow_macro_instructions_); 1542 VIXL_ASSERT(!rd.IsZero()); 1543 VIXL_ASSERT(!rn.IsZero()); 1544 VIXL_ASSERT(!rm.IsZero()); 1545 SingleEmissionCheckScope guard(this); 1546 lslv(rd, rn, rm); 1547 } 1548 void Lsr(const Register& rd, const Register& rn, unsigned shift) { 1549 VIXL_ASSERT(allow_macro_instructions_); 1550 VIXL_ASSERT(!rd.IsZero()); 1551 VIXL_ASSERT(!rn.IsZero()); 1552 SingleEmissionCheckScope guard(this); 1553 lsr(rd, rn, shift); 1554 } 1555 void Lsr(const Register& rd, const Register& rn, const Register& rm) { 1556 VIXL_ASSERT(allow_macro_instructions_); 1557 VIXL_ASSERT(!rd.IsZero()); 1558 VIXL_ASSERT(!rn.IsZero()); 1559 VIXL_ASSERT(!rm.IsZero()); 1560 SingleEmissionCheckScope guard(this); 1561 lsrv(rd, rn, rm); 1562 } 1563 void Madd(const Register& rd, 1564 const Register& rn, 1565 const Register& rm, 1566 const Register& ra) { 1567 VIXL_ASSERT(allow_macro_instructions_); 1568 VIXL_ASSERT(!rd.IsZero()); 1569 VIXL_ASSERT(!rn.IsZero()); 1570 VIXL_ASSERT(!rm.IsZero()); 1571 VIXL_ASSERT(!ra.IsZero()); 1572 SingleEmissionCheckScope guard(this); 1573 madd(rd, rn, rm, ra); 1574 } 1575 void Mneg(const Register& rd, const Register& rn, const Register& rm) { 1576 VIXL_ASSERT(allow_macro_instructions_); 1577 VIXL_ASSERT(!rd.IsZero()); 1578 VIXL_ASSERT(!rn.IsZero()); 1579 VIXL_ASSERT(!rm.IsZero()); 1580 SingleEmissionCheckScope guard(this); 1581 mneg(rd, rn, rm); 1582 } 1583 void Mov(const Register& rd, const Register& rn) { 1584 VIXL_ASSERT(allow_macro_instructions_); 1585 SingleEmissionCheckScope guard(this); 1586 mov(rd, rn); 1587 } 1588 void Movk(const Register& rd, uint64_t imm, int shift = -1) { 1589 VIXL_ASSERT(allow_macro_instructions_); 1590 VIXL_ASSERT(!rd.IsZero()); 1591 SingleEmissionCheckScope guard(this); 1592 movk(rd, imm, shift); 1593 } 1594 void Mrs(const Register& rt, SystemRegister sysreg) { 1595 VIXL_ASSERT(allow_macro_instructions_); 1596 VIXL_ASSERT(!rt.IsZero()); 1597 SingleEmissionCheckScope guard(this); 1598 mrs(rt, sysreg); 1599 } 1600 void Msr(SystemRegister sysreg, const Register& rt) { 1601 VIXL_ASSERT(allow_macro_instructions_); 1602 VIXL_ASSERT(!rt.IsZero()); 1603 SingleEmissionCheckScope guard(this); 1604 msr(sysreg, rt); 1605 } 1606 void Sys(int op1, int crn, int crm, int op2, const Register& rt = xzr) { 1607 VIXL_ASSERT(allow_macro_instructions_); 1608 SingleEmissionCheckScope guard(this); 1609 sys(op1, crn, crm, op2, rt); 1610 } 1611 void Dc(DataCacheOp op, const Register& rt) { 1612 VIXL_ASSERT(allow_macro_instructions_); 1613 SingleEmissionCheckScope guard(this); 1614 dc(op, rt); 1615 } 1616 void Ic(InstructionCacheOp op, const Register& rt) { 1617 VIXL_ASSERT(allow_macro_instructions_); 1618 SingleEmissionCheckScope guard(this); 1619 ic(op, rt); 1620 } 1621 void Msub(const Register& rd, 1622 const Register& rn, 1623 const Register& rm, 1624 const Register& ra) { 1625 VIXL_ASSERT(allow_macro_instructions_); 1626 VIXL_ASSERT(!rd.IsZero()); 1627 VIXL_ASSERT(!rn.IsZero()); 1628 VIXL_ASSERT(!rm.IsZero()); 1629 VIXL_ASSERT(!ra.IsZero()); 1630 SingleEmissionCheckScope guard(this); 1631 msub(rd, rn, rm, ra); 1632 } 1633 void Mul(const Register& rd, const Register& rn, const Register& rm) { 1634 VIXL_ASSERT(allow_macro_instructions_); 1635 VIXL_ASSERT(!rd.IsZero()); 1636 VIXL_ASSERT(!rn.IsZero()); 1637 VIXL_ASSERT(!rm.IsZero()); 1638 SingleEmissionCheckScope guard(this); 1639 mul(rd, rn, rm); 1640 } 1641 void Nop() { 1642 VIXL_ASSERT(allow_macro_instructions_); 1643 SingleEmissionCheckScope guard(this); 1644 nop(); 1645 } 1646 void Rbit(const Register& rd, const Register& rn) { 1647 VIXL_ASSERT(allow_macro_instructions_); 1648 VIXL_ASSERT(!rd.IsZero()); 1649 VIXL_ASSERT(!rn.IsZero()); 1650 SingleEmissionCheckScope guard(this); 1651 rbit(rd, rn); 1652 } 1653 void Ret(const Register& xn = lr) { 1654 VIXL_ASSERT(allow_macro_instructions_); 1655 VIXL_ASSERT(!xn.IsZero()); 1656 SingleEmissionCheckScope guard(this); 1657 ret(xn); 1658 } 1659 void Rev(const Register& rd, const Register& rn) { 1660 VIXL_ASSERT(allow_macro_instructions_); 1661 VIXL_ASSERT(!rd.IsZero()); 1662 VIXL_ASSERT(!rn.IsZero()); 1663 SingleEmissionCheckScope guard(this); 1664 rev(rd, rn); 1665 } 1666 void Rev16(const Register& rd, const Register& rn) { 1667 VIXL_ASSERT(allow_macro_instructions_); 1668 VIXL_ASSERT(!rd.IsZero()); 1669 VIXL_ASSERT(!rn.IsZero()); 1670 SingleEmissionCheckScope guard(this); 1671 rev16(rd, rn); 1672 } 1673 void Rev32(const Register& rd, const Register& rn) { 1674 VIXL_ASSERT(allow_macro_instructions_); 1675 VIXL_ASSERT(!rd.IsZero()); 1676 VIXL_ASSERT(!rn.IsZero()); 1677 SingleEmissionCheckScope guard(this); 1678 rev32(rd, rn); 1679 } 1680 void Ror(const Register& rd, const Register& rs, unsigned shift) { 1681 VIXL_ASSERT(allow_macro_instructions_); 1682 VIXL_ASSERT(!rd.IsZero()); 1683 VIXL_ASSERT(!rs.IsZero()); 1684 SingleEmissionCheckScope guard(this); 1685 ror(rd, rs, shift); 1686 } 1687 void Ror(const Register& rd, const Register& rn, const Register& rm) { 1688 VIXL_ASSERT(allow_macro_instructions_); 1689 VIXL_ASSERT(!rd.IsZero()); 1690 VIXL_ASSERT(!rn.IsZero()); 1691 VIXL_ASSERT(!rm.IsZero()); 1692 SingleEmissionCheckScope guard(this); 1693 rorv(rd, rn, rm); 1694 } 1695 void Sbfiz(const Register& rd, 1696 const Register& rn, 1697 unsigned lsb, 1698 unsigned width) { 1699 VIXL_ASSERT(allow_macro_instructions_); 1700 VIXL_ASSERT(!rd.IsZero()); 1701 VIXL_ASSERT(!rn.IsZero()); 1702 SingleEmissionCheckScope guard(this); 1703 sbfiz(rd, rn, lsb, width); 1704 } 1705 void Sbfm(const Register& rd, 1706 const Register& rn, 1707 unsigned immr, 1708 unsigned imms) { 1709 VIXL_ASSERT(allow_macro_instructions_); 1710 VIXL_ASSERT(!rd.IsZero()); 1711 VIXL_ASSERT(!rn.IsZero()); 1712 SingleEmissionCheckScope guard(this); 1713 sbfm(rd, rn, immr, imms); 1714 } 1715 void Sbfx(const Register& rd, 1716 const Register& rn, 1717 unsigned lsb, 1718 unsigned width) { 1719 VIXL_ASSERT(allow_macro_instructions_); 1720 VIXL_ASSERT(!rd.IsZero()); 1721 VIXL_ASSERT(!rn.IsZero()); 1722 SingleEmissionCheckScope guard(this); 1723 sbfx(rd, rn, lsb, width); 1724 } 1725 void Scvtf(const VRegister& vd, const Register& rn, int fbits = 0) { 1726 VIXL_ASSERT(allow_macro_instructions_); 1727 VIXL_ASSERT(!rn.IsZero()); 1728 SingleEmissionCheckScope guard(this); 1729 scvtf(vd, rn, fbits); 1730 } 1731 void Sdiv(const Register& rd, const Register& rn, const Register& rm) { 1732 VIXL_ASSERT(allow_macro_instructions_); 1733 VIXL_ASSERT(!rd.IsZero()); 1734 VIXL_ASSERT(!rn.IsZero()); 1735 VIXL_ASSERT(!rm.IsZero()); 1736 SingleEmissionCheckScope guard(this); 1737 sdiv(rd, rn, rm); 1738 } 1739 void Smaddl(const Register& rd, 1740 const Register& rn, 1741 const Register& rm, 1742 const Register& ra) { 1743 VIXL_ASSERT(allow_macro_instructions_); 1744 VIXL_ASSERT(!rd.IsZero()); 1745 VIXL_ASSERT(!rn.IsZero()); 1746 VIXL_ASSERT(!rm.IsZero()); 1747 VIXL_ASSERT(!ra.IsZero()); 1748 SingleEmissionCheckScope guard(this); 1749 smaddl(rd, rn, rm, ra); 1750 } 1751 void Smsubl(const Register& rd, 1752 const Register& rn, 1753 const Register& rm, 1754 const Register& ra) { 1755 VIXL_ASSERT(allow_macro_instructions_); 1756 VIXL_ASSERT(!rd.IsZero()); 1757 VIXL_ASSERT(!rn.IsZero()); 1758 VIXL_ASSERT(!rm.IsZero()); 1759 VIXL_ASSERT(!ra.IsZero()); 1760 SingleEmissionCheckScope guard(this); 1761 smsubl(rd, rn, rm, ra); 1762 } 1763 void Smull(const Register& rd, const Register& rn, const Register& rm) { 1764 VIXL_ASSERT(allow_macro_instructions_); 1765 VIXL_ASSERT(!rd.IsZero()); 1766 VIXL_ASSERT(!rn.IsZero()); 1767 VIXL_ASSERT(!rm.IsZero()); 1768 SingleEmissionCheckScope guard(this); 1769 smull(rd, rn, rm); 1770 } 1771 void Smulh(const Register& xd, const Register& xn, const Register& xm) { 1772 VIXL_ASSERT(allow_macro_instructions_); 1773 VIXL_ASSERT(!xd.IsZero()); 1774 VIXL_ASSERT(!xn.IsZero()); 1775 VIXL_ASSERT(!xm.IsZero()); 1776 SingleEmissionCheckScope guard(this); 1777 smulh(xd, xn, xm); 1778 } 1779 void Stlr(const Register& rt, const MemOperand& dst) { 1780 VIXL_ASSERT(allow_macro_instructions_); 1781 SingleEmissionCheckScope guard(this); 1782 stlr(rt, dst); 1783 } 1784 void Stlrb(const Register& rt, const MemOperand& dst) { 1785 VIXL_ASSERT(allow_macro_instructions_); 1786 SingleEmissionCheckScope guard(this); 1787 stlrb(rt, dst); 1788 } 1789 void Stlrh(const Register& rt, const MemOperand& dst) { 1790 VIXL_ASSERT(allow_macro_instructions_); 1791 SingleEmissionCheckScope guard(this); 1792 stlrh(rt, dst); 1793 } 1794 void Stlxp(const Register& rs, 1795 const Register& rt, 1796 const Register& rt2, 1797 const MemOperand& dst) { 1798 VIXL_ASSERT(allow_macro_instructions_); 1799 VIXL_ASSERT(!rs.Aliases(dst.base())); 1800 VIXL_ASSERT(!rs.Aliases(rt)); 1801 VIXL_ASSERT(!rs.Aliases(rt2)); 1802 SingleEmissionCheckScope guard(this); 1803 stlxp(rs, rt, rt2, dst); 1804 } 1805 void Stlxr(const Register& rs, const Register& rt, const MemOperand& dst) { 1806 VIXL_ASSERT(allow_macro_instructions_); 1807 VIXL_ASSERT(!rs.Aliases(dst.base())); 1808 VIXL_ASSERT(!rs.Aliases(rt)); 1809 SingleEmissionCheckScope guard(this); 1810 stlxr(rs, rt, dst); 1811 } 1812 void Stlxrb(const Register& rs, const Register& rt, const MemOperand& dst) { 1813 VIXL_ASSERT(allow_macro_instructions_); 1814 VIXL_ASSERT(!rs.Aliases(dst.base())); 1815 VIXL_ASSERT(!rs.Aliases(rt)); 1816 SingleEmissionCheckScope guard(this); 1817 stlxrb(rs, rt, dst); 1818 } 1819 void Stlxrh(const Register& rs, const Register& rt, const MemOperand& dst) { 1820 VIXL_ASSERT(allow_macro_instructions_); 1821 VIXL_ASSERT(!rs.Aliases(dst.base())); 1822 VIXL_ASSERT(!rs.Aliases(rt)); 1823 SingleEmissionCheckScope guard(this); 1824 stlxrh(rs, rt, dst); 1825 } 1826 void Stnp(const CPURegister& rt, 1827 const CPURegister& rt2, 1828 const MemOperand& dst) { 1829 VIXL_ASSERT(allow_macro_instructions_); 1830 SingleEmissionCheckScope guard(this); 1831 stnp(rt, rt2, dst); 1832 } 1833 void Stxp(const Register& rs, 1834 const Register& rt, 1835 const Register& rt2, 1836 const MemOperand& dst) { 1837 VIXL_ASSERT(allow_macro_instructions_); 1838 VIXL_ASSERT(!rs.Aliases(dst.base())); 1839 VIXL_ASSERT(!rs.Aliases(rt)); 1840 VIXL_ASSERT(!rs.Aliases(rt2)); 1841 SingleEmissionCheckScope guard(this); 1842 stxp(rs, rt, rt2, dst); 1843 } 1844 void Stxr(const Register& rs, const Register& rt, const MemOperand& dst) { 1845 VIXL_ASSERT(allow_macro_instructions_); 1846 VIXL_ASSERT(!rs.Aliases(dst.base())); 1847 VIXL_ASSERT(!rs.Aliases(rt)); 1848 SingleEmissionCheckScope guard(this); 1849 stxr(rs, rt, dst); 1850 } 1851 void Stxrb(const Register& rs, const Register& rt, const MemOperand& dst) { 1852 VIXL_ASSERT(allow_macro_instructions_); 1853 VIXL_ASSERT(!rs.Aliases(dst.base())); 1854 VIXL_ASSERT(!rs.Aliases(rt)); 1855 SingleEmissionCheckScope guard(this); 1856 stxrb(rs, rt, dst); 1857 } 1858 void Stxrh(const Register& rs, const Register& rt, const MemOperand& dst) { 1859 VIXL_ASSERT(allow_macro_instructions_); 1860 VIXL_ASSERT(!rs.Aliases(dst.base())); 1861 VIXL_ASSERT(!rs.Aliases(rt)); 1862 SingleEmissionCheckScope guard(this); 1863 stxrh(rs, rt, dst); 1864 } 1865 void Svc(int code) { 1866 VIXL_ASSERT(allow_macro_instructions_); 1867 SingleEmissionCheckScope guard(this); 1868 svc(code); 1869 } 1870 void Sxtb(const Register& rd, const Register& rn) { 1871 VIXL_ASSERT(allow_macro_instructions_); 1872 VIXL_ASSERT(!rd.IsZero()); 1873 VIXL_ASSERT(!rn.IsZero()); 1874 SingleEmissionCheckScope guard(this); 1875 sxtb(rd, rn); 1876 } 1877 void Sxth(const Register& rd, const Register& rn) { 1878 VIXL_ASSERT(allow_macro_instructions_); 1879 VIXL_ASSERT(!rd.IsZero()); 1880 VIXL_ASSERT(!rn.IsZero()); 1881 SingleEmissionCheckScope guard(this); 1882 sxth(rd, rn); 1883 } 1884 void Sxtw(const Register& rd, const Register& rn) { 1885 VIXL_ASSERT(allow_macro_instructions_); 1886 VIXL_ASSERT(!rd.IsZero()); 1887 VIXL_ASSERT(!rn.IsZero()); 1888 SingleEmissionCheckScope guard(this); 1889 sxtw(rd, rn); 1890 } 1891 void Tbl(const VRegister& vd, 1892 const VRegister& vn, 1893 const VRegister& vm) { 1894 VIXL_ASSERT(allow_macro_instructions_); 1895 SingleEmissionCheckScope guard(this); 1896 tbl(vd, vn, vm); 1897 } 1898 void Tbl(const VRegister& vd, 1899 const VRegister& vn, 1900 const VRegister& vn2, 1901 const VRegister& vm) { 1902 VIXL_ASSERT(allow_macro_instructions_); 1903 SingleEmissionCheckScope guard(this); 1904 tbl(vd, vn, vn2, vm); 1905 } 1906 void Tbl(const VRegister& vd, 1907 const VRegister& vn, 1908 const VRegister& vn2, 1909 const VRegister& vn3, 1910 const VRegister& vm) { 1911 VIXL_ASSERT(allow_macro_instructions_); 1912 SingleEmissionCheckScope guard(this); 1913 tbl(vd, vn, vn2, vn3, vm); 1914 } 1915 void Tbl(const VRegister& vd, 1916 const VRegister& vn, 1917 const VRegister& vn2, 1918 const VRegister& vn3, 1919 const VRegister& vn4, 1920 const VRegister& vm) { 1921 VIXL_ASSERT(allow_macro_instructions_); 1922 SingleEmissionCheckScope guard(this); 1923 tbl(vd, vn, vn2, vn3, vn4, vm); 1924 } 1925 void Tbx(const VRegister& vd, 1926 const VRegister& vn, 1927 const VRegister& vm) { 1928 VIXL_ASSERT(allow_macro_instructions_); 1929 SingleEmissionCheckScope guard(this); 1930 tbx(vd, vn, vm); 1931 } 1932 void Tbx(const VRegister& vd, 1933 const VRegister& vn, 1934 const VRegister& vn2, 1935 const VRegister& vm) { 1936 VIXL_ASSERT(allow_macro_instructions_); 1937 SingleEmissionCheckScope guard(this); 1938 tbx(vd, vn, vn2, vm); 1939 } 1940 void Tbx(const VRegister& vd, 1941 const VRegister& vn, 1942 const VRegister& vn2, 1943 const VRegister& vn3, 1944 const VRegister& vm) { 1945 VIXL_ASSERT(allow_macro_instructions_); 1946 SingleEmissionCheckScope guard(this); 1947 tbx(vd, vn, vn2, vn3, vm); 1948 } 1949 void Tbx(const VRegister& vd, 1950 const VRegister& vn, 1951 const VRegister& vn2, 1952 const VRegister& vn3, 1953 const VRegister& vn4, 1954 const VRegister& vm) { 1955 VIXL_ASSERT(allow_macro_instructions_); 1956 SingleEmissionCheckScope guard(this); 1957 tbx(vd, vn, vn2, vn3, vn4, vm); 1958 } 1959 void Tbnz(const Register& rt, unsigned bit_pos, Label* label); 1960 void Tbz(const Register& rt, unsigned bit_pos, Label* label); 1961 void Ubfiz(const Register& rd, 1962 const Register& rn, 1963 unsigned lsb, 1964 unsigned width) { 1965 VIXL_ASSERT(allow_macro_instructions_); 1966 VIXL_ASSERT(!rd.IsZero()); 1967 VIXL_ASSERT(!rn.IsZero()); 1968 SingleEmissionCheckScope guard(this); 1969 ubfiz(rd, rn, lsb, width); 1970 } 1971 void Ubfm(const Register& rd, 1972 const Register& rn, 1973 unsigned immr, 1974 unsigned imms) { 1975 VIXL_ASSERT(allow_macro_instructions_); 1976 VIXL_ASSERT(!rd.IsZero()); 1977 VIXL_ASSERT(!rn.IsZero()); 1978 SingleEmissionCheckScope guard(this); 1979 ubfm(rd, rn, immr, imms); 1980 } 1981 void Ubfx(const Register& rd, 1982 const Register& rn, 1983 unsigned lsb, 1984 unsigned width) { 1985 VIXL_ASSERT(allow_macro_instructions_); 1986 VIXL_ASSERT(!rd.IsZero()); 1987 VIXL_ASSERT(!rn.IsZero()); 1988 SingleEmissionCheckScope guard(this); 1989 ubfx(rd, rn, lsb, width); 1990 } 1991 void Ucvtf(const VRegister& vd, const Register& rn, int fbits = 0) { 1992 VIXL_ASSERT(allow_macro_instructions_); 1993 VIXL_ASSERT(!rn.IsZero()); 1994 SingleEmissionCheckScope guard(this); 1995 ucvtf(vd, rn, fbits); 1996 } 1997 void Udiv(const Register& rd, const Register& rn, const Register& rm) { 1998 VIXL_ASSERT(allow_macro_instructions_); 1999 VIXL_ASSERT(!rd.IsZero()); 2000 VIXL_ASSERT(!rn.IsZero()); 2001 VIXL_ASSERT(!rm.IsZero()); 2002 SingleEmissionCheckScope guard(this); 2003 udiv(rd, rn, rm); 2004 } 2005 void Umaddl(const Register& rd, 2006 const Register& rn, 2007 const Register& rm, 2008 const Register& ra) { 2009 VIXL_ASSERT(allow_macro_instructions_); 2010 VIXL_ASSERT(!rd.IsZero()); 2011 VIXL_ASSERT(!rn.IsZero()); 2012 VIXL_ASSERT(!rm.IsZero()); 2013 VIXL_ASSERT(!ra.IsZero()); 2014 SingleEmissionCheckScope guard(this); 2015 umaddl(rd, rn, rm, ra); 2016 } 2017 void Umull(const Register& rd, 2018 const Register& rn, 2019 const Register& rm) { 2020 VIXL_ASSERT(allow_macro_instructions_); 2021 VIXL_ASSERT(!rd.IsZero()); 2022 VIXL_ASSERT(!rn.IsZero()); 2023 VIXL_ASSERT(!rm.IsZero()); 2024 SingleEmissionCheckScope guard(this); 2025 umull(rd, rn, rm); 2026 } 2027 void Umulh(const Register& xd, const Register& xn, const Register& xm) { 2028 VIXL_ASSERT(allow_macro_instructions_); 2029 VIXL_ASSERT(!xd.IsZero()); 2030 VIXL_ASSERT(!xn.IsZero()); 2031 VIXL_ASSERT(!xm.IsZero()); 2032 SingleEmissionCheckScope guard(this); 2033 umulh(xd, xn, xm); 2034 } 2035 void Umsubl(const Register& rd, 2036 const Register& rn, 2037 const Register& rm, 2038 const Register& ra) { 2039 VIXL_ASSERT(allow_macro_instructions_); 2040 VIXL_ASSERT(!rd.IsZero()); 2041 VIXL_ASSERT(!rn.IsZero()); 2042 VIXL_ASSERT(!rm.IsZero()); 2043 VIXL_ASSERT(!ra.IsZero()); 2044 SingleEmissionCheckScope guard(this); 2045 umsubl(rd, rn, rm, ra); 2046 } 2047 void Unreachable() { 2048 VIXL_ASSERT(allow_macro_instructions_); 2049 SingleEmissionCheckScope guard(this); 2050 #ifdef USE_SIMULATOR 2051 hlt(kUnreachableOpcode); 2052 #else 2053 // Branch to 0 to generate a segfault. 2054 // lr - kInstructionSize is the address of the offending instruction. 2055 blr(xzr); 2056 #endif 2057 } 2058 void Uxtb(const Register& rd, const Register& rn) { 2059 VIXL_ASSERT(allow_macro_instructions_); 2060 VIXL_ASSERT(!rd.IsZero()); 2061 VIXL_ASSERT(!rn.IsZero()); 2062 SingleEmissionCheckScope guard(this); 2063 uxtb(rd, rn); 2064 } 2065 void Uxth(const Register& rd, const Register& rn) { 2066 VIXL_ASSERT(allow_macro_instructions_); 2067 VIXL_ASSERT(!rd.IsZero()); 2068 VIXL_ASSERT(!rn.IsZero()); 2069 SingleEmissionCheckScope guard(this); 2070 uxth(rd, rn); 2071 } 2072 void Uxtw(const Register& rd, const Register& rn) { 2073 VIXL_ASSERT(allow_macro_instructions_); 2074 VIXL_ASSERT(!rd.IsZero()); 2075 VIXL_ASSERT(!rn.IsZero()); 2076 SingleEmissionCheckScope guard(this); 2077 uxtw(rd, rn); 2078 } 2079 2080 // NEON 3 vector register instructions. 2081 #define NEON_3VREG_MACRO_LIST(V) \ 2082 V(add, Add) \ 2083 V(addhn, Addhn) \ 2084 V(addhn2, Addhn2) \ 2085 V(addp, Addp) \ 2086 V(and_, And) \ 2087 V(bic, Bic) \ 2088 V(bif, Bif) \ 2089 V(bit, Bit) \ 2090 V(bsl, Bsl) \ 2091 V(cmeq, Cmeq) \ 2092 V(cmge, Cmge) \ 2093 V(cmgt, Cmgt) \ 2094 V(cmhi, Cmhi) \ 2095 V(cmhs, Cmhs) \ 2096 V(cmtst, Cmtst) \ 2097 V(eor, Eor) \ 2098 V(fabd, Fabd) \ 2099 V(facge, Facge) \ 2100 V(facgt, Facgt) \ 2101 V(faddp, Faddp) \ 2102 V(fcmeq, Fcmeq) \ 2103 V(fcmge, Fcmge) \ 2104 V(fcmgt, Fcmgt) \ 2105 V(fmaxnmp, Fmaxnmp) \ 2106 V(fmaxp, Fmaxp) \ 2107 V(fminnmp, Fminnmp) \ 2108 V(fminp, Fminp) \ 2109 V(fmla, Fmla) \ 2110 V(fmls, Fmls) \ 2111 V(fmulx, Fmulx) \ 2112 V(frecps, Frecps) \ 2113 V(frsqrts, Frsqrts) \ 2114 V(mla, Mla) \ 2115 V(mls, Mls) \ 2116 V(mul, Mul) \ 2117 V(orn, Orn) \ 2118 V(orr, Orr) \ 2119 V(pmul, Pmul) \ 2120 V(pmull, Pmull) \ 2121 V(pmull2, Pmull2) \ 2122 V(raddhn, Raddhn) \ 2123 V(raddhn2, Raddhn2) \ 2124 V(rsubhn, Rsubhn) \ 2125 V(rsubhn2, Rsubhn2) \ 2126 V(saba, Saba) \ 2127 V(sabal, Sabal) \ 2128 V(sabal2, Sabal2) \ 2129 V(sabd, Sabd) \ 2130 V(sabdl, Sabdl) \ 2131 V(sabdl2, Sabdl2) \ 2132 V(saddl, Saddl) \ 2133 V(saddl2, Saddl2) \ 2134 V(saddw, Saddw) \ 2135 V(saddw2, Saddw2) \ 2136 V(shadd, Shadd) \ 2137 V(shsub, Shsub) \ 2138 V(smax, Smax) \ 2139 V(smaxp, Smaxp) \ 2140 V(smin, Smin) \ 2141 V(sminp, Sminp) \ 2142 V(smlal, Smlal) \ 2143 V(smlal2, Smlal2) \ 2144 V(smlsl, Smlsl) \ 2145 V(smlsl2, Smlsl2) \ 2146 V(smull, Smull) \ 2147 V(smull2, Smull2) \ 2148 V(sqadd, Sqadd) \ 2149 V(sqdmlal, Sqdmlal) \ 2150 V(sqdmlal2, Sqdmlal2) \ 2151 V(sqdmlsl, Sqdmlsl) \ 2152 V(sqdmlsl2, Sqdmlsl2) \ 2153 V(sqdmulh, Sqdmulh) \ 2154 V(sqdmull, Sqdmull) \ 2155 V(sqdmull2, Sqdmull2) \ 2156 V(sqrdmulh, Sqrdmulh) \ 2157 V(sqrshl, Sqrshl) \ 2158 V(sqshl, Sqshl) \ 2159 V(sqsub, Sqsub) \ 2160 V(srhadd, Srhadd) \ 2161 V(srshl, Srshl) \ 2162 V(sshl, Sshl) \ 2163 V(ssubl, Ssubl) \ 2164 V(ssubl2, Ssubl2) \ 2165 V(ssubw, Ssubw) \ 2166 V(ssubw2, Ssubw2) \ 2167 V(sub, Sub) \ 2168 V(subhn, Subhn) \ 2169 V(subhn2, Subhn2) \ 2170 V(trn1, Trn1) \ 2171 V(trn2, Trn2) \ 2172 V(uaba, Uaba) \ 2173 V(uabal, Uabal) \ 2174 V(uabal2, Uabal2) \ 2175 V(uabd, Uabd) \ 2176 V(uabdl, Uabdl) \ 2177 V(uabdl2, Uabdl2) \ 2178 V(uaddl, Uaddl) \ 2179 V(uaddl2, Uaddl2) \ 2180 V(uaddw, Uaddw) \ 2181 V(uaddw2, Uaddw2) \ 2182 V(uhadd, Uhadd) \ 2183 V(uhsub, Uhsub) \ 2184 V(umax, Umax) \ 2185 V(umaxp, Umaxp) \ 2186 V(umin, Umin) \ 2187 V(uminp, Uminp) \ 2188 V(umlal, Umlal) \ 2189 V(umlal2, Umlal2) \ 2190 V(umlsl, Umlsl) \ 2191 V(umlsl2, Umlsl2) \ 2192 V(umull, Umull) \ 2193 V(umull2, Umull2) \ 2194 V(uqadd, Uqadd) \ 2195 V(uqrshl, Uqrshl) \ 2196 V(uqshl, Uqshl) \ 2197 V(uqsub, Uqsub) \ 2198 V(urhadd, Urhadd) \ 2199 V(urshl, Urshl) \ 2200 V(ushl, Ushl) \ 2201 V(usubl, Usubl) \ 2202 V(usubl2, Usubl2) \ 2203 V(usubw, Usubw) \ 2204 V(usubw2, Usubw2) \ 2205 V(uzp1, Uzp1) \ 2206 V(uzp2, Uzp2) \ 2207 V(zip1, Zip1) \ 2208 V(zip2, Zip2) 2209 2210 #define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \ 2211 void MASM(const VRegister& vd, \ 2212 const VRegister& vn, \ 2213 const VRegister& vm) { \ 2214 VIXL_ASSERT(allow_macro_instructions_); \ 2215 SingleEmissionCheckScope guard(this); \ 2216 ASM(vd, vn, vm); \ 2217 } 2218 NEON_3VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 2219 #undef DEFINE_MACRO_ASM_FUNC 2220 2221 // NEON 2 vector register instructions. 2222 #define NEON_2VREG_MACRO_LIST(V) \ 2223 V(abs, Abs) \ 2224 V(addp, Addp) \ 2225 V(addv, Addv) \ 2226 V(cls, Cls) \ 2227 V(clz, Clz) \ 2228 V(cnt, Cnt) \ 2229 V(fabs, Fabs) \ 2230 V(faddp, Faddp) \ 2231 V(fcvtas, Fcvtas) \ 2232 V(fcvtau, Fcvtau) \ 2233 V(fcvtms, Fcvtms) \ 2234 V(fcvtmu, Fcvtmu) \ 2235 V(fcvtns, Fcvtns) \ 2236 V(fcvtnu, Fcvtnu) \ 2237 V(fcvtps, Fcvtps) \ 2238 V(fcvtpu, Fcvtpu) \ 2239 V(fmaxnmp, Fmaxnmp) \ 2240 V(fmaxnmv, Fmaxnmv) \ 2241 V(fmaxp, Fmaxp) \ 2242 V(fmaxv, Fmaxv) \ 2243 V(fminnmp, Fminnmp) \ 2244 V(fminnmv, Fminnmv) \ 2245 V(fminp, Fminp) \ 2246 V(fminv, Fminv) \ 2247 V(fneg, Fneg) \ 2248 V(frecpe, Frecpe) \ 2249 V(frecpx, Frecpx) \ 2250 V(frinta, Frinta) \ 2251 V(frinti, Frinti) \ 2252 V(frintm, Frintm) \ 2253 V(frintn, Frintn) \ 2254 V(frintp, Frintp) \ 2255 V(frintx, Frintx) \ 2256 V(frintz, Frintz) \ 2257 V(frsqrte, Frsqrte) \ 2258 V(fsqrt, Fsqrt) \ 2259 V(mov, Mov) \ 2260 V(mvn, Mvn) \ 2261 V(neg, Neg) \ 2262 V(not_, Not) \ 2263 V(rbit, Rbit) \ 2264 V(rev16, Rev16) \ 2265 V(rev32, Rev32) \ 2266 V(rev64, Rev64) \ 2267 V(sadalp, Sadalp) \ 2268 V(saddlp, Saddlp) \ 2269 V(saddlv, Saddlv) \ 2270 V(smaxv, Smaxv) \ 2271 V(sminv, Sminv) \ 2272 V(sqabs, Sqabs) \ 2273 V(sqneg, Sqneg) \ 2274 V(sqxtn, Sqxtn) \ 2275 V(sqxtn2, Sqxtn2) \ 2276 V(sqxtun, Sqxtun) \ 2277 V(sqxtun2, Sqxtun2) \ 2278 V(suqadd, Suqadd) \ 2279 V(sxtl, Sxtl) \ 2280 V(sxtl2, Sxtl2) \ 2281 V(uadalp, Uadalp) \ 2282 V(uaddlp, Uaddlp) \ 2283 V(uaddlv, Uaddlv) \ 2284 V(umaxv, Umaxv) \ 2285 V(uminv, Uminv) \ 2286 V(uqxtn, Uqxtn) \ 2287 V(uqxtn2, Uqxtn2) \ 2288 V(urecpe, Urecpe) \ 2289 V(ursqrte, Ursqrte) \ 2290 V(usqadd, Usqadd) \ 2291 V(uxtl, Uxtl) \ 2292 V(uxtl2, Uxtl2) \ 2293 V(xtn, Xtn) \ 2294 V(xtn2, Xtn2) 2295 2296 #define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \ 2297 void MASM(const VRegister& vd, \ 2298 const VRegister& vn) { \ 2299 VIXL_ASSERT(allow_macro_instructions_); \ 2300 SingleEmissionCheckScope guard(this); \ 2301 ASM(vd, vn); \ 2302 } 2303 NEON_2VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 2304 #undef DEFINE_MACRO_ASM_FUNC 2305 2306 // NEON 2 vector register with immediate instructions. 2307 #define NEON_2VREG_FPIMM_MACRO_LIST(V) \ 2308 V(fcmeq, Fcmeq) \ 2309 V(fcmge, Fcmge) \ 2310 V(fcmgt, Fcmgt) \ 2311 V(fcmle, Fcmle) \ 2312 V(fcmlt, Fcmlt) 2313 2314 #define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \ 2315 void MASM(const VRegister& vd, \ 2316 const VRegister& vn, \ 2317 double imm) { \ 2318 VIXL_ASSERT(allow_macro_instructions_); \ 2319 SingleEmissionCheckScope guard(this); \ 2320 ASM(vd, vn, imm); \ 2321 } 2322 NEON_2VREG_FPIMM_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 2323 #undef DEFINE_MACRO_ASM_FUNC 2324 2325 // NEON by element instructions. 2326 #define NEON_BYELEMENT_MACRO_LIST(V) \ 2327 V(fmul, Fmul) \ 2328 V(fmla, Fmla) \ 2329 V(fmls, Fmls) \ 2330 V(fmulx, Fmulx) \ 2331 V(mul, Mul) \ 2332 V(mla, Mla) \ 2333 V(mls, Mls) \ 2334 V(sqdmulh, Sqdmulh) \ 2335 V(sqrdmulh, Sqrdmulh) \ 2336 V(sqdmull, Sqdmull) \ 2337 V(sqdmull2, Sqdmull2) \ 2338 V(sqdmlal, Sqdmlal) \ 2339 V(sqdmlal2, Sqdmlal2) \ 2340 V(sqdmlsl, Sqdmlsl) \ 2341 V(sqdmlsl2, Sqdmlsl2) \ 2342 V(smull, Smull) \ 2343 V(smull2, Smull2) \ 2344 V(smlal, Smlal) \ 2345 V(smlal2, Smlal2) \ 2346 V(smlsl, Smlsl) \ 2347 V(smlsl2, Smlsl2) \ 2348 V(umull, Umull) \ 2349 V(umull2, Umull2) \ 2350 V(umlal, Umlal) \ 2351 V(umlal2, Umlal2) \ 2352 V(umlsl, Umlsl) \ 2353 V(umlsl2, Umlsl2) 2354 2355 #define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \ 2356 void MASM(const VRegister& vd, \ 2357 const VRegister& vn, \ 2358 const VRegister& vm, \ 2359 int vm_index \ 2360 ) { \ 2361 VIXL_ASSERT(allow_macro_instructions_); \ 2362 SingleEmissionCheckScope guard(this); \ 2363 ASM(vd, vn, vm, vm_index); \ 2364 } 2365 NEON_BYELEMENT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 2366 #undef DEFINE_MACRO_ASM_FUNC 2367 2368 #define NEON_2VREG_SHIFT_MACRO_LIST(V) \ 2369 V(rshrn, Rshrn) \ 2370 V(rshrn2, Rshrn2) \ 2371 V(shl, Shl) \ 2372 V(shll, Shll) \ 2373 V(shll2, Shll2) \ 2374 V(shrn, Shrn) \ 2375 V(shrn2, Shrn2) \ 2376 V(sli, Sli) \ 2377 V(sqrshrn, Sqrshrn) \ 2378 V(sqrshrn2, Sqrshrn2) \ 2379 V(sqrshrun, Sqrshrun) \ 2380 V(sqrshrun2, Sqrshrun2) \ 2381 V(sqshl, Sqshl) \ 2382 V(sqshlu, Sqshlu) \ 2383 V(sqshrn, Sqshrn) \ 2384 V(sqshrn2, Sqshrn2) \ 2385 V(sqshrun, Sqshrun) \ 2386 V(sqshrun2, Sqshrun2) \ 2387 V(sri, Sri) \ 2388 V(srshr, Srshr) \ 2389 V(srsra, Srsra) \ 2390 V(sshll, Sshll) \ 2391 V(sshll2, Sshll2) \ 2392 V(sshr, Sshr) \ 2393 V(ssra, Ssra) \ 2394 V(uqrshrn, Uqrshrn) \ 2395 V(uqrshrn2, Uqrshrn2) \ 2396 V(uqshl, Uqshl) \ 2397 V(uqshrn, Uqshrn) \ 2398 V(uqshrn2, Uqshrn2) \ 2399 V(urshr, Urshr) \ 2400 V(ursra, Ursra) \ 2401 V(ushll, Ushll) \ 2402 V(ushll2, Ushll2) \ 2403 V(ushr, Ushr) \ 2404 V(usra, Usra) \ 2405 2406 #define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \ 2407 void MASM(const VRegister& vd, \ 2408 const VRegister& vn, \ 2409 int shift) { \ 2410 VIXL_ASSERT(allow_macro_instructions_); \ 2411 SingleEmissionCheckScope guard(this); \ 2412 ASM(vd, vn, shift); \ 2413 } 2414 NEON_2VREG_SHIFT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 2415 #undef DEFINE_MACRO_ASM_FUNC 2416 2417 void Bic(const VRegister& vd, 2418 const int imm8, 2419 const int left_shift = 0) { 2420 VIXL_ASSERT(allow_macro_instructions_); 2421 SingleEmissionCheckScope guard(this); 2422 bic(vd, imm8, left_shift); 2423 } 2424 void Cmeq(const VRegister& vd, 2425 const VRegister& vn, 2426 int imm) { 2427 VIXL_ASSERT(allow_macro_instructions_); 2428 SingleEmissionCheckScope guard(this); 2429 cmeq(vd, vn, imm); 2430 } 2431 void Cmge(const VRegister& vd, 2432 const VRegister& vn, 2433 int imm) { 2434 VIXL_ASSERT(allow_macro_instructions_); 2435 SingleEmissionCheckScope guard(this); 2436 cmge(vd, vn, imm); 2437 } 2438 void Cmgt(const VRegister& vd, 2439 const VRegister& vn, 2440 int imm) { 2441 VIXL_ASSERT(allow_macro_instructions_); 2442 SingleEmissionCheckScope guard(this); 2443 cmgt(vd, vn, imm); 2444 } 2445 void Cmle(const VRegister& vd, 2446 const VRegister& vn, 2447 int imm) { 2448 VIXL_ASSERT(allow_macro_instructions_); 2449 SingleEmissionCheckScope guard(this); 2450 cmle(vd, vn, imm); 2451 } 2452 void Cmlt(const VRegister& vd, 2453 const VRegister& vn, 2454 int imm) { 2455 VIXL_ASSERT(allow_macro_instructions_); 2456 SingleEmissionCheckScope guard(this); 2457 cmlt(vd, vn, imm); 2458 } 2459 void Dup(const VRegister& vd, 2460 const VRegister& vn, 2461 int index) { 2462 VIXL_ASSERT(allow_macro_instructions_); 2463 SingleEmissionCheckScope guard(this); 2464 dup(vd, vn, index); 2465 } 2466 void Dup(const VRegister& vd, 2467 const Register& rn) { 2468 VIXL_ASSERT(allow_macro_instructions_); 2469 SingleEmissionCheckScope guard(this); 2470 dup(vd, rn); 2471 } 2472 void Ext(const VRegister& vd, 2473 const VRegister& vn, 2474 const VRegister& vm, 2475 int index) { 2476 VIXL_ASSERT(allow_macro_instructions_); 2477 SingleEmissionCheckScope guard(this); 2478 ext(vd, vn, vm, index); 2479 } 2480 void Ins(const VRegister& vd, 2481 int vd_index, 2482 const VRegister& vn, 2483 int vn_index) { 2484 VIXL_ASSERT(allow_macro_instructions_); 2485 SingleEmissionCheckScope guard(this); 2486 ins(vd, vd_index, vn, vn_index); 2487 } 2488 void Ins(const VRegister& vd, 2489 int vd_index, 2490 const Register& rn) { 2491 VIXL_ASSERT(allow_macro_instructions_); 2492 SingleEmissionCheckScope guard(this); 2493 ins(vd, vd_index, rn); 2494 } 2495 void Ld1(const VRegister& vt, 2496 const MemOperand& src) { 2497 VIXL_ASSERT(allow_macro_instructions_); 2498 SingleEmissionCheckScope guard(this); 2499 ld1(vt, src); 2500 } 2501 void Ld1(const VRegister& vt, 2502 const VRegister& vt2, 2503 const MemOperand& src) { 2504 VIXL_ASSERT(allow_macro_instructions_); 2505 SingleEmissionCheckScope guard(this); 2506 ld1(vt, vt2, src); 2507 } 2508 void Ld1(const VRegister& vt, 2509 const VRegister& vt2, 2510 const VRegister& vt3, 2511 const MemOperand& src) { 2512 VIXL_ASSERT(allow_macro_instructions_); 2513 SingleEmissionCheckScope guard(this); 2514 ld1(vt, vt2, vt3, src); 2515 } 2516 void Ld1(const VRegister& vt, 2517 const VRegister& vt2, 2518 const VRegister& vt3, 2519 const VRegister& vt4, 2520 const MemOperand& src) { 2521 VIXL_ASSERT(allow_macro_instructions_); 2522 SingleEmissionCheckScope guard(this); 2523 ld1(vt, vt2, vt3, vt4, src); 2524 } 2525 void Ld1(const VRegister& vt, 2526 int lane, 2527 const MemOperand& src) { 2528 VIXL_ASSERT(allow_macro_instructions_); 2529 SingleEmissionCheckScope guard(this); 2530 ld1(vt, lane, src); 2531 } 2532 void Ld1r(const VRegister& vt, 2533 const MemOperand& src) { 2534 VIXL_ASSERT(allow_macro_instructions_); 2535 SingleEmissionCheckScope guard(this); 2536 ld1r(vt, src); 2537 } 2538 void Ld2(const VRegister& vt, 2539 const VRegister& vt2, 2540 const MemOperand& src) { 2541 VIXL_ASSERT(allow_macro_instructions_); 2542 SingleEmissionCheckScope guard(this); 2543 ld2(vt, vt2, src); 2544 } 2545 void Ld2(const VRegister& vt, 2546 const VRegister& vt2, 2547 int lane, 2548 const MemOperand& src) { 2549 VIXL_ASSERT(allow_macro_instructions_); 2550 SingleEmissionCheckScope guard(this); 2551 ld2(vt, vt2, lane, src); 2552 } 2553 void Ld2r(const VRegister& vt, 2554 const VRegister& vt2, 2555 const MemOperand& src) { 2556 VIXL_ASSERT(allow_macro_instructions_); 2557 SingleEmissionCheckScope guard(this); 2558 ld2r(vt, vt2, src); 2559 } 2560 void Ld3(const VRegister& vt, 2561 const VRegister& vt2, 2562 const VRegister& vt3, 2563 const MemOperand& src) { 2564 VIXL_ASSERT(allow_macro_instructions_); 2565 SingleEmissionCheckScope guard(this); 2566 ld3(vt, vt2, vt3, src); 2567 } 2568 void Ld3(const VRegister& vt, 2569 const VRegister& vt2, 2570 const VRegister& vt3, 2571 int lane, 2572 const MemOperand& src) { 2573 VIXL_ASSERT(allow_macro_instructions_); 2574 SingleEmissionCheckScope guard(this); 2575 ld3(vt, vt2, vt3, lane, src); 2576 } 2577 void Ld3r(const VRegister& vt, 2578 const VRegister& vt2, 2579 const VRegister& vt3, 2580 const MemOperand& src) { 2581 VIXL_ASSERT(allow_macro_instructions_); 2582 SingleEmissionCheckScope guard(this); 2583 ld3r(vt, vt2, vt3, src); 2584 } 2585 void Ld4(const VRegister& vt, 2586 const VRegister& vt2, 2587 const VRegister& vt3, 2588 const VRegister& vt4, 2589 const MemOperand& src) { 2590 VIXL_ASSERT(allow_macro_instructions_); 2591 SingleEmissionCheckScope guard(this); 2592 ld4(vt, vt2, vt3, vt4, src); 2593 } 2594 void Ld4(const VRegister& vt, 2595 const VRegister& vt2, 2596 const VRegister& vt3, 2597 const VRegister& vt4, 2598 int lane, 2599 const MemOperand& src) { 2600 VIXL_ASSERT(allow_macro_instructions_); 2601 SingleEmissionCheckScope guard(this); 2602 ld4(vt, vt2, vt3, vt4, lane, src); 2603 } 2604 void Ld4r(const VRegister& vt, 2605 const VRegister& vt2, 2606 const VRegister& vt3, 2607 const VRegister& vt4, 2608 const MemOperand& src) { 2609 VIXL_ASSERT(allow_macro_instructions_); 2610 SingleEmissionCheckScope guard(this); 2611 ld4r(vt, vt2, vt3, vt4, src); 2612 } 2613 void Mov(const VRegister& vd, 2614 int vd_index, 2615 const VRegister& vn, 2616 int vn_index) { 2617 VIXL_ASSERT(allow_macro_instructions_); 2618 SingleEmissionCheckScope guard(this); 2619 mov(vd, vd_index, vn, vn_index); 2620 } 2621 void Mov(const VRegister& vd, 2622 const VRegister& vn, 2623 int index) { 2624 VIXL_ASSERT(allow_macro_instructions_); 2625 SingleEmissionCheckScope guard(this); 2626 mov(vd, vn, index); 2627 } 2628 void Mov(const VRegister& vd, 2629 int vd_index, 2630 const Register& rn) { 2631 VIXL_ASSERT(allow_macro_instructions_); 2632 SingleEmissionCheckScope guard(this); 2633 mov(vd, vd_index, rn); 2634 } 2635 void Mov(const Register& rd, 2636 const VRegister& vn, 2637 int vn_index) { 2638 VIXL_ASSERT(allow_macro_instructions_); 2639 SingleEmissionCheckScope guard(this); 2640 mov(rd, vn, vn_index); 2641 } 2642 void Movi(const VRegister& vd, 2643 uint64_t imm, 2644 Shift shift = LSL, 2645 int shift_amount = 0); 2646 void Movi(const VRegister& vd, uint64_t hi, uint64_t lo); 2647 void Mvni(const VRegister& vd, 2648 const int imm8, 2649 Shift shift = LSL, 2650 const int shift_amount = 0) { 2651 VIXL_ASSERT(allow_macro_instructions_); 2652 SingleEmissionCheckScope guard(this); 2653 mvni(vd, imm8, shift, shift_amount); 2654 } 2655 void Orr(const VRegister& vd, 2656 const int imm8, 2657 const int left_shift = 0) { 2658 VIXL_ASSERT(allow_macro_instructions_); 2659 SingleEmissionCheckScope guard(this); 2660 orr(vd, imm8, left_shift); 2661 } 2662 void Scvtf(const VRegister& vd, 2663 const VRegister& vn, 2664 int fbits = 0) { 2665 VIXL_ASSERT(allow_macro_instructions_); 2666 SingleEmissionCheckScope guard(this); 2667 scvtf(vd, vn, fbits); 2668 } 2669 void Ucvtf(const VRegister& vd, 2670 const VRegister& vn, 2671 int fbits = 0) { 2672 VIXL_ASSERT(allow_macro_instructions_); 2673 SingleEmissionCheckScope guard(this); 2674 ucvtf(vd, vn, fbits); 2675 } 2676 void Fcvtzs(const VRegister& vd, 2677 const VRegister& vn, 2678 int fbits = 0) { 2679 VIXL_ASSERT(allow_macro_instructions_); 2680 SingleEmissionCheckScope guard(this); 2681 fcvtzs(vd, vn, fbits); 2682 } 2683 void Fcvtzu(const VRegister& vd, 2684 const VRegister& vn, 2685 int fbits = 0) { 2686 VIXL_ASSERT(allow_macro_instructions_); 2687 SingleEmissionCheckScope guard(this); 2688 fcvtzu(vd, vn, fbits); 2689 } 2690 void St1(const VRegister& vt, 2691 const MemOperand& dst) { 2692 VIXL_ASSERT(allow_macro_instructions_); 2693 SingleEmissionCheckScope guard(this); 2694 st1(vt, dst); 2695 } 2696 void St1(const VRegister& vt, 2697 const VRegister& vt2, 2698 const MemOperand& dst) { 2699 VIXL_ASSERT(allow_macro_instructions_); 2700 SingleEmissionCheckScope guard(this); 2701 st1(vt, vt2, dst); 2702 } 2703 void St1(const VRegister& vt, 2704 const VRegister& vt2, 2705 const VRegister& vt3, 2706 const MemOperand& dst) { 2707 VIXL_ASSERT(allow_macro_instructions_); 2708 SingleEmissionCheckScope guard(this); 2709 st1(vt, vt2, vt3, dst); 2710 } 2711 void St1(const VRegister& vt, 2712 const VRegister& vt2, 2713 const VRegister& vt3, 2714 const VRegister& vt4, 2715 const MemOperand& dst) { 2716 VIXL_ASSERT(allow_macro_instructions_); 2717 SingleEmissionCheckScope guard(this); 2718 st1(vt, vt2, vt3, vt4, dst); 2719 } 2720 void St1(const VRegister& vt, 2721 int lane, 2722 const MemOperand& dst) { 2723 VIXL_ASSERT(allow_macro_instructions_); 2724 SingleEmissionCheckScope guard(this); 2725 st1(vt, lane, dst); 2726 } 2727 void St2(const VRegister& vt, 2728 const VRegister& vt2, 2729 const MemOperand& dst) { 2730 VIXL_ASSERT(allow_macro_instructions_); 2731 SingleEmissionCheckScope guard(this); 2732 st2(vt, vt2, dst); 2733 } 2734 void St3(const VRegister& vt, 2735 const VRegister& vt2, 2736 const VRegister& vt3, 2737 const MemOperand& dst) { 2738 VIXL_ASSERT(allow_macro_instructions_); 2739 SingleEmissionCheckScope guard(this); 2740 st3(vt, vt2, vt3, dst); 2741 } 2742 void St4(const VRegister& vt, 2743 const VRegister& vt2, 2744 const VRegister& vt3, 2745 const VRegister& vt4, 2746 const MemOperand& dst) { 2747 VIXL_ASSERT(allow_macro_instructions_); 2748 SingleEmissionCheckScope guard(this); 2749 st4(vt, vt2, vt3, vt4, dst); 2750 } 2751 void St2(const VRegister& vt, 2752 const VRegister& vt2, 2753 int lane, 2754 const MemOperand& dst) { 2755 VIXL_ASSERT(allow_macro_instructions_); 2756 SingleEmissionCheckScope guard(this); 2757 st2(vt, vt2, lane, dst); 2758 } 2759 void St3(const VRegister& vt, 2760 const VRegister& vt2, 2761 const VRegister& vt3, 2762 int lane, 2763 const MemOperand& dst) { 2764 VIXL_ASSERT(allow_macro_instructions_); 2765 SingleEmissionCheckScope guard(this); 2766 st3(vt, vt2, vt3, lane, dst); 2767 } 2768 void St4(const VRegister& vt, 2769 const VRegister& vt2, 2770 const VRegister& vt3, 2771 const VRegister& vt4, 2772 int lane, 2773 const MemOperand& dst) { 2774 VIXL_ASSERT(allow_macro_instructions_); 2775 SingleEmissionCheckScope guard(this); 2776 st4(vt, vt2, vt3, vt4, lane, dst); 2777 } 2778 void Smov(const Register& rd, 2779 const VRegister& vn, 2780 int vn_index) { 2781 VIXL_ASSERT(allow_macro_instructions_); 2782 SingleEmissionCheckScope guard(this); 2783 smov(rd, vn, vn_index); 2784 } 2785 void Umov(const Register& rd, 2786 const VRegister& vn, 2787 int vn_index) { 2788 VIXL_ASSERT(allow_macro_instructions_); 2789 SingleEmissionCheckScope guard(this); 2790 umov(rd, vn, vn_index); 2791 } 2792 void Crc32b(const Register& rd, 2793 const Register& rn, 2794 const Register& rm) { 2795 VIXL_ASSERT(allow_macro_instructions_); 2796 SingleEmissionCheckScope guard(this); 2797 crc32b(rd, rn, rm); 2798 } 2799 void Crc32h(const Register& rd, 2800 const Register& rn, 2801 const Register& rm) { 2802 VIXL_ASSERT(allow_macro_instructions_); 2803 SingleEmissionCheckScope guard(this); 2804 crc32h(rd, rn, rm); 2805 } 2806 void Crc32w(const Register& rd, 2807 const Register& rn, 2808 const Register& rm) { 2809 VIXL_ASSERT(allow_macro_instructions_); 2810 SingleEmissionCheckScope guard(this); 2811 crc32w(rd, rn, rm); 2812 } 2813 void Crc32x(const Register& rd, 2814 const Register& rn, 2815 const Register& rm) { 2816 VIXL_ASSERT(allow_macro_instructions_); 2817 SingleEmissionCheckScope guard(this); 2818 crc32x(rd, rn, rm); 2819 } 2820 void Crc32cb(const Register& rd, 2821 const Register& rn, 2822 const Register& rm) { 2823 VIXL_ASSERT(allow_macro_instructions_); 2824 SingleEmissionCheckScope guard(this); 2825 crc32cb(rd, rn, rm); 2826 } 2827 void Crc32ch(const Register& rd, 2828 const Register& rn, 2829 const Register& rm) { 2830 VIXL_ASSERT(allow_macro_instructions_); 2831 SingleEmissionCheckScope guard(this); 2832 crc32ch(rd, rn, rm); 2833 } 2834 void Crc32cw(const Register& rd, 2835 const Register& rn, 2836 const Register& rm) { 2837 VIXL_ASSERT(allow_macro_instructions_); 2838 SingleEmissionCheckScope guard(this); 2839 crc32cw(rd, rn, rm); 2840 } 2841 void Crc32cx(const Register& rd, 2842 const Register& rn, 2843 const Register& rm) { 2844 VIXL_ASSERT(allow_macro_instructions_); 2845 SingleEmissionCheckScope guard(this); 2846 crc32cx(rd, rn, rm); 2847 } 2848 // Push the system stack pointer (sp) down to allow the same to be done to 2849 // the current stack pointer (according to StackPointer()). This must be 2850 // called _before_ accessing the memory. 2851 // 2852 // This is necessary when pushing or otherwise adding things to the stack, to 2853 // satisfy the AAPCS64 constraint that the memory below the system stack 2854 // pointer is not accessed. 2855 // 2856 // This method asserts that StackPointer() is not sp, since the call does 2857 // not make sense in that context. 2858 // 2859 // TODO: This method can only accept values of 'space' that can be encoded in 2860 // one instruction. Refer to the implementation for details. 2861 void BumpSystemStackPointer(const Operand& space); 2862 2863 #if VIXL_DEBUG 2864 void SetAllowMacroInstructions(bool value) { 2865 allow_macro_instructions_ = value; 2866 } 2867 2868 bool AllowMacroInstructions() const { 2869 return allow_macro_instructions_; 2870 } 2871 #endif 2872 2873 void BlockLiteralPool() { literal_pool_.Block(); } 2874 void ReleaseLiteralPool() { literal_pool_.Release(); } 2875 bool IsLiteralPoolBlocked() const { return literal_pool_.IsBlocked(); } 2876 void BlockVeneerPool() { veneer_pool_.Block(); } 2877 void ReleaseVeneerPool() { veneer_pool_.Release(); } 2878 bool IsVeneerPoolBlocked() const { return veneer_pool_.IsBlocked(); } 2879 2880 size_t LiteralPoolSize() const { 2881 return literal_pool_.Size(); 2882 } 2883 2884 size_t LiteralPoolMaxSize() const { 2885 return literal_pool_.MaxSize(); 2886 } 2887 2888 size_t VeneerPoolMaxSize() const { 2889 return veneer_pool_.MaxSize(); 2890 } 2891 2892 // The number of unresolved branches that may require a veneer. 2893 int NumberOfPotentialVeneers() const { 2894 return veneer_pool_.NumberOfPotentialVeneers(); 2895 } 2896 2897 ptrdiff_t NextCheckPoint() { 2898 ptrdiff_t next_checkpoint_for_pools = std::min(literal_pool_.checkpoint(), 2899 veneer_pool_.checkpoint()); 2900 return std::min(next_checkpoint_for_pools, BufferEndOffset()); 2901 } 2902 2903 void EmitLiteralPool(LiteralPool::EmitOption option) { 2904 if (!literal_pool_.IsEmpty()) literal_pool_.Emit(option); 2905 2906 checkpoint_ = NextCheckPoint(); 2907 recommended_checkpoint_ = literal_pool_.NextRecommendedCheckpoint(); 2908 } 2909 2910 void CheckEmitFor(size_t amount); 2911 void EnsureEmitFor(size_t amount) { 2912 ptrdiff_t offset = amount; 2913 ptrdiff_t max_pools_size = literal_pool_.MaxSize() + veneer_pool_.MaxSize(); 2914 ptrdiff_t cursor = CursorOffset(); 2915 if ((cursor >= recommended_checkpoint_) || 2916 ((cursor + offset + max_pools_size) >= checkpoint_)) { 2917 CheckEmitFor(amount); 2918 } 2919 } 2920 2921 // Set the current stack pointer, but don't generate any code. 2922 void SetStackPointer(const Register& stack_pointer) { 2923 VIXL_ASSERT(!TmpList()->IncludesAliasOf(stack_pointer)); 2924 sp_ = stack_pointer; 2925 } 2926 2927 // Return the current stack pointer, as set by SetStackPointer. 2928 const Register& StackPointer() const { 2929 return sp_; 2930 } 2931 2932 CPURegList* TmpList() { return &tmp_list_; } 2933 CPURegList* FPTmpList() { return &fptmp_list_; } 2934 2935 // Like printf, but print at run-time from generated code. 2936 // 2937 // The caller must ensure that arguments for floating-point placeholders 2938 // (such as %e, %f or %g) are VRegisters in format 1S or 1D, and that 2939 // arguments for integer placeholders are Registers. 2940 // 2941 // At the moment it is only possible to print the value of sp if it is the 2942 // current stack pointer. Otherwise, the MacroAssembler will automatically 2943 // update sp on every push (using BumpSystemStackPointer), so determining its 2944 // value is difficult. 2945 // 2946 // Format placeholders that refer to more than one argument, or to a specific 2947 // argument, are not supported. This includes formats like "%1$d" or "%.*d". 2948 // 2949 // This function automatically preserves caller-saved registers so that 2950 // calling code can use Printf at any point without having to worry about 2951 // corruption. The preservation mechanism generates a lot of code. If this is 2952 // a problem, preserve the important registers manually and then call 2953 // PrintfNoPreserve. Callee-saved registers are not used by Printf, and are 2954 // implicitly preserved. 2955 void Printf(const char * format, 2956 CPURegister arg0 = NoCPUReg, 2957 CPURegister arg1 = NoCPUReg, 2958 CPURegister arg2 = NoCPUReg, 2959 CPURegister arg3 = NoCPUReg); 2960 2961 // Like Printf, but don't preserve any caller-saved registers, not even 'lr'. 2962 // 2963 // The return code from the system printf call will be returned in x0. 2964 void PrintfNoPreserve(const char * format, 2965 const CPURegister& arg0 = NoCPUReg, 2966 const CPURegister& arg1 = NoCPUReg, 2967 const CPURegister& arg2 = NoCPUReg, 2968 const CPURegister& arg3 = NoCPUReg); 2969 2970 // Trace control when running the debug simulator. 2971 // 2972 // For example: 2973 // 2974 // __ Trace(LOG_REGS, TRACE_ENABLE); 2975 // Will add registers to the trace if it wasn't already the case. 2976 // 2977 // __ Trace(LOG_DISASM, TRACE_DISABLE); 2978 // Will stop logging disassembly. It has no effect if the disassembly wasn't 2979 // already being logged. 2980 void Trace(TraceParameters parameters, TraceCommand command); 2981 2982 // Log the requested data independently of what is being traced. 2983 // 2984 // For example: 2985 // 2986 // __ Log(LOG_FLAGS) 2987 // Will output the flags. 2988 void Log(TraceParameters parameters); 2989 2990 // Enable or disable instrumentation when an Instrument visitor is attached to 2991 // the simulator. 2992 void EnableInstrumentation(); 2993 void DisableInstrumentation(); 2994 2995 // Add a marker to the instrumentation data produced by an Instrument visitor. 2996 // The name is a two character string that will be attached to the marker in 2997 // the output data. 2998 void AnnotateInstrumentation(const char* marker_name); 2999 3000 private: 3001 // The actual Push and Pop implementations. These don't generate any code 3002 // other than that required for the push or pop. This allows 3003 // (Push|Pop)CPURegList to bundle together setup code for a large block of 3004 // registers. 3005 // 3006 // Note that size is per register, and is specified in bytes. 3007 void PushHelper(int count, int size, 3008 const CPURegister& src0, const CPURegister& src1, 3009 const CPURegister& src2, const CPURegister& src3); 3010 void PopHelper(int count, int size, 3011 const CPURegister& dst0, const CPURegister& dst1, 3012 const CPURegister& dst2, const CPURegister& dst3); 3013 3014 void Movi16bitHelper(const VRegister& vd, uint64_t imm); 3015 void Movi32bitHelper(const VRegister& vd, uint64_t imm); 3016 void Movi64bitHelper(const VRegister& vd, uint64_t imm); 3017 3018 // Perform necessary maintenance operations before a push or pop. 3019 // 3020 // Note that size is per register, and is specified in bytes. 3021 void PrepareForPush(int count, int size); 3022 void PrepareForPop(int count, int size); 3023 3024 // The actual implementation of load and store operations for CPURegList. 3025 enum LoadStoreCPURegListAction { 3026 kLoad, 3027 kStore 3028 }; 3029 void LoadStoreCPURegListHelper(LoadStoreCPURegListAction operation, 3030 CPURegList registers, 3031 const MemOperand& mem); 3032 // Returns a MemOperand suitable for loading or storing a CPURegList at `dst`. 3033 // This helper may allocate registers from `scratch_scope` and generate code 3034 // to compute an intermediate address. The resulting MemOperand is only valid 3035 // as long as `scratch_scope` remains valid. 3036 MemOperand BaseMemOperandForLoadStoreCPURegList( 3037 const CPURegList& registers, 3038 const MemOperand& mem, 3039 UseScratchRegisterScope* scratch_scope); 3040 3041 bool LabelIsOutOfRange(Label* label, ImmBranchType branch_type) { 3042 return !Instruction::IsValidImmPCOffset(branch_type, 3043 label->location() - CursorOffset()); 3044 } 3045 3046 #if VIXL_DEBUG 3047 // Tell whether any of the macro instruction can be used. When false the 3048 // MacroAssembler will assert if a method which can emit a variable number 3049 // of instructions is called. 3050 bool allow_macro_instructions_; 3051 #endif 3052 3053 // The register to use as a stack pointer for stack operations. 3054 Register sp_; 3055 3056 // Scratch registers available for use by the MacroAssembler. 3057 CPURegList tmp_list_; 3058 CPURegList fptmp_list_; 3059 3060 LiteralPool literal_pool_; 3061 VeneerPool veneer_pool_; 3062 3063 ptrdiff_t checkpoint_; 3064 ptrdiff_t recommended_checkpoint_; 3065 3066 friend class Pool; 3067 friend class LiteralPool; 3068 }; 3069 3070 3071 inline size_t VeneerPool::OtherPoolsMaxSize() const { 3072 return masm_->LiteralPoolMaxSize(); 3073 } 3074 3075 3076 inline size_t LiteralPool::OtherPoolsMaxSize() const { 3077 return masm_->VeneerPoolMaxSize(); 3078 } 3079 3080 3081 inline void LiteralPool::SetNextRecommendedCheckpoint(ptrdiff_t offset) { 3082 masm_->recommended_checkpoint_ = 3083 std::min(masm_->recommended_checkpoint_, offset); 3084 recommended_checkpoint_ = offset; 3085 } 3086 3087 // Use this scope when you need a one-to-one mapping between methods and 3088 // instructions. This scope prevents the MacroAssembler from being called and 3089 // literal pools from being emitted. It also asserts the number of instructions 3090 // emitted is what you specified when creating the scope. 3091 class InstructionAccurateScope : public CodeBufferCheckScope { 3092 public: 3093 InstructionAccurateScope(MacroAssembler* masm, 3094 int count, 3095 AssertPolicy policy = kExactSize) 3096 : CodeBufferCheckScope(masm, 3097 (count * kInstructionSize), 3098 kCheck, 3099 policy) { 3100 VIXL_ASSERT(policy != kNoAssert); 3101 #ifdef VIXL_DEBUG 3102 old_allow_macro_instructions_ = masm->AllowMacroInstructions(); 3103 masm->SetAllowMacroInstructions(false); 3104 #endif 3105 } 3106 3107 ~InstructionAccurateScope() { 3108 #ifdef VIXL_DEBUG 3109 MacroAssembler* masm = reinterpret_cast<MacroAssembler*>(assm_); 3110 masm->SetAllowMacroInstructions(old_allow_macro_instructions_); 3111 #endif 3112 } 3113 3114 private: 3115 #ifdef VIXL_DEBUG 3116 bool old_allow_macro_instructions_; 3117 #endif 3118 }; 3119 3120 3121 class BlockLiteralPoolScope { 3122 public: 3123 explicit BlockLiteralPoolScope(MacroAssembler* masm) : masm_(masm) { 3124 masm_->BlockLiteralPool(); 3125 } 3126 3127 ~BlockLiteralPoolScope() { 3128 masm_->ReleaseLiteralPool(); 3129 } 3130 3131 private: 3132 MacroAssembler* masm_; 3133 }; 3134 3135 3136 class BlockVeneerPoolScope { 3137 public: 3138 explicit BlockVeneerPoolScope(MacroAssembler* masm) : masm_(masm) { 3139 masm_->BlockVeneerPool(); 3140 } 3141 3142 ~BlockVeneerPoolScope() { 3143 masm_->ReleaseVeneerPool(); 3144 } 3145 3146 private: 3147 MacroAssembler* masm_; 3148 }; 3149 3150 3151 class BlockPoolsScope { 3152 public: 3153 explicit BlockPoolsScope(MacroAssembler* masm) : masm_(masm) { 3154 masm_->BlockLiteralPool(); 3155 masm_->BlockVeneerPool(); 3156 } 3157 3158 ~BlockPoolsScope() { 3159 masm_->ReleaseLiteralPool(); 3160 masm_->ReleaseVeneerPool(); 3161 } 3162 3163 private: 3164 MacroAssembler* masm_; 3165 }; 3166 3167 3168 // This scope utility allows scratch registers to be managed safely. The 3169 // MacroAssembler's TmpList() (and FPTmpList()) is used as a pool of scratch 3170 // registers. These registers can be allocated on demand, and will be returned 3171 // at the end of the scope. 3172 // 3173 // When the scope ends, the MacroAssembler's lists will be restored to their 3174 // original state, even if the lists were modified by some other means. 3175 class UseScratchRegisterScope { 3176 public: 3177 // This constructor implicitly calls the `Open` function to initialise the 3178 // scope, so it is ready to use immediately after it has been constructed. 3179 explicit UseScratchRegisterScope(MacroAssembler* masm); 3180 // This constructor allows deferred and optional initialisation of the scope. 3181 // The user is required to explicitly call the `Open` function before using 3182 // the scope. 3183 UseScratchRegisterScope(); 3184 // This function performs the actual initialisation work. 3185 void Open(MacroAssembler* masm); 3186 3187 // The destructor always implicitly calls the `Close` function. 3188 ~UseScratchRegisterScope(); 3189 // This function performs the cleaning-up work. It must succeed even if the 3190 // scope has not been opened. It is safe to call multiple times. 3191 void Close(); 3192 3193 3194 bool IsAvailable(const CPURegister& reg) const; 3195 3196 3197 // Take a register from the appropriate temps list. It will be returned 3198 // automatically when the scope ends. 3199 Register AcquireW() { return AcquireNextAvailable(available_).W(); } 3200 Register AcquireX() { return AcquireNextAvailable(available_).X(); } 3201 VRegister AcquireS() { return AcquireNextAvailable(availablefp_).S(); } 3202 VRegister AcquireD() { return AcquireNextAvailable(availablefp_).D(); } 3203 3204 3205 Register AcquireSameSizeAs(const Register& reg); 3206 VRegister AcquireSameSizeAs(const VRegister& reg); 3207 3208 3209 // Explicitly release an acquired (or excluded) register, putting it back in 3210 // the appropriate temps list. 3211 void Release(const CPURegister& reg); 3212 3213 3214 // Make the specified registers available as scratch registers for the 3215 // duration of this scope. 3216 void Include(const CPURegList& list); 3217 void Include(const Register& reg1, 3218 const Register& reg2 = NoReg, 3219 const Register& reg3 = NoReg, 3220 const Register& reg4 = NoReg); 3221 void Include(const VRegister& reg1, 3222 const VRegister& reg2 = NoVReg, 3223 const VRegister& reg3 = NoVReg, 3224 const VRegister& reg4 = NoVReg); 3225 3226 3227 // Make sure that the specified registers are not available in this scope. 3228 // This can be used to prevent helper functions from using sensitive 3229 // registers, for example. 3230 void Exclude(const CPURegList& list); 3231 void Exclude(const Register& reg1, 3232 const Register& reg2 = NoReg, 3233 const Register& reg3 = NoReg, 3234 const Register& reg4 = NoReg); 3235 void Exclude(const VRegister& reg1, 3236 const VRegister& reg2 = NoVReg, 3237 const VRegister& reg3 = NoVReg, 3238 const VRegister& reg4 = NoVReg); 3239 void Exclude(const CPURegister& reg1, 3240 const CPURegister& reg2 = NoCPUReg, 3241 const CPURegister& reg3 = NoCPUReg, 3242 const CPURegister& reg4 = NoCPUReg); 3243 3244 3245 // Prevent any scratch registers from being used in this scope. 3246 void ExcludeAll(); 3247 3248 3249 private: 3250 static CPURegister AcquireNextAvailable(CPURegList* available); 3251 3252 static void ReleaseByCode(CPURegList* available, int code); 3253 3254 static void ReleaseByRegList(CPURegList* available, 3255 RegList regs); 3256 3257 static void IncludeByRegList(CPURegList* available, 3258 RegList exclude); 3259 3260 static void ExcludeByRegList(CPURegList* available, 3261 RegList exclude); 3262 3263 // Available scratch registers. 3264 CPURegList* available_; // kRegister 3265 CPURegList* availablefp_; // kVRegister 3266 3267 // The state of the available lists at the start of this scope. 3268 RegList old_available_; // kRegister 3269 RegList old_availablefp_; // kVRegister 3270 #ifdef VIXL_DEBUG 3271 bool initialised_; 3272 #endif 3273 3274 // Disallow copy constructor and operator=. 3275 UseScratchRegisterScope(const UseScratchRegisterScope&) { 3276 VIXL_UNREACHABLE(); 3277 } 3278 void operator=(const UseScratchRegisterScope&) { 3279 VIXL_UNREACHABLE(); 3280 } 3281 }; 3282 3283 3284 } // namespace vixl 3285 3286 #endif // VIXL_A64_MACRO_ASSEMBLER_A64_H_ 3287