1// Copyright 2015, VIXL authors 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_AARCH64_MACRO_ASSEMBLER_AARCH64_H_ 28#define VIXL_AARCH64_MACRO_ASSEMBLER_AARCH64_H_ 29 30#include <algorithm> 31#include <limits> 32 33#include "../code-generation-scopes-vixl.h" 34#include "../globals-vixl.h" 35#include "../macro-assembler-interface.h" 36 37#include "assembler-aarch64.h" 38// Required for runtime call support. 39// TODO: Break this dependency. We should be able to separate out the necessary 40// parts so that we don't need to include the whole simulator header. 41#include "simulator-aarch64.h" 42// Required in order to generate debugging instructions for the simulator. This 43// is needed regardless of whether the simulator is included or not, since 44// generating simulator specific instructions is controlled at runtime. 45#include "simulator-constants-aarch64.h" 46 47 48#define LS_MACRO_LIST(V) \ 49 V(Ldrb, Register&, rt, LDRB_w) \ 50 V(Strb, Register&, rt, STRB_w) \ 51 V(Ldrsb, Register&, rt, rt.Is64Bits() ? LDRSB_x : LDRSB_w) \ 52 V(Ldrh, Register&, rt, LDRH_w) \ 53 V(Strh, Register&, rt, STRH_w) \ 54 V(Ldrsh, Register&, rt, rt.Is64Bits() ? LDRSH_x : LDRSH_w) \ 55 V(Ldr, CPURegister&, rt, LoadOpFor(rt)) \ 56 V(Str, CPURegister&, rt, StoreOpFor(rt)) \ 57 V(Ldrsw, Register&, rt, LDRSW_x) 58 59 60#define LSPAIR_MACRO_LIST(V) \ 61 V(Ldp, CPURegister&, rt, rt2, LoadPairOpFor(rt, rt2)) \ 62 V(Stp, CPURegister&, rt, rt2, StorePairOpFor(rt, rt2)) \ 63 V(Ldpsw, Register&, rt, rt2, LDPSW_x) 64 65namespace vixl { 66namespace aarch64 { 67 68// Forward declaration 69class MacroAssembler; 70class UseScratchRegisterScope; 71 72class Pool { 73 public: 74 explicit Pool(MacroAssembler* masm) 75 : checkpoint_(kNoCheckpointRequired), masm_(masm) { 76 Reset(); 77 } 78 79 void Reset() { 80 checkpoint_ = kNoCheckpointRequired; 81 monitor_ = 0; 82 } 83 84 void Block() { monitor_++; } 85 void Release(); 86 bool IsBlocked() const { return monitor_ != 0; } 87 88 static const ptrdiff_t kNoCheckpointRequired = PTRDIFF_MAX; 89 90 void SetNextCheckpoint(ptrdiff_t checkpoint); 91 ptrdiff_t GetCheckpoint() const { return checkpoint_; } 92 VIXL_DEPRECATED("GetCheckpoint", ptrdiff_t checkpoint() const) { 93 return GetCheckpoint(); 94 } 95 96 enum EmitOption { kBranchRequired, kNoBranchRequired }; 97 98 protected: 99 // Next buffer offset at which a check is required for this pool. 100 ptrdiff_t checkpoint_; 101 // Indicates whether the emission of this pool is blocked. 102 int monitor_; 103 // The MacroAssembler using this pool. 104 MacroAssembler* masm_; 105}; 106 107 108class LiteralPool : public Pool { 109 public: 110#ifndef PANDA_BUILD 111 explicit LiteralPool(MacroAssembler* masm); 112#else 113 explicit LiteralPool(MacroAssembler* masm) = delete; 114 LiteralPool(AllocatorWrapper allocator, MacroAssembler* masm); 115#endif 116 ~LiteralPool() VIXL_NEGATIVE_TESTING_ALLOW_EXCEPTION; 117 void Reset(); 118 119 void AddEntry(RawLiteral* literal); 120 bool IsEmpty() const { return entries_.empty(); } 121 size_t GetSize() const; 122 VIXL_DEPRECATED("GetSize", size_t Size() const) { return GetSize(); } 123 124 size_t GetMaxSize() const; 125 VIXL_DEPRECATED("GetMaxSize", size_t MaxSize() const) { return GetMaxSize(); } 126 127 size_t GetOtherPoolsMaxSize() const; 128 VIXL_DEPRECATED("GetOtherPoolsMaxSize", size_t OtherPoolsMaxSize() const) { 129 return GetOtherPoolsMaxSize(); 130 } 131 132 void CheckEmitFor(size_t amount, EmitOption option = kBranchRequired); 133 // Check whether we need to emit the literal pool in order to be able to 134 // safely emit a branch with a given range. 135 void CheckEmitForBranch(size_t range); 136 void Emit(EmitOption option = kNoBranchRequired); 137 138 void SetNextRecommendedCheckpoint(ptrdiff_t offset); 139 ptrdiff_t GetNextRecommendedCheckpoint(); 140 VIXL_DEPRECATED("GetNextRecommendedCheckpoint", 141 ptrdiff_t NextRecommendedCheckpoint()) { 142 return GetNextRecommendedCheckpoint(); 143 } 144 145 void UpdateFirstUse(ptrdiff_t use_position); 146 147 void DeleteOnDestruction(RawLiteral* literal) { 148 deleted_on_destruction_.push_back(literal); 149 } 150 151 // Recommended not exact since the pool can be blocked for short periods. 152 static const ptrdiff_t kRecommendedLiteralPoolRange = 128 * KBytes; 153 154 private: 155#ifndef PANDA_BUILD 156 std::vector<RawLiteral*> entries_; 157#else 158 Vector<RawLiteral*> entries_; 159#endif 160 size_t size_; 161 ptrdiff_t first_use_; 162 // The parent class `Pool` provides a `checkpoint_`, which is the buffer 163 // offset before which a check *must* occur. This recommended checkpoint 164 // indicates when we would like to start emitting the constant pool. The 165 // MacroAssembler can, but does not have to, check the buffer when the 166 // checkpoint is reached. 167 ptrdiff_t recommended_checkpoint_; 168 169#ifndef PANDA_BUILD 170 std::vector<RawLiteral*> deleted_on_destruction_; 171#else 172 Vector<RawLiteral*> deleted_on_destruction_; 173 AllocatorWrapper allocator_; 174#endif 175}; 176 177 178inline size_t LiteralPool::GetSize() const { 179 // Account for the pool header. 180 return size_ + kInstructionSize; 181} 182 183 184inline size_t LiteralPool::GetMaxSize() const { 185 // Account for the potential branch over the pool. 186 return GetSize() + kInstructionSize; 187} 188 189 190inline ptrdiff_t LiteralPool::GetNextRecommendedCheckpoint() { 191 return first_use_ + kRecommendedLiteralPoolRange; 192} 193 194 195class VeneerPool : public Pool { 196 public: 197#ifndef PANDA_BUILD 198 explicit VeneerPool(MacroAssembler* masm) : Pool(masm) {} 199#else 200explicit VeneerPool(MacroAssembler* masm) = delete; 201VeneerPool(AllocatorWrapper allocator, MacroAssembler* masm) : Pool(masm), unresolved_branches_(allocator), allocator_(allocator) {} 202#endif 203 void Reset(); 204 205 void Block() { monitor_++; } 206 void Release(); 207 bool IsBlocked() const { return monitor_ != 0; } 208 bool IsEmpty() const { return unresolved_branches_.IsEmpty(); } 209 210 class BranchInfo { 211 public: 212 BranchInfo() 213 : first_unreacheable_pc_(0), 214 pc_offset_(0), 215 label_(NULL), 216 branch_type_(UnknownBranchType) {} 217 BranchInfo(ptrdiff_t offset, Label* label, ImmBranchType branch_type) 218 : pc_offset_(offset), label_(label), branch_type_(branch_type) { 219 first_unreacheable_pc_ = 220 pc_offset_ + Instruction::GetImmBranchForwardRange(branch_type_); 221 } 222 223 static bool IsValidComparison(const BranchInfo& branch_1, 224 const BranchInfo& branch_2) { 225 // BranchInfo are always compared against against other objects with 226 // the same branch type. 227 if (branch_1.branch_type_ != branch_2.branch_type_) { 228 return false; 229 } 230 // Since we should never have two branch infos with the same offsets, it 231 // first looks like we should check that offsets are different. However 232 // the operators may also be used to *search* for a branch info in the 233 // set. 234 bool same_offsets = (branch_1.pc_offset_ == branch_2.pc_offset_); 235 return (!same_offsets || ((branch_1.label_ == branch_2.label_) && 236 (branch_1.first_unreacheable_pc_ == 237 branch_2.first_unreacheable_pc_))); 238 } 239 240 // We must provide comparison operators to work with InvalSet. 241 bool operator==(const BranchInfo& other) const { 242 VIXL_ASSERT(IsValidComparison(*this, other)); 243 return pc_offset_ == other.pc_offset_; 244 } 245 bool operator<(const BranchInfo& other) const { 246 VIXL_ASSERT(IsValidComparison(*this, other)); 247 return pc_offset_ < other.pc_offset_; 248 } 249 bool operator<=(const BranchInfo& other) const { 250 VIXL_ASSERT(IsValidComparison(*this, other)); 251 return pc_offset_ <= other.pc_offset_; 252 } 253 bool operator>(const BranchInfo& other) const { 254 VIXL_ASSERT(IsValidComparison(*this, other)); 255 return pc_offset_ > other.pc_offset_; 256 } 257 258 // First instruction position that is not reachable by the branch using a 259 // positive branch offset. 260 ptrdiff_t first_unreacheable_pc_; 261 // Offset of the branch in the code generation buffer. 262 ptrdiff_t pc_offset_; 263 // The label branched to. 264 Label* label_; 265 ImmBranchType branch_type_; 266 }; 267 268 bool BranchTypeUsesVeneers(ImmBranchType type) { 269 return (type != UnknownBranchType) && (type != UncondBranchType); 270 } 271 272 void RegisterUnresolvedBranch(ptrdiff_t branch_pos, 273 Label* label, 274 ImmBranchType branch_type); 275 void DeleteUnresolvedBranchInfoForLabel(Label* label); 276 277 bool ShouldEmitVeneer(int64_t first_unreacheable_pc, size_t amount); 278 bool ShouldEmitVeneers(size_t amount) { 279 return ShouldEmitVeneer(unresolved_branches_.GetFirstLimit(), amount); 280 } 281 282 void CheckEmitFor(size_t amount, EmitOption option = kBranchRequired); 283 void Emit(EmitOption option, size_t margin); 284 285 // The code size generated for a veneer. Currently one branch instruction. 286 // This is for code size checking purposes, and can be extended in the future 287 // for example if we decide to add nops between the veneers. 288 static const int kVeneerCodeSize = 1 * kInstructionSize; 289 // The maximum size of code other than veneers that can be generated when 290 // emitting a veneer pool. Currently there can be an additional branch to jump 291 // over the pool. 292 static const int kPoolNonVeneerCodeSize = 1 * kInstructionSize; 293 294 void UpdateNextCheckPoint() { SetNextCheckpoint(GetNextCheckPoint()); } 295 296 int GetNumberOfPotentialVeneers() const { 297 return static_cast<int>(unresolved_branches_.GetSize()); 298 } 299 VIXL_DEPRECATED("GetNumberOfPotentialVeneers", 300 int NumberOfPotentialVeneers() const) { 301 return GetNumberOfPotentialVeneers(); 302 } 303 304 size_t GetMaxSize() const { 305 return kPoolNonVeneerCodeSize + 306 unresolved_branches_.GetSize() * kVeneerCodeSize; 307 } 308 VIXL_DEPRECATED("GetMaxSize", size_t MaxSize() const) { return GetMaxSize(); } 309 310 size_t GetOtherPoolsMaxSize() const; 311 VIXL_DEPRECATED("GetOtherPoolsMaxSize", size_t OtherPoolsMaxSize() const) { 312 return GetOtherPoolsMaxSize(); 313 } 314 315 static const int kNPreallocatedInfos = 4; 316 static const ptrdiff_t kInvalidOffset = PTRDIFF_MAX; 317 static const size_t kReclaimFrom = 128; 318 static const size_t kReclaimFactor = 16; 319 320 private: 321 typedef InvalSet<BranchInfo, 322 kNPreallocatedInfos, 323 ptrdiff_t, 324 kInvalidOffset, 325 kReclaimFrom, 326 kReclaimFactor> 327 BranchInfoTypedSetBase; 328 typedef InvalSetIterator<BranchInfoTypedSetBase> BranchInfoTypedSetIterBase; 329 330 class BranchInfoTypedSet : public BranchInfoTypedSetBase { 331 public: 332#ifndef PANDA_BUILD 333 BranchInfoTypedSet() : BranchInfoTypedSetBase() {} 334#else 335 BranchInfoTypedSet() = delete; 336 explicit BranchInfoTypedSet(AllocatorWrapper alloc) : BranchInfoTypedSetBase(alloc) {} 337 BranchInfoTypedSet(BranchInfoTypedSet&&) = default; 338#endif 339 ptrdiff_t GetFirstLimit() { 340 if (empty()) { 341 return kInvalidOffset; 342 } 343 return GetMinElementKey(); 344 } 345 VIXL_DEPRECATED("GetFirstLimit", ptrdiff_t FirstLimit()) { 346 return GetFirstLimit(); 347 } 348 }; 349 350 class BranchInfoTypedSetIterator : public BranchInfoTypedSetIterBase { 351 public: 352 BranchInfoTypedSetIterator() : BranchInfoTypedSetIterBase(NULL) {} 353 explicit BranchInfoTypedSetIterator(BranchInfoTypedSet* typed_set) 354 : BranchInfoTypedSetIterBase(typed_set) {} 355 356 // TODO: Remove these and use the STL-like interface instead. 357 using BranchInfoTypedSetIterBase::Advance; 358 using BranchInfoTypedSetIterBase::Current; 359 }; 360 361 class BranchInfoSet { 362 public: 363#ifdef PANDA_BUILD 364 BranchInfoSet() = delete; 365 BranchInfoSet(AllocatorWrapper allocator) : 366 typed_set_(allocator.Adapter()) { 367 typed_set_.reserve(3); 368 typed_set_.emplace_back((allocator)); 369 typed_set_.emplace_back((allocator)); 370 typed_set_.emplace_back((allocator)); 371 }; 372#endif 373 void insert(BranchInfo branch_info) { 374 ImmBranchType type = branch_info.branch_type_; 375 VIXL_ASSERT(IsValidBranchType(type)); 376 typed_set_[BranchIndexFromType(type)].insert(branch_info); 377 } 378 379 void erase(BranchInfo branch_info) { 380 if (IsValidBranchType(branch_info.branch_type_)) { 381 int index = 382 BranchInfoSet::BranchIndexFromType(branch_info.branch_type_); 383 typed_set_[index].erase(branch_info); 384 } 385 } 386 387 size_t GetSize() const { 388 size_t res = 0; 389 for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) { 390 res += typed_set_[i].size(); 391 } 392 return res; 393 } 394 VIXL_DEPRECATED("GetSize", size_t size() const) { return GetSize(); } 395 396 bool IsEmpty() const { 397 for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) { 398 if (!typed_set_[i].empty()) { 399 return false; 400 } 401 } 402 return true; 403 } 404 VIXL_DEPRECATED("IsEmpty", bool empty() const) { return IsEmpty(); } 405 406 ptrdiff_t GetFirstLimit() { 407 ptrdiff_t res = kInvalidOffset; 408 for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) { 409 res = std::min(res, typed_set_[i].GetFirstLimit()); 410 } 411 return res; 412 } 413 VIXL_DEPRECATED("GetFirstLimit", ptrdiff_t FirstLimit()) { 414 return GetFirstLimit(); 415 } 416 417 void Reset() { 418 for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) { 419 typed_set_[i].clear(); 420 } 421 } 422 423 static ImmBranchType BranchTypeFromIndex(int index) { 424 switch (index) { 425 case 0: 426 return CondBranchType; 427 case 1: 428 return CompareBranchType; 429 case 2: 430 return TestBranchType; 431 default: 432 VIXL_UNREACHABLE(); 433 return UnknownBranchType; 434 } 435 } 436 static int BranchIndexFromType(ImmBranchType branch_type) { 437 switch (branch_type) { 438 case CondBranchType: 439 return 0; 440 case CompareBranchType: 441 return 1; 442 case TestBranchType: 443 return 2; 444 default: 445 VIXL_UNREACHABLE(); 446 return 0; 447 } 448 } 449 450 bool IsValidBranchType(ImmBranchType branch_type) { 451 return (branch_type != UnknownBranchType) && 452 (branch_type != UncondBranchType); 453 } 454 455 private: 456 static const int kNumberOfTrackedBranchTypes = 3; 457#ifndef PANDA_BUILD 458 BranchInfoTypedSet typed_set_[kNumberOfTrackedBranchTypes]; 459#else 460 Vector<BranchInfoTypedSet> typed_set_; 461#endif 462 friend class VeneerPool; 463 friend class BranchInfoSetIterator; 464 }; 465 466 class BranchInfoSetIterator { 467 public: 468#ifndef PANDA_BUILD 469 explicit BranchInfoSetIterator(BranchInfoSet* set) : set_(set) { 470 for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) { 471 new (&sub_iterator_[i]) 472 BranchInfoTypedSetIterator(&(set_->typed_set_[i])); 473 } 474 } 475#else 476 explicit BranchInfoSetIterator(BranchInfoSet* set) = delete; 477 BranchInfoSetIterator(AllocatorWrapper allocator, BranchInfoSet* set) : set_(set), sub_iterator_(allocator.Adapter()) { 478 for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) { 479 sub_iterator_.emplace_back(&(set_->typed_set_[i])); 480 } 481 } 482 483#endif 484 485 VeneerPool::BranchInfo* Current() { 486 for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) { 487 if (!sub_iterator_[i].Done()) { 488 return sub_iterator_[i].Current(); 489 } 490 } 491 VIXL_UNREACHABLE(); 492 return NULL; 493 } 494 495 void Advance() { 496 VIXL_ASSERT(!Done()); 497 for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) { 498 if (!sub_iterator_[i].Done()) { 499 sub_iterator_[i].Advance(); 500 return; 501 } 502 } 503 VIXL_UNREACHABLE(); 504 } 505 506 bool Done() const { 507 for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) { 508 if (!sub_iterator_[i].Done()) return false; 509 } 510 return true; 511 } 512 513 void AdvanceToNextType() { 514 VIXL_ASSERT(!Done()); 515 for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) { 516 if (!sub_iterator_[i].Done()) { 517 sub_iterator_[i].Finish(); 518 return; 519 } 520 } 521 VIXL_UNREACHABLE(); 522 } 523 524 void DeleteCurrentAndAdvance() { 525 for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) { 526 if (!sub_iterator_[i].Done()) { 527 sub_iterator_[i].DeleteCurrentAndAdvance(); 528 return; 529 } 530 } 531 } 532 533 private: 534 BranchInfoSet* set_; 535#ifndef PANDA_BUILD 536 BranchInfoTypedSetIterator 537 sub_iterator_[BranchInfoSet::kNumberOfTrackedBranchTypes]; 538#else 539 Vector<BranchInfoTypedSetIterator> sub_iterator_; 540#endif 541 }; 542 543 ptrdiff_t GetNextCheckPoint() { 544 if (unresolved_branches_.IsEmpty()) { 545 return kNoCheckpointRequired; 546 } else { 547 return unresolved_branches_.GetFirstLimit(); 548 } 549 } 550 VIXL_DEPRECATED("GetNextCheckPoint", ptrdiff_t NextCheckPoint()) { 551 return GetNextCheckPoint(); 552 } 553 554 // Information about unresolved (forward) branches. 555 BranchInfoSet unresolved_branches_; 556#ifdef PANDA_BUILD 557 AllocatorWrapper allocator_; 558#endif 559}; 560 561 562// Helper for common Emission checks. 563// The macro-instruction maps to a single instruction. 564class SingleEmissionCheckScope : public EmissionCheckScope { 565 public: 566 explicit SingleEmissionCheckScope(MacroAssemblerInterface* masm) 567 : EmissionCheckScope(masm, kInstructionSize) {} 568}; 569 570 571// The macro instruction is a "typical" macro-instruction. Typical macro- 572// instruction only emit a few instructions, a few being defined as 8 here. 573class MacroEmissionCheckScope : public EmissionCheckScope { 574 public: 575 explicit MacroEmissionCheckScope(MacroAssemblerInterface* masm) 576 : EmissionCheckScope(masm, kTypicalMacroInstructionMaxSize) {} 577 578 private: 579 static const size_t kTypicalMacroInstructionMaxSize = 8 * kInstructionSize; 580}; 581 582 583// This scope simplifies the handling of the SVE `movprfx` instruction. 584// 585// If dst.Aliases(src): 586// - Start an ExactAssemblyScope(masm, kInstructionSize). 587// Otherwise: 588// - Start an ExactAssemblyScope(masm, 2 * kInstructionSize). 589// - Generate a suitable `movprfx` instruction. 590// 591// In both cases, the ExactAssemblyScope is left with enough remaining space for 592// exactly one destructive instruction. 593class MovprfxHelperScope : public ExactAssemblyScope { 594 public: 595 inline MovprfxHelperScope(MacroAssembler* masm, 596 const ZRegister& dst, 597 const ZRegister& src); 598 599 inline MovprfxHelperScope(MacroAssembler* masm, 600 const ZRegister& dst, 601 const PRegister& pg, 602 const ZRegister& src); 603 604 // TODO: Implement constructors that examine _all_ sources. If `dst` aliases 605 // any other source register, we can't use `movprfx`. This isn't obviously 606 // useful, but the MacroAssembler should not generate invalid code for it. 607 // Valid behaviour can be implemented using `mov`. 608 // 609 // The best way to handle this in an instruction-agnostic way is probably to 610 // use variadic templates. 611 612 private: 613 inline bool ShouldGenerateMovprfx(const ZRegister& dst, 614 const ZRegister& src) { 615 VIXL_ASSERT(AreSameLaneSize(dst, src)); 616 return !dst.Aliases(src); 617 } 618 619 inline bool ShouldGenerateMovprfx(const ZRegister& dst, 620 const PRegister& pg, 621 const ZRegister& src) { 622 VIXL_ASSERT(pg.IsMerging() || pg.IsZeroing()); 623 // We need to emit movprfx in two cases: 624 // 1. To give a predicated merging unary instruction zeroing predication. 625 // 2. To make destructive instructions constructive. 626 // 627 // There are no predicated zeroing instructions that can take movprfx, so we 628 // will never generate an unnecessary movprfx with this logic. 629 return pg.IsZeroing() || ShouldGenerateMovprfx(dst, src); 630 } 631}; 632 633 634enum BranchType { 635 // Copies of architectural conditions. 636 // The associated conditions can be used in place of those, the code will 637 // take care of reinterpreting them with the correct type. 638 integer_eq = eq, 639 integer_ne = ne, 640 integer_hs = hs, 641 integer_lo = lo, 642 integer_mi = mi, 643 integer_pl = pl, 644 integer_vs = vs, 645 integer_vc = vc, 646 integer_hi = hi, 647 integer_ls = ls, 648 integer_ge = ge, 649 integer_lt = lt, 650 integer_gt = gt, 651 integer_le = le, 652 integer_al = al, 653 integer_nv = nv, 654 655 // These two are *different* from the architectural codes al and nv. 656 // 'always' is used to generate unconditional branches. 657 // 'never' is used to not generate a branch (generally as the inverse 658 // branch type of 'always). 659 always, 660 never, 661 // cbz and cbnz 662 reg_zero, 663 reg_not_zero, 664 // tbz and tbnz 665 reg_bit_clear, 666 reg_bit_set, 667 668 // Aliases. 669 kBranchTypeFirstCondition = eq, 670 kBranchTypeLastCondition = nv, 671 kBranchTypeFirstUsingReg = reg_zero, 672 kBranchTypeFirstUsingBit = reg_bit_clear, 673 674 // SVE branch conditions. 675 integer_none = eq, 676 integer_any = ne, 677 integer_nlast = cs, 678 integer_last = cc, 679 integer_first = mi, 680 integer_nfrst = pl, 681 integer_pmore = hi, 682 integer_plast = ls, 683 integer_tcont = ge, 684 integer_tstop = lt 685}; 686 687 688enum DiscardMoveMode { kDontDiscardForSameWReg, kDiscardForSameWReg }; 689 690// The macro assembler supports moving automatically pre-shifted immediates for 691// arithmetic and logical instructions, and then applying a post shift in the 692// instruction to undo the modification, in order to reduce the code emitted for 693// an operation. For example: 694// 695// Add(x0, x0, 0x1f7de) => movz x16, 0xfbef; add x0, x0, x16, lsl #1. 696// 697// This optimisation can be only partially applied when the stack pointer is an 698// operand or destination, so this enumeration is used to control the shift. 699enum PreShiftImmMode { 700 kNoShift, // Don't pre-shift. 701 kLimitShiftForSP, // Limit pre-shift for add/sub extend use. 702 kAnyShift // Allow any pre-shift. 703}; 704 705enum FPMacroNaNPropagationOption { 706 // The default option. This generates a run-time error in macros that respect 707 // this option. 708 NoFPMacroNaNPropagationSelected, 709 // For example, Fmin(result, NaN(a), NaN(b)) always selects NaN(a) if both 710 // NaN(a) and NaN(b) are both quiet, or both are signalling, at the 711 // cost of extra code generation in some cases. 712 StrictNaNPropagation, 713 // For example, Fmin(result, NaN(a), NaN(b)) selects either NaN, but using the 714 // fewest instructions. 715 FastNaNPropagation 716}; 717 718class MacroAssembler : public Assembler, public MacroAssemblerInterface { 719 public: 720#ifdef PANDA_BUILD 721 explicit MacroAssembler(PandaAllocator* allocator, 722 PositionIndependentCodeOption pic = PositionIndependentCode); 723#else 724 explicit MacroAssembler( 725 PositionIndependentCodeOption pic = PositionIndependentCode); 726#endif 727#ifdef PANDA_BUILD 728 MacroAssembler(size_t capacity, 729 PositionIndependentCodeOption pic = PositionIndependentCode) = delete; 730#else 731 MacroAssembler(size_t capacity, 732 PositionIndependentCodeOption pic = PositionIndependentCode); 733#endif 734#ifndef PANDA_BUILD 735 MacroAssembler(byte* buffer, 736 size_t capacity, 737 PositionIndependentCodeOption pic = PositionIndependentCode); 738#else 739MacroAssembler(PandaAllocator* allocator, byte* buffer, 740 size_t capacity, 741 PositionIndependentCodeOption pic = PositionIndependentCode); 742#endif 743 ~MacroAssembler(); 744 745 enum FinalizeOption { 746 kFallThrough, // There may be more code to execute after calling Finalize. 747 kUnreachable // Anything generated after calling Finalize is unreachable. 748 }; 749 750 virtual vixl::internal::AssemblerBase* AsAssemblerBase() VIXL_OVERRIDE { 751 return this; 752 } 753 754 // TODO(pools): implement these functions. 755 virtual void EmitPoolHeader() VIXL_OVERRIDE {} 756 virtual void EmitPoolFooter() VIXL_OVERRIDE {} 757 virtual void EmitPaddingBytes(int n) VIXL_OVERRIDE { USE(n); } 758 virtual void EmitNopBytes(int n) VIXL_OVERRIDE { USE(n); } 759 760 // Start generating code from the beginning of the buffer, discarding any code 761 // and data that has already been emitted into the buffer. 762 // 763 // In order to avoid any accidental transfer of state, Reset ASSERTs that the 764 // constant pool is not blocked. 765 void Reset(); 766 767 // Finalize a code buffer of generated instructions. This function must be 768 // called before executing or copying code from the buffer. By default, 769 // anything generated after this should not be reachable (the last instruction 770 // generated is an unconditional branch). If you need to generate more code, 771 // then set `option` to kFallThrough. 772 void FinalizeCode(FinalizeOption option = kUnreachable); 773 774 775 // Constant generation helpers. 776 // These functions return the number of instructions required to move the 777 // immediate into the destination register. Also, if the masm pointer is 778 // non-null, it generates the code to do so. 779 // The two features are implemented using one function to avoid duplication of 780 // the logic. 781 // The function can be used to evaluate the cost of synthesizing an 782 // instruction using 'mov immediate' instructions. A user might prefer loading 783 // a constant using the literal pool instead of using multiple 'mov immediate' 784 // instructions. 785 static int MoveImmediateHelper(MacroAssembler* masm, 786 const Register& rd, 787 uint64_t imm); 788 789 790 // Logical macros. 791 void And(const Register& rd, const Register& rn, const Operand& operand); 792 void Ands(const Register& rd, const Register& rn, const Operand& operand); 793 void Bic(const Register& rd, const Register& rn, const Operand& operand); 794 void Bics(const Register& rd, const Register& rn, const Operand& operand); 795 void Orr(const Register& rd, const Register& rn, const Operand& operand); 796 void Orn(const Register& rd, const Register& rn, const Operand& operand); 797 void Eor(const Register& rd, const Register& rn, const Operand& operand); 798 void Eon(const Register& rd, const Register& rn, const Operand& operand); 799 void Tst(const Register& rn, const Operand& operand); 800 void LogicalMacro(const Register& rd, 801 const Register& rn, 802 const Operand& operand, 803 LogicalOp op); 804 805 // Add and sub macros. 806 void Add(const Register& rd, 807 const Register& rn, 808 const Operand& operand, 809 FlagsUpdate S = LeaveFlags); 810 void Adds(const Register& rd, const Register& rn, const Operand& operand); 811 void Sub(const Register& rd, 812 const Register& rn, 813 const Operand& operand, 814 FlagsUpdate S = LeaveFlags); 815 void Subs(const Register& rd, const Register& rn, const Operand& operand); 816 void Cmn(const Register& rn, const Operand& operand); 817 void Cmp(const Register& rn, const Operand& operand); 818 void Neg(const Register& rd, const Operand& operand); 819 void Negs(const Register& rd, const Operand& operand); 820 821 void AddSubMacro(const Register& rd, 822 const Register& rn, 823 const Operand& operand, 824 FlagsUpdate S, 825 AddSubOp op); 826 827 // Add/sub with carry macros. 828 void Adc(const Register& rd, const Register& rn, const Operand& operand); 829 void Adcs(const Register& rd, const Register& rn, const Operand& operand); 830 void Sbc(const Register& rd, const Register& rn, const Operand& operand); 831 void Sbcs(const Register& rd, const Register& rn, const Operand& operand); 832 void Ngc(const Register& rd, const Operand& operand); 833 void Ngcs(const Register& rd, const Operand& operand); 834 void AddSubWithCarryMacro(const Register& rd, 835 const Register& rn, 836 const Operand& operand, 837 FlagsUpdate S, 838 AddSubWithCarryOp op); 839 840 void Rmif(const Register& xn, unsigned shift, StatusFlags flags); 841 void Setf8(const Register& wn); 842 void Setf16(const Register& wn); 843 844 // Move macros. 845 void Mov(const Register& rd, uint64_t imm); 846 void Mov(const Register& rd, 847 const Operand& operand, 848 DiscardMoveMode discard_mode = kDontDiscardForSameWReg); 849 void Mvn(const Register& rd, uint64_t imm) { 850 Mov(rd, (rd.GetSizeInBits() == kXRegSize) ? ~imm : (~imm & kWRegMask)); 851 } 852 void Mvn(const Register& rd, const Operand& operand); 853 854 // Try to move an immediate into the destination register in a single 855 // instruction. Returns true for success, and updates the contents of dst. 856 // Returns false, otherwise. 857 bool TryOneInstrMoveImmediate(const Register& dst, uint64_t imm); 858 859 // Move an immediate into register dst, and return an Operand object for 860 // use with a subsequent instruction that accepts a shift. The value moved 861 // into dst is not necessarily equal to imm; it may have had a shifting 862 // operation applied to it that will be subsequently undone by the shift 863 // applied in the Operand. 864 Operand MoveImmediateForShiftedOp(const Register& dst, 865 uint64_t imm, 866 PreShiftImmMode mode); 867 868 void Move(const GenericOperand& dst, const GenericOperand& src); 869 870 // Synthesises the address represented by a MemOperand into a register. 871 void ComputeAddress(const Register& dst, const MemOperand& mem_op); 872 873 // Conditional macros. 874 void Ccmp(const Register& rn, 875 const Operand& operand, 876 StatusFlags nzcv, 877 Condition cond); 878 void Ccmn(const Register& rn, 879 const Operand& operand, 880 StatusFlags nzcv, 881 Condition cond); 882 void ConditionalCompareMacro(const Register& rn, 883 const Operand& operand, 884 StatusFlags nzcv, 885 Condition cond, 886 ConditionalCompareOp op); 887 888 // On return, the boolean values pointed to will indicate whether `left` and 889 // `right` should be synthesised in a temporary register. 890 static void GetCselSynthesisInformation(const Register& rd, 891 const Operand& left, 892 const Operand& right, 893 bool* should_synthesise_left, 894 bool* should_synthesise_right) { 895 // Note that the helper does not need to look at the condition. 896 CselHelper(NULL, 897 rd, 898 left, 899 right, 900 eq, 901 should_synthesise_left, 902 should_synthesise_right); 903 } 904 905 void Csel(const Register& rd, 906 const Operand& left, 907 const Operand& right, 908 Condition cond) { 909 CselHelper(this, rd, left, right, cond); 910 } 911 912// Load/store macros. 913#define DECLARE_FUNCTION(FN, REGTYPE, REG, OP) \ 914 void FN(const REGTYPE REG, const MemOperand& addr); 915 LS_MACRO_LIST(DECLARE_FUNCTION) 916#undef DECLARE_FUNCTION 917 918 void LoadStoreMacro(const CPURegister& rt, 919 const MemOperand& addr, 920 LoadStoreOp op); 921 922#define DECLARE_FUNCTION(FN, REGTYPE, REG, REG2, OP) \ 923 void FN(const REGTYPE REG, const REGTYPE REG2, const MemOperand& addr); 924 LSPAIR_MACRO_LIST(DECLARE_FUNCTION) 925#undef DECLARE_FUNCTION 926 927 void LoadStorePairMacro(const CPURegister& rt, 928 const CPURegister& rt2, 929 const MemOperand& addr, 930 LoadStorePairOp op); 931 932 void Prfm(PrefetchOperation op, const MemOperand& addr); 933 934 // Push or pop up to 4 registers of the same width to or from the stack, 935 // using the current stack pointer as set by SetStackPointer. 936 // 937 // If an argument register is 'NoReg', all further arguments are also assumed 938 // to be 'NoReg', and are thus not pushed or popped. 939 // 940 // Arguments are ordered such that "Push(a, b);" is functionally equivalent 941 // to "Push(a); Push(b);". 942 // 943 // It is valid to push the same register more than once, and there is no 944 // restriction on the order in which registers are specified. 945 // 946 // It is not valid to pop into the same register more than once in one 947 // operation, not even into the zero register. 948 // 949 // If the current stack pointer (as set by SetStackPointer) is sp, then it 950 // must be aligned to 16 bytes on entry and the total size of the specified 951 // registers must also be a multiple of 16 bytes. 952 // 953 // Even if the current stack pointer is not the system stack pointer (sp), 954 // Push (and derived methods) will still modify the system stack pointer in 955 // order to comply with ABI rules about accessing memory below the system 956 // stack pointer. 957 // 958 // Other than the registers passed into Pop, the stack pointer and (possibly) 959 // the system stack pointer, these methods do not modify any other registers. 960 void Push(const CPURegister& src0, 961 const CPURegister& src1 = NoReg, 962 const CPURegister& src2 = NoReg, 963 const CPURegister& src3 = NoReg); 964 void Pop(const CPURegister& dst0, 965 const CPURegister& dst1 = NoReg, 966 const CPURegister& dst2 = NoReg, 967 const CPURegister& dst3 = NoReg); 968 969 // Alternative forms of Push and Pop, taking a RegList or CPURegList that 970 // specifies the registers that are to be pushed or popped. Higher-numbered 971 // registers are associated with higher memory addresses (as in the A32 push 972 // and pop instructions). 973 // 974 // (Push|Pop)SizeRegList allow you to specify the register size as a 975 // parameter. Only kXRegSize, kWRegSize, kDRegSize and kSRegSize are 976 // supported. 977 // 978 // Otherwise, (Push|Pop)(CPU|X|W|D|S)RegList is preferred. 979 void PushCPURegList(CPURegList registers); 980 void PopCPURegList(CPURegList registers); 981 982 void PushSizeRegList( 983 RegList registers, 984 unsigned reg_size, 985 CPURegister::RegisterType type = CPURegister::kRegister) { 986 PushCPURegList(CPURegList(type, reg_size, registers)); 987 } 988 void PopSizeRegList(RegList registers, 989 unsigned reg_size, 990 CPURegister::RegisterType type = CPURegister::kRegister) { 991 PopCPURegList(CPURegList(type, reg_size, registers)); 992 } 993 void PushXRegList(RegList regs) { PushSizeRegList(regs, kXRegSize); } 994 void PopXRegList(RegList regs) { PopSizeRegList(regs, kXRegSize); } 995 void PushWRegList(RegList regs) { PushSizeRegList(regs, kWRegSize); } 996 void PopWRegList(RegList regs) { PopSizeRegList(regs, kWRegSize); } 997 void PushDRegList(RegList regs) { 998 PushSizeRegList(regs, kDRegSize, CPURegister::kVRegister); 999 } 1000 void PopDRegList(RegList regs) { 1001 PopSizeRegList(regs, kDRegSize, CPURegister::kVRegister); 1002 } 1003 void PushSRegList(RegList regs) { 1004 PushSizeRegList(regs, kSRegSize, CPURegister::kVRegister); 1005 } 1006 void PopSRegList(RegList regs) { 1007 PopSizeRegList(regs, kSRegSize, CPURegister::kVRegister); 1008 } 1009 1010 // Push the specified register 'count' times. 1011 void PushMultipleTimes(int count, Register src); 1012 1013 // Poke 'src' onto the stack. The offset is in bytes. 1014 // 1015 // If the current stack pointer (as set by SetStackPointer) is sp, then sp 1016 // must be aligned to 16 bytes. 1017 void Poke(const Register& src, const Operand& offset); 1018 1019 // Peek at a value on the stack, and put it in 'dst'. The offset is in bytes. 1020 // 1021 // If the current stack pointer (as set by SetStackPointer) is sp, then sp 1022 // must be aligned to 16 bytes. 1023 void Peek(const Register& dst, const Operand& offset); 1024 1025 // Alternative forms of Peek and Poke, taking a RegList or CPURegList that 1026 // specifies the registers that are to be pushed or popped. Higher-numbered 1027 // registers are associated with higher memory addresses. 1028 // 1029 // (Peek|Poke)SizeRegList allow you to specify the register size as a 1030 // parameter. Only kXRegSize, kWRegSize, kDRegSize and kSRegSize are 1031 // supported. 1032 // 1033 // Otherwise, (Peek|Poke)(CPU|X|W|D|S)RegList is preferred. 1034 void PeekCPURegList(CPURegList registers, int64_t offset) { 1035 LoadCPURegList(registers, MemOperand(StackPointer(), offset)); 1036 } 1037 void PokeCPURegList(CPURegList registers, int64_t offset) { 1038 StoreCPURegList(registers, MemOperand(StackPointer(), offset)); 1039 } 1040 1041 void PeekSizeRegList( 1042 RegList registers, 1043 int64_t offset, 1044 unsigned reg_size, 1045 CPURegister::RegisterType type = CPURegister::kRegister) { 1046 PeekCPURegList(CPURegList(type, reg_size, registers), offset); 1047 } 1048 void PokeSizeRegList( 1049 RegList registers, 1050 int64_t offset, 1051 unsigned reg_size, 1052 CPURegister::RegisterType type = CPURegister::kRegister) { 1053 PokeCPURegList(CPURegList(type, reg_size, registers), offset); 1054 } 1055 void PeekXRegList(RegList regs, int64_t offset) { 1056 PeekSizeRegList(regs, offset, kXRegSize); 1057 } 1058 void PokeXRegList(RegList regs, int64_t offset) { 1059 PokeSizeRegList(regs, offset, kXRegSize); 1060 } 1061 void PeekWRegList(RegList regs, int64_t offset) { 1062 PeekSizeRegList(regs, offset, kWRegSize); 1063 } 1064 void PokeWRegList(RegList regs, int64_t offset) { 1065 PokeSizeRegList(regs, offset, kWRegSize); 1066 } 1067 void PeekDRegList(RegList regs, int64_t offset) { 1068 PeekSizeRegList(regs, offset, kDRegSize, CPURegister::kVRegister); 1069 } 1070 void PokeDRegList(RegList regs, int64_t offset) { 1071 PokeSizeRegList(regs, offset, kDRegSize, CPURegister::kVRegister); 1072 } 1073 void PeekSRegList(RegList regs, int64_t offset) { 1074 PeekSizeRegList(regs, offset, kSRegSize, CPURegister::kVRegister); 1075 } 1076 void PokeSRegList(RegList regs, int64_t offset) { 1077 PokeSizeRegList(regs, offset, kSRegSize, CPURegister::kVRegister); 1078 } 1079 1080 1081 // Claim or drop stack space without actually accessing memory. 1082 // 1083 // If the current stack pointer (as set by SetStackPointer) is sp, then it 1084 // must be aligned to 16 bytes and the size claimed or dropped must be a 1085 // multiple of 16 bytes. 1086 void Claim(const Operand& size); 1087 void Drop(const Operand& size); 1088 1089 // As above, but for multiples of the SVE vector length. 1090 void ClaimVL(int64_t multiplier) { 1091 // We never need to worry about sp alignment because the VL is always a 1092 // multiple of 16. 1093 VIXL_STATIC_ASSERT((kZRegMinSizeInBytes % 16) == 0); 1094 VIXL_ASSERT(multiplier >= 0); 1095 Addvl(sp, sp, -multiplier); 1096 } 1097 void DropVL(int64_t multiplier) { 1098 VIXL_STATIC_ASSERT((kZRegMinSizeInBytes % 16) == 0); 1099 VIXL_ASSERT(multiplier >= 0); 1100 Addvl(sp, sp, multiplier); 1101 } 1102 1103 // Preserve the callee-saved registers (as defined by AAPCS64). 1104 // 1105 // Higher-numbered registers are pushed before lower-numbered registers, and 1106 // thus get higher addresses. 1107 // Floating-point registers are pushed before general-purpose registers, and 1108 // thus get higher addresses. 1109 // 1110 // This method must not be called unless StackPointer() is sp, and it is 1111 // aligned to 16 bytes. 1112 void PushCalleeSavedRegisters(); 1113 1114 // Restore the callee-saved registers (as defined by AAPCS64). 1115 // 1116 // Higher-numbered registers are popped after lower-numbered registers, and 1117 // thus come from higher addresses. 1118 // Floating-point registers are popped after general-purpose registers, and 1119 // thus come from higher addresses. 1120 // 1121 // This method must not be called unless StackPointer() is sp, and it is 1122 // aligned to 16 bytes. 1123 void PopCalleeSavedRegisters(); 1124 1125 void LoadCPURegList(CPURegList registers, const MemOperand& src); 1126 void StoreCPURegList(CPURegList registers, const MemOperand& dst); 1127 1128 // Remaining instructions are simple pass-through calls to the assembler. 1129 void Adr(const Register& rd, Label* label) { 1130 VIXL_ASSERT(allow_macro_instructions_); 1131 VIXL_ASSERT(!rd.IsZero()); 1132 SingleEmissionCheckScope guard(this); 1133 adr(rd, label); 1134 } 1135 void Adrp(const Register& rd, Label* label) { 1136 VIXL_ASSERT(allow_macro_instructions_); 1137 VIXL_ASSERT(!rd.IsZero()); 1138 SingleEmissionCheckScope guard(this); 1139 adrp(rd, label); 1140 } 1141 void Asr(const Register& rd, const Register& rn, unsigned shift) { 1142 VIXL_ASSERT(allow_macro_instructions_); 1143 VIXL_ASSERT(!rd.IsZero()); 1144 VIXL_ASSERT(!rn.IsZero()); 1145 SingleEmissionCheckScope guard(this); 1146 asr(rd, rn, shift); 1147 } 1148 void Asr(const Register& rd, const Register& rn, const Register& rm) { 1149 VIXL_ASSERT(allow_macro_instructions_); 1150 VIXL_ASSERT(!rd.IsZero()); 1151 VIXL_ASSERT(!rn.IsZero()); 1152 VIXL_ASSERT(!rm.IsZero()); 1153 SingleEmissionCheckScope guard(this); 1154 asrv(rd, rn, rm); 1155 } 1156 1157 // Branch type inversion relies on these relations. 1158 VIXL_STATIC_ASSERT((reg_zero == (reg_not_zero ^ 1)) && 1159 (reg_bit_clear == (reg_bit_set ^ 1)) && 1160 (always == (never ^ 1))); 1161 1162 BranchType InvertBranchType(BranchType type) { 1163 if (kBranchTypeFirstCondition <= type && type <= kBranchTypeLastCondition) { 1164 return static_cast<BranchType>( 1165 InvertCondition(static_cast<Condition>(type))); 1166 } else { 1167 return static_cast<BranchType>(type ^ 1); 1168 } 1169 } 1170 1171 void B(Label* label, BranchType type, Register reg = NoReg, int bit = -1); 1172 1173 void B(Label* label); 1174 void B(Label* label, Condition cond); 1175 void B(Condition cond, Label* label) { B(label, cond); } 1176 void Bfm(const Register& rd, 1177 const Register& rn, 1178 unsigned immr, 1179 unsigned imms) { 1180 VIXL_ASSERT(allow_macro_instructions_); 1181 VIXL_ASSERT(!rd.IsZero()); 1182 VIXL_ASSERT(!rn.IsZero()); 1183 SingleEmissionCheckScope guard(this); 1184 bfm(rd, rn, immr, imms); 1185 } 1186 void Bfi(const Register& rd, 1187 const Register& rn, 1188 unsigned lsb, 1189 unsigned width) { 1190 VIXL_ASSERT(allow_macro_instructions_); 1191 VIXL_ASSERT(!rd.IsZero()); 1192 VIXL_ASSERT(!rn.IsZero()); 1193 SingleEmissionCheckScope guard(this); 1194 bfi(rd, rn, lsb, width); 1195 } 1196 void Bfc(const Register& rd, unsigned lsb, unsigned width) { 1197 VIXL_ASSERT(allow_macro_instructions_); 1198 VIXL_ASSERT(!rd.IsZero()); 1199 SingleEmissionCheckScope guard(this); 1200 bfc(rd, lsb, width); 1201 } 1202 void Bfxil(const Register& rd, 1203 const Register& rn, 1204 unsigned lsb, 1205 unsigned width) { 1206 VIXL_ASSERT(allow_macro_instructions_); 1207 VIXL_ASSERT(!rd.IsZero()); 1208 VIXL_ASSERT(!rn.IsZero()); 1209 SingleEmissionCheckScope guard(this); 1210 bfxil(rd, rn, lsb, width); 1211 } 1212 void Bind(Label* label, BranchTargetIdentifier id = EmitBTI_none); 1213 // Bind a label to a specified offset from the start of the buffer. 1214 void BindToOffset(Label* label, ptrdiff_t offset); 1215 void Bl(Label* label) { 1216 VIXL_ASSERT(allow_macro_instructions_); 1217 SingleEmissionCheckScope guard(this); 1218 bl(label); 1219 } 1220 void Bl(int64_t offset) { 1221 VIXL_ASSERT(allow_macro_instructions_); 1222 SingleEmissionCheckScope guard(this); 1223 bl(offset >> kInstructionSizeLog2); 1224 } 1225 void Blr(const Register& xn) { 1226 VIXL_ASSERT(allow_macro_instructions_); 1227 VIXL_ASSERT(!xn.IsZero()); 1228 SingleEmissionCheckScope guard(this); 1229 blr(xn); 1230 } 1231 void Br(const Register& xn) { 1232 VIXL_ASSERT(allow_macro_instructions_); 1233 VIXL_ASSERT(!xn.IsZero()); 1234 SingleEmissionCheckScope guard(this); 1235 br(xn); 1236 } 1237 void Braaz(const Register& xn) { 1238 VIXL_ASSERT(allow_macro_instructions_); 1239 SingleEmissionCheckScope guard(this); 1240 braaz(xn); 1241 } 1242 void Brabz(const Register& xn) { 1243 VIXL_ASSERT(allow_macro_instructions_); 1244 SingleEmissionCheckScope guard(this); 1245 brabz(xn); 1246 } 1247 void Blraaz(const Register& xn) { 1248 VIXL_ASSERT(allow_macro_instructions_); 1249 SingleEmissionCheckScope guard(this); 1250 blraaz(xn); 1251 } 1252 void Blrabz(const Register& xn) { 1253 VIXL_ASSERT(allow_macro_instructions_); 1254 SingleEmissionCheckScope guard(this); 1255 blrabz(xn); 1256 } 1257 void Retaa() { 1258 VIXL_ASSERT(allow_macro_instructions_); 1259 SingleEmissionCheckScope guard(this); 1260 retaa(); 1261 } 1262 void Retab() { 1263 VIXL_ASSERT(allow_macro_instructions_); 1264 SingleEmissionCheckScope guard(this); 1265 retab(); 1266 } 1267 void Braa(const Register& xn, const Register& xm) { 1268 VIXL_ASSERT(allow_macro_instructions_); 1269 SingleEmissionCheckScope guard(this); 1270 braa(xn, xm); 1271 } 1272 void Brab(const Register& xn, const Register& xm) { 1273 VIXL_ASSERT(allow_macro_instructions_); 1274 SingleEmissionCheckScope guard(this); 1275 brab(xn, xm); 1276 } 1277 void Blraa(const Register& xn, const Register& xm) { 1278 VIXL_ASSERT(allow_macro_instructions_); 1279 SingleEmissionCheckScope guard(this); 1280 blraa(xn, xm); 1281 } 1282 void Blrab(const Register& xn, const Register& xm) { 1283 VIXL_ASSERT(allow_macro_instructions_); 1284 SingleEmissionCheckScope guard(this); 1285 blrab(xn, xm); 1286 } 1287 void Brk(int code = 0) { 1288 VIXL_ASSERT(allow_macro_instructions_); 1289 SingleEmissionCheckScope guard(this); 1290 brk(code); 1291 } 1292 void Cbnz(const Register& rt, Label* label); 1293 void Cbz(const Register& rt, Label* label); 1294 void Cinc(const Register& rd, const Register& rn, Condition cond) { 1295 VIXL_ASSERT(allow_macro_instructions_); 1296 VIXL_ASSERT(!rd.IsZero()); 1297 VIXL_ASSERT(!rn.IsZero()); 1298 SingleEmissionCheckScope guard(this); 1299 cinc(rd, rn, cond); 1300 } 1301 void Cinv(const Register& rd, const Register& rn, Condition cond) { 1302 VIXL_ASSERT(allow_macro_instructions_); 1303 VIXL_ASSERT(!rd.IsZero()); 1304 VIXL_ASSERT(!rn.IsZero()); 1305 SingleEmissionCheckScope guard(this); 1306 cinv(rd, rn, cond); 1307 } 1308 1309#define PAUTH_SYSTEM_MODES(V) \ 1310 V(az) \ 1311 V(bz) \ 1312 V(asp) \ 1313 V(bsp) 1314 1315#define DEFINE_MACRO_ASM_FUNCS(SUFFIX) \ 1316 void Paci##SUFFIX() { \ 1317 VIXL_ASSERT(allow_macro_instructions_); \ 1318 SingleEmissionCheckScope guard(this); \ 1319 paci##SUFFIX(); \ 1320 } \ 1321 void Auti##SUFFIX() { \ 1322 VIXL_ASSERT(allow_macro_instructions_); \ 1323 SingleEmissionCheckScope guard(this); \ 1324 auti##SUFFIX(); \ 1325 } 1326 1327 PAUTH_SYSTEM_MODES(DEFINE_MACRO_ASM_FUNCS) 1328#undef DEFINE_MACRO_ASM_FUNCS 1329 1330 // The 1716 pac and aut instructions encourage people to use x16 and x17 1331 // directly, perhaps without realising that this is forbidden. For example: 1332 // 1333 // UseScratchRegisterScope temps(&masm); 1334 // Register temp = temps.AcquireX(); // temp will be x16 1335 // __ Mov(x17, ptr); 1336 // __ Mov(x16, modifier); // Will override temp! 1337 // __ Pacia1716(); 1338 // 1339 // To work around this issue, you must exclude x16 and x17 from the scratch 1340 // register list. You may need to replace them with other registers: 1341 // 1342 // UseScratchRegisterScope temps(&masm); 1343 // temps.Exclude(x16, x17); 1344 // temps.Include(x10, x11); 1345 // __ Mov(x17, ptr); 1346 // __ Mov(x16, modifier); 1347 // __ Pacia1716(); 1348 void Pacia1716() { 1349 VIXL_ASSERT(allow_macro_instructions_); 1350 VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x16)); 1351 VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x17)); 1352 SingleEmissionCheckScope guard(this); 1353 pacia1716(); 1354 } 1355 void Pacib1716() { 1356 VIXL_ASSERT(allow_macro_instructions_); 1357 VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x16)); 1358 VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x17)); 1359 SingleEmissionCheckScope guard(this); 1360 pacib1716(); 1361 } 1362 void Autia1716() { 1363 VIXL_ASSERT(allow_macro_instructions_); 1364 VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x16)); 1365 VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x17)); 1366 SingleEmissionCheckScope guard(this); 1367 autia1716(); 1368 } 1369 void Autib1716() { 1370 VIXL_ASSERT(allow_macro_instructions_); 1371 VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x16)); 1372 VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(x17)); 1373 SingleEmissionCheckScope guard(this); 1374 autib1716(); 1375 } 1376 void Xpaclri() { 1377 VIXL_ASSERT(allow_macro_instructions_); 1378 SingleEmissionCheckScope guard(this); 1379 xpaclri(); 1380 } 1381 void Clrex() { 1382 VIXL_ASSERT(allow_macro_instructions_); 1383 SingleEmissionCheckScope guard(this); 1384 clrex(); 1385 } 1386 void Cls(const Register& rd, const Register& rn) { 1387 VIXL_ASSERT(allow_macro_instructions_); 1388 VIXL_ASSERT(!rd.IsZero()); 1389 VIXL_ASSERT(!rn.IsZero()); 1390 SingleEmissionCheckScope guard(this); 1391 cls(rd, rn); 1392 } 1393 void Clz(const Register& rd, const Register& rn) { 1394 VIXL_ASSERT(allow_macro_instructions_); 1395 VIXL_ASSERT(!rd.IsZero()); 1396 VIXL_ASSERT(!rn.IsZero()); 1397 SingleEmissionCheckScope guard(this); 1398 clz(rd, rn); 1399 } 1400 void Cneg(const Register& rd, const Register& rn, Condition cond) { 1401 VIXL_ASSERT(allow_macro_instructions_); 1402 VIXL_ASSERT(!rd.IsZero()); 1403 VIXL_ASSERT(!rn.IsZero()); 1404 SingleEmissionCheckScope guard(this); 1405 cneg(rd, rn, cond); 1406 } 1407 void Esb() { 1408 VIXL_ASSERT(allow_macro_instructions_); 1409 SingleEmissionCheckScope guard(this); 1410 esb(); 1411 } 1412 void Csdb() { 1413 VIXL_ASSERT(allow_macro_instructions_); 1414 SingleEmissionCheckScope guard(this); 1415 csdb(); 1416 } 1417 void Cset(const Register& rd, Condition cond) { 1418 VIXL_ASSERT(allow_macro_instructions_); 1419 VIXL_ASSERT(!rd.IsZero()); 1420 SingleEmissionCheckScope guard(this); 1421 cset(rd, cond); 1422 } 1423 void Csetm(const Register& rd, Condition cond) { 1424 VIXL_ASSERT(allow_macro_instructions_); 1425 VIXL_ASSERT(!rd.IsZero()); 1426 SingleEmissionCheckScope guard(this); 1427 csetm(rd, cond); 1428 } 1429 void Csinc(const Register& rd, 1430 const Register& rn, 1431 const Register& rm, 1432 Condition cond) { 1433 VIXL_ASSERT(allow_macro_instructions_); 1434 VIXL_ASSERT(!rd.IsZero()); 1435 VIXL_ASSERT((cond != al) && (cond != nv)); 1436 SingleEmissionCheckScope guard(this); 1437 csinc(rd, rn, rm, cond); 1438 } 1439 void Csinv(const Register& rd, 1440 const Register& rn, 1441 const Register& rm, 1442 Condition cond) { 1443 VIXL_ASSERT(allow_macro_instructions_); 1444 VIXL_ASSERT(!rd.IsZero()); 1445 VIXL_ASSERT((cond != al) && (cond != nv)); 1446 SingleEmissionCheckScope guard(this); 1447 csinv(rd, rn, rm, cond); 1448 } 1449 void Csneg(const Register& rd, 1450 const Register& rn, 1451 const Register& rm, 1452 Condition cond) { 1453 VIXL_ASSERT(allow_macro_instructions_); 1454 VIXL_ASSERT(!rd.IsZero()); 1455 VIXL_ASSERT((cond != al) && (cond != nv)); 1456 SingleEmissionCheckScope guard(this); 1457 csneg(rd, rn, rm, cond); 1458 } 1459 void Dmb(BarrierDomain domain, BarrierType type) { 1460 VIXL_ASSERT(allow_macro_instructions_); 1461 SingleEmissionCheckScope guard(this); 1462 dmb(domain, type); 1463 } 1464 void Dsb(BarrierDomain domain, BarrierType type) { 1465 VIXL_ASSERT(allow_macro_instructions_); 1466 SingleEmissionCheckScope guard(this); 1467 dsb(domain, type); 1468 } 1469 void Extr(const Register& rd, 1470 const Register& rn, 1471 const Register& rm, 1472 unsigned lsb) { 1473 VIXL_ASSERT(allow_macro_instructions_); 1474 VIXL_ASSERT(!rd.IsZero()); 1475 VIXL_ASSERT(!rn.IsZero()); 1476 VIXL_ASSERT(!rm.IsZero()); 1477 SingleEmissionCheckScope guard(this); 1478 extr(rd, rn, rm, lsb); 1479 } 1480 void Fadd(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1481 VIXL_ASSERT(allow_macro_instructions_); 1482 SingleEmissionCheckScope guard(this); 1483 fadd(vd, vn, vm); 1484 } 1485 void Fccmp(const VRegister& vn, 1486 const VRegister& vm, 1487 StatusFlags nzcv, 1488 Condition cond, 1489 FPTrapFlags trap = DisableTrap) { 1490 VIXL_ASSERT(allow_macro_instructions_); 1491 VIXL_ASSERT((cond != al) && (cond != nv)); 1492 SingleEmissionCheckScope guard(this); 1493 FPCCompareMacro(vn, vm, nzcv, cond, trap); 1494 } 1495 void Fccmpe(const VRegister& vn, 1496 const VRegister& vm, 1497 StatusFlags nzcv, 1498 Condition cond) { 1499 Fccmp(vn, vm, nzcv, cond, EnableTrap); 1500 } 1501 void Fcmp(const VRegister& vn, 1502 const VRegister& vm, 1503 FPTrapFlags trap = DisableTrap) { 1504 VIXL_ASSERT(allow_macro_instructions_); 1505 SingleEmissionCheckScope guard(this); 1506 FPCompareMacro(vn, vm, trap); 1507 } 1508 void Fcmp(const VRegister& vn, double value, FPTrapFlags trap = DisableTrap); 1509 void Fcmpe(const VRegister& vn, double value); 1510 void Fcmpe(const VRegister& vn, const VRegister& vm) { 1511 Fcmp(vn, vm, EnableTrap); 1512 } 1513 void Fcsel(const VRegister& vd, 1514 const VRegister& vn, 1515 const VRegister& vm, 1516 Condition cond) { 1517 VIXL_ASSERT(allow_macro_instructions_); 1518 VIXL_ASSERT((cond != al) && (cond != nv)); 1519 SingleEmissionCheckScope guard(this); 1520 fcsel(vd, vn, vm, cond); 1521 } 1522 void Fcvt(const VRegister& vd, const VRegister& vn) { 1523 VIXL_ASSERT(allow_macro_instructions_); 1524 SingleEmissionCheckScope guard(this); 1525 fcvt(vd, vn); 1526 } 1527 void Fcvtl(const VRegister& vd, const VRegister& vn) { 1528 VIXL_ASSERT(allow_macro_instructions_); 1529 SingleEmissionCheckScope guard(this); 1530 fcvtl(vd, vn); 1531 } 1532 void Fcvtl2(const VRegister& vd, const VRegister& vn) { 1533 VIXL_ASSERT(allow_macro_instructions_); 1534 SingleEmissionCheckScope guard(this); 1535 fcvtl2(vd, vn); 1536 } 1537 void Fcvtn(const VRegister& vd, const VRegister& vn) { 1538 VIXL_ASSERT(allow_macro_instructions_); 1539 SingleEmissionCheckScope guard(this); 1540 fcvtn(vd, vn); 1541 } 1542 void Fcvtn2(const VRegister& vd, const VRegister& vn) { 1543 VIXL_ASSERT(allow_macro_instructions_); 1544 SingleEmissionCheckScope guard(this); 1545 fcvtn2(vd, vn); 1546 } 1547 void Fcvtxn(const VRegister& vd, const VRegister& vn) { 1548 VIXL_ASSERT(allow_macro_instructions_); 1549 SingleEmissionCheckScope guard(this); 1550 fcvtxn(vd, vn); 1551 } 1552 void Fcvtxn2(const VRegister& vd, const VRegister& vn) { 1553 VIXL_ASSERT(allow_macro_instructions_); 1554 SingleEmissionCheckScope guard(this); 1555 fcvtxn2(vd, vn); 1556 } 1557 void Fcvtas(const Register& rd, const VRegister& vn) { 1558 VIXL_ASSERT(allow_macro_instructions_); 1559 VIXL_ASSERT(!rd.IsZero()); 1560 SingleEmissionCheckScope guard(this); 1561 fcvtas(rd, vn); 1562 } 1563 void Fcvtau(const Register& rd, const VRegister& vn) { 1564 VIXL_ASSERT(allow_macro_instructions_); 1565 VIXL_ASSERT(!rd.IsZero()); 1566 SingleEmissionCheckScope guard(this); 1567 fcvtau(rd, vn); 1568 } 1569 void Fcvtms(const Register& rd, const VRegister& vn) { 1570 VIXL_ASSERT(allow_macro_instructions_); 1571 VIXL_ASSERT(!rd.IsZero()); 1572 SingleEmissionCheckScope guard(this); 1573 fcvtms(rd, vn); 1574 } 1575 void Fcvtmu(const Register& rd, const VRegister& vn) { 1576 VIXL_ASSERT(allow_macro_instructions_); 1577 VIXL_ASSERT(!rd.IsZero()); 1578 SingleEmissionCheckScope guard(this); 1579 fcvtmu(rd, vn); 1580 } 1581 void Fcvtns(const Register& rd, const VRegister& vn) { 1582 VIXL_ASSERT(allow_macro_instructions_); 1583 VIXL_ASSERT(!rd.IsZero()); 1584 SingleEmissionCheckScope guard(this); 1585 fcvtns(rd, vn); 1586 } 1587 void Fcvtnu(const Register& rd, const VRegister& vn) { 1588 VIXL_ASSERT(allow_macro_instructions_); 1589 VIXL_ASSERT(!rd.IsZero()); 1590 SingleEmissionCheckScope guard(this); 1591 fcvtnu(rd, vn); 1592 } 1593 void Fcvtps(const Register& rd, const VRegister& vn) { 1594 VIXL_ASSERT(allow_macro_instructions_); 1595 VIXL_ASSERT(!rd.IsZero()); 1596 SingleEmissionCheckScope guard(this); 1597 fcvtps(rd, vn); 1598 } 1599 void Fcvtpu(const Register& rd, const VRegister& vn) { 1600 VIXL_ASSERT(allow_macro_instructions_); 1601 VIXL_ASSERT(!rd.IsZero()); 1602 SingleEmissionCheckScope guard(this); 1603 fcvtpu(rd, vn); 1604 } 1605 void Fcvtzs(const Register& rd, const VRegister& vn, int fbits = 0) { 1606 VIXL_ASSERT(allow_macro_instructions_); 1607 VIXL_ASSERT(!rd.IsZero()); 1608 SingleEmissionCheckScope guard(this); 1609 fcvtzs(rd, vn, fbits); 1610 } 1611 void Fjcvtzs(const Register& rd, const VRegister& vn) { 1612 VIXL_ASSERT(allow_macro_instructions_); 1613 VIXL_ASSERT(!rd.IsZero()); 1614 SingleEmissionCheckScope guard(this); 1615 fjcvtzs(rd, vn); 1616 } 1617 void Fcvtzu(const Register& rd, const VRegister& vn, int fbits = 0) { 1618 VIXL_ASSERT(allow_macro_instructions_); 1619 VIXL_ASSERT(!rd.IsZero()); 1620 SingleEmissionCheckScope guard(this); 1621 fcvtzu(rd, vn, fbits); 1622 } 1623 void Fdiv(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1624 VIXL_ASSERT(allow_macro_instructions_); 1625 SingleEmissionCheckScope guard(this); 1626 fdiv(vd, vn, vm); 1627 } 1628 void Fmax(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1629 VIXL_ASSERT(allow_macro_instructions_); 1630 SingleEmissionCheckScope guard(this); 1631 fmax(vd, vn, vm); 1632 } 1633 void Fmaxnm(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1634 VIXL_ASSERT(allow_macro_instructions_); 1635 SingleEmissionCheckScope guard(this); 1636 fmaxnm(vd, vn, vm); 1637 } 1638 void Fmin(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1639 VIXL_ASSERT(allow_macro_instructions_); 1640 SingleEmissionCheckScope guard(this); 1641 fmin(vd, vn, vm); 1642 } 1643 void Fminnm(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1644 VIXL_ASSERT(allow_macro_instructions_); 1645 SingleEmissionCheckScope guard(this); 1646 fminnm(vd, vn, vm); 1647 } 1648 void Fmov(const VRegister& vd, const VRegister& vn) { 1649 VIXL_ASSERT(allow_macro_instructions_); 1650 SingleEmissionCheckScope guard(this); 1651 // TODO: Use DiscardMoveMode to allow this move to be elided if vd.Is(vn). 1652 fmov(vd, vn); 1653 } 1654 void Fmov(const VRegister& vd, const Register& rn) { 1655 VIXL_ASSERT(allow_macro_instructions_); 1656 VIXL_ASSERT(!rn.IsZero()); 1657 SingleEmissionCheckScope guard(this); 1658 fmov(vd, rn); 1659 } 1660 void Fmov(const VRegister& vd, int index, const Register& rn) { 1661 VIXL_ASSERT(allow_macro_instructions_); 1662 SingleEmissionCheckScope guard(this); 1663 if (vd.Is1D() && (index == 0)) { 1664 mov(vd, index, rn); 1665 } else { 1666 fmov(vd, index, rn); 1667 } 1668 } 1669 void Fmov(const Register& rd, const VRegister& vn, int index) { 1670 VIXL_ASSERT(allow_macro_instructions_); 1671 SingleEmissionCheckScope guard(this); 1672 if (vn.Is1D() && (index == 0)) { 1673 mov(rd, vn, index); 1674 } else { 1675 fmov(rd, vn, index); 1676 } 1677 } 1678 1679 // Provide explicit double and float interfaces for FP immediate moves, rather 1680 // than relying on implicit C++ casts. This allows signalling NaNs to be 1681 // preserved when the immediate matches the format of vd. Most systems convert 1682 // signalling NaNs to quiet NaNs when converting between float and double. 1683 void Fmov(VRegister vd, double imm); 1684 void Fmov(VRegister vd, float imm); 1685 void Fmov(VRegister vd, const Float16 imm); 1686 // Provide a template to allow other types to be converted automatically. 1687 template <typename T> 1688 void Fmov(VRegister vd, T imm) { 1689 VIXL_ASSERT(allow_macro_instructions_); 1690 Fmov(vd, static_cast<double>(imm)); 1691 } 1692 void Fmov(Register rd, VRegister vn) { 1693 VIXL_ASSERT(allow_macro_instructions_); 1694 VIXL_ASSERT(!rd.IsZero()); 1695 SingleEmissionCheckScope guard(this); 1696 fmov(rd, vn); 1697 } 1698 void Fmul(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1699 VIXL_ASSERT(allow_macro_instructions_); 1700 SingleEmissionCheckScope guard(this); 1701 fmul(vd, vn, vm); 1702 } 1703 void Fnmul(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1704 VIXL_ASSERT(allow_macro_instructions_); 1705 SingleEmissionCheckScope guard(this); 1706 fnmul(vd, vn, vm); 1707 } 1708 void Fmadd(const VRegister& vd, 1709 const VRegister& vn, 1710 const VRegister& vm, 1711 const VRegister& va) { 1712 VIXL_ASSERT(allow_macro_instructions_); 1713 SingleEmissionCheckScope guard(this); 1714 fmadd(vd, vn, vm, va); 1715 } 1716 void Fmsub(const VRegister& vd, 1717 const VRegister& vn, 1718 const VRegister& vm, 1719 const VRegister& va) { 1720 VIXL_ASSERT(allow_macro_instructions_); 1721 SingleEmissionCheckScope guard(this); 1722 fmsub(vd, vn, vm, va); 1723 } 1724 void Fnmadd(const VRegister& vd, 1725 const VRegister& vn, 1726 const VRegister& vm, 1727 const VRegister& va) { 1728 VIXL_ASSERT(allow_macro_instructions_); 1729 SingleEmissionCheckScope guard(this); 1730 fnmadd(vd, vn, vm, va); 1731 } 1732 void Fnmsub(const VRegister& vd, 1733 const VRegister& vn, 1734 const VRegister& vm, 1735 const VRegister& va) { 1736 VIXL_ASSERT(allow_macro_instructions_); 1737 SingleEmissionCheckScope guard(this); 1738 fnmsub(vd, vn, vm, va); 1739 } 1740 void Fsub(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 1741 VIXL_ASSERT(allow_macro_instructions_); 1742 SingleEmissionCheckScope guard(this); 1743 fsub(vd, vn, vm); 1744 } 1745 void Hint(SystemHint code) { 1746 VIXL_ASSERT(allow_macro_instructions_); 1747 SingleEmissionCheckScope guard(this); 1748 hint(code); 1749 } 1750 void Hint(int imm7) { 1751 VIXL_ASSERT(allow_macro_instructions_); 1752 SingleEmissionCheckScope guard(this); 1753 hint(imm7); 1754 } 1755 void Hlt(int code) { 1756 VIXL_ASSERT(allow_macro_instructions_); 1757 SingleEmissionCheckScope guard(this); 1758 hlt(code); 1759 } 1760 void Isb() { 1761 VIXL_ASSERT(allow_macro_instructions_); 1762 SingleEmissionCheckScope guard(this); 1763 isb(); 1764 } 1765 void Ldar(const Register& rt, const MemOperand& src) { 1766 VIXL_ASSERT(allow_macro_instructions_); 1767 SingleEmissionCheckScope guard(this); 1768 ldar(rt, src); 1769 } 1770 void Ldarb(const Register& rt, const MemOperand& src) { 1771 VIXL_ASSERT(allow_macro_instructions_); 1772 SingleEmissionCheckScope guard(this); 1773 ldarb(rt, src); 1774 } 1775 void Ldarh(const Register& rt, const MemOperand& src) { 1776 VIXL_ASSERT(allow_macro_instructions_); 1777 SingleEmissionCheckScope guard(this); 1778 ldarh(rt, src); 1779 } 1780 void Ldlar(const Register& rt, const MemOperand& src) { 1781 VIXL_ASSERT(allow_macro_instructions_); 1782 SingleEmissionCheckScope guard(this); 1783 ldlar(rt, src); 1784 } 1785 void Ldlarb(const Register& rt, const MemOperand& src) { 1786 VIXL_ASSERT(allow_macro_instructions_); 1787 SingleEmissionCheckScope guard(this); 1788 ldlarb(rt, src); 1789 } 1790 void Ldlarh(const Register& rt, const MemOperand& src) { 1791 VIXL_ASSERT(allow_macro_instructions_); 1792 SingleEmissionCheckScope guard(this); 1793 ldlarh(rt, src); 1794 } 1795 void Ldaxp(const Register& rt, const Register& rt2, const MemOperand& src) { 1796 VIXL_ASSERT(allow_macro_instructions_); 1797 VIXL_ASSERT(!rt.Aliases(rt2)); 1798 SingleEmissionCheckScope guard(this); 1799 ldaxp(rt, rt2, src); 1800 } 1801 void Ldaxr(const Register& rt, const MemOperand& src) { 1802 VIXL_ASSERT(allow_macro_instructions_); 1803 SingleEmissionCheckScope guard(this); 1804 ldaxr(rt, src); 1805 } 1806 void Ldaxrb(const Register& rt, const MemOperand& src) { 1807 VIXL_ASSERT(allow_macro_instructions_); 1808 SingleEmissionCheckScope guard(this); 1809 ldaxrb(rt, src); 1810 } 1811 void Ldaxrh(const Register& rt, const MemOperand& src) { 1812 VIXL_ASSERT(allow_macro_instructions_); 1813 SingleEmissionCheckScope guard(this); 1814 ldaxrh(rt, src); 1815 } 1816 1817// clang-format off 1818#define COMPARE_AND_SWAP_SINGLE_MACRO_LIST(V) \ 1819 V(cas, Cas) \ 1820 V(casa, Casa) \ 1821 V(casl, Casl) \ 1822 V(casal, Casal) \ 1823 V(casb, Casb) \ 1824 V(casab, Casab) \ 1825 V(caslb, Caslb) \ 1826 V(casalb, Casalb) \ 1827 V(cash, Cash) \ 1828 V(casah, Casah) \ 1829 V(caslh, Caslh) \ 1830 V(casalh, Casalh) 1831 // clang-format on 1832 1833#define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \ 1834 void MASM(const Register& rs, const Register& rt, const MemOperand& src) { \ 1835 VIXL_ASSERT(allow_macro_instructions_); \ 1836 SingleEmissionCheckScope guard(this); \ 1837 ASM(rs, rt, src); \ 1838 } 1839 COMPARE_AND_SWAP_SINGLE_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 1840#undef DEFINE_MACRO_ASM_FUNC 1841 1842 1843// clang-format off 1844#define COMPARE_AND_SWAP_PAIR_MACRO_LIST(V) \ 1845 V(casp, Casp) \ 1846 V(caspa, Caspa) \ 1847 V(caspl, Caspl) \ 1848 V(caspal, Caspal) 1849 // clang-format on 1850 1851#define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \ 1852 void MASM(const Register& rs, \ 1853 const Register& rs2, \ 1854 const Register& rt, \ 1855 const Register& rt2, \ 1856 const MemOperand& src) { \ 1857 VIXL_ASSERT(allow_macro_instructions_); \ 1858 SingleEmissionCheckScope guard(this); \ 1859 ASM(rs, rs2, rt, rt2, src); \ 1860 } 1861 COMPARE_AND_SWAP_PAIR_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 1862#undef DEFINE_MACRO_ASM_FUNC 1863 1864// These macros generate all the variations of the atomic memory operations, 1865// e.g. ldadd, ldadda, ldaddb, staddl, etc. 1866 1867// clang-format off 1868#define ATOMIC_MEMORY_SIMPLE_MACRO_LIST(V, DEF, MASM_PRE, ASM_PRE) \ 1869 V(DEF, MASM_PRE##add, ASM_PRE##add) \ 1870 V(DEF, MASM_PRE##clr, ASM_PRE##clr) \ 1871 V(DEF, MASM_PRE##eor, ASM_PRE##eor) \ 1872 V(DEF, MASM_PRE##set, ASM_PRE##set) \ 1873 V(DEF, MASM_PRE##smax, ASM_PRE##smax) \ 1874 V(DEF, MASM_PRE##smin, ASM_PRE##smin) \ 1875 V(DEF, MASM_PRE##umax, ASM_PRE##umax) \ 1876 V(DEF, MASM_PRE##umin, ASM_PRE##umin) 1877 1878#define ATOMIC_MEMORY_STORE_MACRO_MODES(V, MASM, ASM) \ 1879 V(MASM, ASM) \ 1880 V(MASM##l, ASM##l) \ 1881 V(MASM##b, ASM##b) \ 1882 V(MASM##lb, ASM##lb) \ 1883 V(MASM##h, ASM##h) \ 1884 V(MASM##lh, ASM##lh) 1885 1886#define ATOMIC_MEMORY_LOAD_MACRO_MODES(V, MASM, ASM) \ 1887 ATOMIC_MEMORY_STORE_MACRO_MODES(V, MASM, ASM) \ 1888 V(MASM##a, ASM##a) \ 1889 V(MASM##al, ASM##al) \ 1890 V(MASM##ab, ASM##ab) \ 1891 V(MASM##alb, ASM##alb) \ 1892 V(MASM##ah, ASM##ah) \ 1893 V(MASM##alh, ASM##alh) 1894 // clang-format on 1895 1896#define DEFINE_MACRO_LOAD_ASM_FUNC(MASM, ASM) \ 1897 void MASM(const Register& rs, const Register& rt, const MemOperand& src) { \ 1898 VIXL_ASSERT(allow_macro_instructions_); \ 1899 SingleEmissionCheckScope guard(this); \ 1900 ASM(rs, rt, src); \ 1901 } 1902#define DEFINE_MACRO_STORE_ASM_FUNC(MASM, ASM) \ 1903 void MASM(const Register& rs, const MemOperand& src) { \ 1904 VIXL_ASSERT(allow_macro_instructions_); \ 1905 SingleEmissionCheckScope guard(this); \ 1906 ASM(rs, src); \ 1907 } 1908 1909 ATOMIC_MEMORY_SIMPLE_MACRO_LIST(ATOMIC_MEMORY_LOAD_MACRO_MODES, 1910 DEFINE_MACRO_LOAD_ASM_FUNC, 1911 Ld, 1912 ld) 1913 ATOMIC_MEMORY_SIMPLE_MACRO_LIST(ATOMIC_MEMORY_STORE_MACRO_MODES, 1914 DEFINE_MACRO_STORE_ASM_FUNC, 1915 St, 1916 st) 1917 1918#define DEFINE_MACRO_SWP_ASM_FUNC(MASM, ASM) \ 1919 void MASM(const Register& rs, const Register& rt, const MemOperand& src) { \ 1920 VIXL_ASSERT(allow_macro_instructions_); \ 1921 SingleEmissionCheckScope guard(this); \ 1922 ASM(rs, rt, src); \ 1923 } 1924 1925 ATOMIC_MEMORY_LOAD_MACRO_MODES(DEFINE_MACRO_SWP_ASM_FUNC, Swp, swp) 1926 1927#undef DEFINE_MACRO_LOAD_ASM_FUNC 1928#undef DEFINE_MACRO_STORE_ASM_FUNC 1929#undef DEFINE_MACRO_SWP_ASM_FUNC 1930 1931 void Ldaprb(const Register& rt, const MemOperand& src) { 1932 VIXL_ASSERT(allow_macro_instructions_); 1933 SingleEmissionCheckScope guard(this); 1934 VIXL_ASSERT(src.IsImmediateOffset()); 1935 if (src.GetOffset() == 0) { 1936 ldaprb(rt, src); 1937 } else { 1938 ldapurb(rt, src); 1939 } 1940 } 1941 1942 void Ldapursb(const Register& rt, const MemOperand& src) { 1943 VIXL_ASSERT(allow_macro_instructions_); 1944 SingleEmissionCheckScope guard(this); 1945 ldapursb(rt, src); 1946 } 1947 1948 void Ldaprh(const Register& rt, const MemOperand& src) { 1949 VIXL_ASSERT(allow_macro_instructions_); 1950 SingleEmissionCheckScope guard(this); 1951 VIXL_ASSERT(src.IsImmediateOffset()); 1952 if (src.GetOffset() == 0) { 1953 ldaprh(rt, src); 1954 } else { 1955 ldapurh(rt, src); 1956 } 1957 } 1958 1959 void Ldapursh(const Register& rt, const MemOperand& src) { 1960 VIXL_ASSERT(allow_macro_instructions_); 1961 SingleEmissionCheckScope guard(this); 1962 ldapursh(rt, src); 1963 } 1964 1965 void Ldapr(const Register& rt, const MemOperand& src) { 1966 VIXL_ASSERT(allow_macro_instructions_); 1967 SingleEmissionCheckScope guard(this); 1968 VIXL_ASSERT(src.IsImmediateOffset()); 1969 if (src.GetOffset() == 0) { 1970 ldapr(rt, src); 1971 } else { 1972 ldapur(rt, src); 1973 } 1974 } 1975 1976 void Ldapursw(const Register& rt, const MemOperand& src) { 1977 VIXL_ASSERT(allow_macro_instructions_); 1978 SingleEmissionCheckScope guard(this); 1979 ldapursw(rt, src); 1980 } 1981 1982 void Ldnp(const CPURegister& rt, 1983 const CPURegister& rt2, 1984 const MemOperand& src) { 1985 VIXL_ASSERT(allow_macro_instructions_); 1986 SingleEmissionCheckScope guard(this); 1987 ldnp(rt, rt2, src); 1988 } 1989 // Provide both double and float interfaces for FP immediate loads, rather 1990 // than relying on implicit C++ casts. This allows signalling NaNs to be 1991 // preserved when the immediate matches the format of fd. Most systems convert 1992 // signalling NaNs to quiet NaNs when converting between float and double. 1993 void Ldr(const VRegister& vt, double imm) { 1994 VIXL_ASSERT(allow_macro_instructions_); 1995 SingleEmissionCheckScope guard(this); 1996 RawLiteral* literal; 1997#ifndef PANDA_BUILD 1998 if (vt.IsD()) { 1999 literal = new Literal<double>(imm, 2000 &literal_pool_, 2001 RawLiteral::kDeletedOnPlacementByPool); 2002 } else { 2003 literal = new Literal<float>(static_cast<float>(imm), 2004 &literal_pool_, 2005 RawLiteral::kDeletedOnPlacementByPool); 2006 } 2007#else 2008 if (vt.IsD()) { 2009 literal = allocator_.New<Literal<double>>(imm, 2010 &literal_pool_, 2011 RawLiteral::kDeletedOnPlacementByPool); 2012 } else { 2013 literal = allocator_.New<Literal<float>>(static_cast<float>(imm), 2014 &literal_pool_, 2015 RawLiteral::kDeletedOnPlacementByPool); 2016 } 2017#endif 2018 ldr(vt, literal); 2019 } 2020 void Ldr(const VRegister& vt, float imm) { 2021 VIXL_ASSERT(allow_macro_instructions_); 2022 SingleEmissionCheckScope guard(this); 2023 RawLiteral* literal; 2024#ifndef PANDA_BUILD 2025 if (vt.IsS()) { 2026 literal = new Literal<float>(imm, 2027 &literal_pool_, 2028 RawLiteral::kDeletedOnPlacementByPool); 2029 } else { 2030 literal = new Literal<double>(static_cast<double>(imm), 2031 &literal_pool_, 2032 RawLiteral::kDeletedOnPlacementByPool); 2033 } 2034#else 2035 if (vt.IsS()) { 2036 literal = allocator_.New<Literal<float>>(imm, 2037 &literal_pool_, 2038 RawLiteral::kDeletedOnPlacementByPool); 2039 } else { 2040 literal = allocator_.New<Literal<double>>(static_cast<double>(imm), 2041 &literal_pool_, 2042 RawLiteral::kDeletedOnPlacementByPool); 2043 } 2044#endif 2045 ldr(vt, literal); 2046 } 2047 void Ldr(const VRegister& vt, uint64_t high64, uint64_t low64) { 2048 VIXL_ASSERT(allow_macro_instructions_); 2049 VIXL_ASSERT(vt.IsQ()); 2050 SingleEmissionCheckScope guard(this); 2051#ifndef PANDA_BUILD 2052 ldr(vt, 2053 new Literal<uint64_t>(high64, 2054 low64, 2055 &literal_pool_, 2056 RawLiteral::kDeletedOnPlacementByPool)); 2057#else 2058 ldr(vt, 2059 allocator_.New<Literal<uint64_t>>(high64, 2060 low64, 2061 &literal_pool_, 2062 RawLiteral::kDeletedOnPlacementByPool)); 2063#endif 2064 } 2065 void Ldr(const Register& rt, uint64_t imm) { 2066 VIXL_ASSERT(allow_macro_instructions_); 2067 VIXL_ASSERT(!rt.IsZero()); 2068 SingleEmissionCheckScope guard(this); 2069 RawLiteral* literal; 2070#ifndef PANDA_BUILD 2071 if (rt.Is64Bits()) { 2072 literal = new Literal<uint64_t>(imm, 2073 &literal_pool_, 2074 RawLiteral::kDeletedOnPlacementByPool); 2075 } else { 2076 VIXL_ASSERT(rt.Is32Bits()); 2077 VIXL_ASSERT(IsUint32(imm) || IsInt32(imm)); 2078 literal = new Literal<uint32_t>(static_cast<uint32_t>(imm), 2079 &literal_pool_, 2080 RawLiteral::kDeletedOnPlacementByPool); 2081 } 2082#else 2083 if (rt.Is64Bits()) { 2084 literal = allocator_.New<Literal<uint64_t>>(imm, 2085 &literal_pool_, 2086 RawLiteral::kDeletedOnPlacementByPool); 2087 } else { 2088 VIXL_ASSERT(rt.Is32Bits()); 2089 VIXL_ASSERT(IsUint32(imm) || IsInt32(imm)); 2090 literal = allocator_.New<Literal<uint32_t>>(static_cast<uint32_t>(imm), 2091 &literal_pool_, 2092 RawLiteral::kDeletedOnPlacementByPool); 2093 } 2094#endif 2095 ldr(rt, literal); 2096 } 2097 void Ldrsw(const Register& rt, uint32_t imm) { 2098 VIXL_ASSERT(allow_macro_instructions_); 2099 VIXL_ASSERT(!rt.IsZero()); 2100 SingleEmissionCheckScope guard(this); 2101#ifndef PANDA_BUILD 2102 ldrsw(rt, 2103 new Literal<uint32_t>(imm, 2104 &literal_pool_, 2105 RawLiteral::kDeletedOnPlacementByPool)); 2106#else 2107 ldrsw(rt, 2108 allocator_.New<Literal<uint32_t>>(imm, 2109 &literal_pool_, 2110 RawLiteral::kDeletedOnPlacementByPool)); 2111#endif 2112 } 2113 void Ldr(const CPURegister& rt, RawLiteral* literal) { 2114 VIXL_ASSERT(allow_macro_instructions_); 2115 SingleEmissionCheckScope guard(this); 2116 ldr(rt, literal); 2117 } 2118 void Ldrsw(const Register& rt, RawLiteral* literal) { 2119 VIXL_ASSERT(allow_macro_instructions_); 2120 SingleEmissionCheckScope guard(this); 2121 ldrsw(rt, literal); 2122 } 2123 void Ldxp(const Register& rt, const Register& rt2, const MemOperand& src) { 2124 VIXL_ASSERT(allow_macro_instructions_); 2125 VIXL_ASSERT(!rt.Aliases(rt2)); 2126 SingleEmissionCheckScope guard(this); 2127 ldxp(rt, rt2, src); 2128 } 2129 void Ldxr(const Register& rt, const MemOperand& src) { 2130 VIXL_ASSERT(allow_macro_instructions_); 2131 SingleEmissionCheckScope guard(this); 2132 ldxr(rt, src); 2133 } 2134 void Ldxrb(const Register& rt, const MemOperand& src) { 2135 VIXL_ASSERT(allow_macro_instructions_); 2136 SingleEmissionCheckScope guard(this); 2137 ldxrb(rt, src); 2138 } 2139 void Ldxrh(const Register& rt, const MemOperand& src) { 2140 VIXL_ASSERT(allow_macro_instructions_); 2141 SingleEmissionCheckScope guard(this); 2142 ldxrh(rt, src); 2143 } 2144 void Lsl(const Register& rd, const Register& rn, unsigned shift) { 2145 VIXL_ASSERT(allow_macro_instructions_); 2146 VIXL_ASSERT(!rd.IsZero()); 2147 VIXL_ASSERT(!rn.IsZero()); 2148 SingleEmissionCheckScope guard(this); 2149 lsl(rd, rn, shift); 2150 } 2151 void Lsl(const Register& rd, const Register& rn, const Register& rm) { 2152 VIXL_ASSERT(allow_macro_instructions_); 2153 VIXL_ASSERT(!rd.IsZero()); 2154 VIXL_ASSERT(!rn.IsZero()); 2155 VIXL_ASSERT(!rm.IsZero()); 2156 SingleEmissionCheckScope guard(this); 2157 lslv(rd, rn, rm); 2158 } 2159 void Lsr(const Register& rd, const Register& rn, unsigned shift) { 2160 VIXL_ASSERT(allow_macro_instructions_); 2161 VIXL_ASSERT(!rd.IsZero()); 2162 VIXL_ASSERT(!rn.IsZero()); 2163 SingleEmissionCheckScope guard(this); 2164 lsr(rd, rn, shift); 2165 } 2166 void Lsr(const Register& rd, const Register& rn, const Register& rm) { 2167 VIXL_ASSERT(allow_macro_instructions_); 2168 VIXL_ASSERT(!rd.IsZero()); 2169 VIXL_ASSERT(!rn.IsZero()); 2170 VIXL_ASSERT(!rm.IsZero()); 2171 SingleEmissionCheckScope guard(this); 2172 lsrv(rd, rn, rm); 2173 } 2174 void Ldraa(const Register& xt, const MemOperand& src) { 2175 VIXL_ASSERT(allow_macro_instructions_); 2176 SingleEmissionCheckScope guard(this); 2177 ldraa(xt, src); 2178 } 2179 void Ldrab(const Register& xt, const MemOperand& src) { 2180 VIXL_ASSERT(allow_macro_instructions_); 2181 SingleEmissionCheckScope guard(this); 2182 ldrab(xt, src); 2183 } 2184 void Madd(const Register& rd, 2185 const Register& rn, 2186 const Register& rm, 2187 const Register& ra) { 2188 VIXL_ASSERT(allow_macro_instructions_); 2189 VIXL_ASSERT(!rd.IsZero()); 2190 VIXL_ASSERT(!rn.IsZero()); 2191 VIXL_ASSERT(!rm.IsZero()); 2192 VIXL_ASSERT(!ra.IsZero()); 2193 SingleEmissionCheckScope guard(this); 2194 madd(rd, rn, rm, ra); 2195 } 2196 void Mneg(const Register& rd, const Register& rn, const Register& rm) { 2197 VIXL_ASSERT(allow_macro_instructions_); 2198 VIXL_ASSERT(!rd.IsZero()); 2199 VIXL_ASSERT(!rn.IsZero()); 2200 VIXL_ASSERT(!rm.IsZero()); 2201 SingleEmissionCheckScope guard(this); 2202 mneg(rd, rn, rm); 2203 } 2204 void Mov(const Register& rd, 2205 const Register& rn, 2206 DiscardMoveMode discard_mode = kDontDiscardForSameWReg) { 2207 VIXL_ASSERT(allow_macro_instructions_); 2208 // Emit a register move only if the registers are distinct, or if they are 2209 // not X registers. 2210 // 2211 // Note that mov(w0, w0) is not a no-op because it clears the top word of 2212 // x0. A flag is provided (kDiscardForSameWReg) if a move between the same W 2213 // registers is not required to clear the top word of the X register. In 2214 // this case, the instruction is discarded. 2215 // 2216 // If the sp is an operand, add #0 is emitted, otherwise, orr #0. 2217 if (!rd.Is(rn) || 2218 (rd.Is32Bits() && (discard_mode == kDontDiscardForSameWReg))) { 2219 SingleEmissionCheckScope guard(this); 2220 mov(rd, rn); 2221 } 2222 } 2223 void Movk(const Register& rd, uint64_t imm, int shift = -1) { 2224 VIXL_ASSERT(allow_macro_instructions_); 2225 VIXL_ASSERT(!rd.IsZero()); 2226 SingleEmissionCheckScope guard(this); 2227 movk(rd, imm, shift); 2228 } 2229 void Mrs(const Register& rt, SystemRegister sysreg) { 2230 VIXL_ASSERT(allow_macro_instructions_); 2231 VIXL_ASSERT(!rt.IsZero()); 2232 SingleEmissionCheckScope guard(this); 2233 mrs(rt, sysreg); 2234 } 2235 void Msr(SystemRegister sysreg, const Register& rt) { 2236 VIXL_ASSERT(allow_macro_instructions_); 2237 VIXL_ASSERT(!rt.IsZero()); 2238 SingleEmissionCheckScope guard(this); 2239 msr(sysreg, rt); 2240 } 2241 void Cfinv() { 2242 VIXL_ASSERT(allow_macro_instructions_); 2243 SingleEmissionCheckScope guard(this); 2244 cfinv(); 2245 } 2246 void Axflag() { 2247 VIXL_ASSERT(allow_macro_instructions_); 2248 SingleEmissionCheckScope guard(this); 2249 axflag(); 2250 } 2251 void Xaflag() { 2252 VIXL_ASSERT(allow_macro_instructions_); 2253 SingleEmissionCheckScope guard(this); 2254 xaflag(); 2255 } 2256 void Sys(int op1, int crn, int crm, int op2, const Register& rt = xzr) { 2257 VIXL_ASSERT(allow_macro_instructions_); 2258 SingleEmissionCheckScope guard(this); 2259 sys(op1, crn, crm, op2, rt); 2260 } 2261 void Dc(DataCacheOp op, const Register& rt) { 2262 VIXL_ASSERT(allow_macro_instructions_); 2263 SingleEmissionCheckScope guard(this); 2264 dc(op, rt); 2265 } 2266 void Ic(InstructionCacheOp op, const Register& rt) { 2267 VIXL_ASSERT(allow_macro_instructions_); 2268 SingleEmissionCheckScope guard(this); 2269 ic(op, rt); 2270 } 2271 void Msub(const Register& rd, 2272 const Register& rn, 2273 const Register& rm, 2274 const Register& ra) { 2275 VIXL_ASSERT(allow_macro_instructions_); 2276 VIXL_ASSERT(!rd.IsZero()); 2277 VIXL_ASSERT(!rn.IsZero()); 2278 VIXL_ASSERT(!rm.IsZero()); 2279 VIXL_ASSERT(!ra.IsZero()); 2280 SingleEmissionCheckScope guard(this); 2281 msub(rd, rn, rm, ra); 2282 } 2283 void Mul(const Register& rd, const Register& rn, const Register& rm) { 2284 VIXL_ASSERT(allow_macro_instructions_); 2285 VIXL_ASSERT(!rd.IsZero()); 2286 VIXL_ASSERT(!rn.IsZero()); 2287 VIXL_ASSERT(!rm.IsZero()); 2288 SingleEmissionCheckScope guard(this); 2289 mul(rd, rn, rm); 2290 } 2291 void Nop() { 2292 VIXL_ASSERT(allow_macro_instructions_); 2293 SingleEmissionCheckScope guard(this); 2294 nop(); 2295 } 2296 void Rbit(const Register& rd, const Register& rn) { 2297 VIXL_ASSERT(allow_macro_instructions_); 2298 VIXL_ASSERT(!rd.IsZero()); 2299 VIXL_ASSERT(!rn.IsZero()); 2300 SingleEmissionCheckScope guard(this); 2301 rbit(rd, rn); 2302 } 2303 void Ret(const Register& xn = lr) { 2304 VIXL_ASSERT(allow_macro_instructions_); 2305 VIXL_ASSERT(!xn.IsZero()); 2306 SingleEmissionCheckScope guard(this); 2307 ret(xn); 2308 } 2309 void Rev(const Register& rd, const Register& rn) { 2310 VIXL_ASSERT(allow_macro_instructions_); 2311 VIXL_ASSERT(!rd.IsZero()); 2312 VIXL_ASSERT(!rn.IsZero()); 2313 SingleEmissionCheckScope guard(this); 2314 rev(rd, rn); 2315 } 2316 void Rev16(const Register& rd, const Register& rn) { 2317 VIXL_ASSERT(allow_macro_instructions_); 2318 VIXL_ASSERT(!rd.IsZero()); 2319 VIXL_ASSERT(!rn.IsZero()); 2320 SingleEmissionCheckScope guard(this); 2321 rev16(rd, rn); 2322 } 2323 void Rev32(const Register& rd, const Register& rn) { 2324 VIXL_ASSERT(allow_macro_instructions_); 2325 VIXL_ASSERT(!rd.IsZero()); 2326 VIXL_ASSERT(!rn.IsZero()); 2327 SingleEmissionCheckScope guard(this); 2328 rev32(rd, rn); 2329 } 2330 void Rev64(const Register& rd, const Register& rn) { 2331 VIXL_ASSERT(allow_macro_instructions_); 2332 VIXL_ASSERT(!rd.IsZero()); 2333 VIXL_ASSERT(!rn.IsZero()); 2334 SingleEmissionCheckScope guard(this); 2335 rev64(rd, rn); 2336 } 2337 2338#define PAUTH_MASM_VARIATIONS(V) \ 2339 V(Paci, paci) \ 2340 V(Pacd, pacd) \ 2341 V(Auti, auti) \ 2342 V(Autd, autd) 2343 2344#define DEFINE_MACRO_ASM_FUNCS(MASM_PRE, ASM_PRE) \ 2345 void MASM_PRE##a(const Register& xd, const Register& xn) { \ 2346 VIXL_ASSERT(allow_macro_instructions_); \ 2347 SingleEmissionCheckScope guard(this); \ 2348 ASM_PRE##a(xd, xn); \ 2349 } \ 2350 void MASM_PRE##za(const Register& xd) { \ 2351 VIXL_ASSERT(allow_macro_instructions_); \ 2352 SingleEmissionCheckScope guard(this); \ 2353 ASM_PRE##za(xd); \ 2354 } \ 2355 void MASM_PRE##b(const Register& xd, const Register& xn) { \ 2356 VIXL_ASSERT(allow_macro_instructions_); \ 2357 SingleEmissionCheckScope guard(this); \ 2358 ASM_PRE##b(xd, xn); \ 2359 } \ 2360 void MASM_PRE##zb(const Register& xd) { \ 2361 VIXL_ASSERT(allow_macro_instructions_); \ 2362 SingleEmissionCheckScope guard(this); \ 2363 ASM_PRE##zb(xd); \ 2364 } 2365 2366 PAUTH_MASM_VARIATIONS(DEFINE_MACRO_ASM_FUNCS) 2367#undef DEFINE_MACRO_ASM_FUNCS 2368 2369 void Pacga(const Register& xd, const Register& xn, const Register& xm) { 2370 VIXL_ASSERT(allow_macro_instructions_); 2371 SingleEmissionCheckScope guard(this); 2372 pacga(xd, xn, xm); 2373 } 2374 2375 void Xpaci(const Register& xd) { 2376 VIXL_ASSERT(allow_macro_instructions_); 2377 SingleEmissionCheckScope guard(this); 2378 xpaci(xd); 2379 } 2380 2381 void Xpacd(const Register& xd) { 2382 VIXL_ASSERT(allow_macro_instructions_); 2383 SingleEmissionCheckScope guard(this); 2384 xpacd(xd); 2385 } 2386 void Ror(const Register& rd, const Register& rs, unsigned shift) { 2387 VIXL_ASSERT(allow_macro_instructions_); 2388 VIXL_ASSERT(!rd.IsZero()); 2389 VIXL_ASSERT(!rs.IsZero()); 2390 SingleEmissionCheckScope guard(this); 2391 ror(rd, rs, shift); 2392 } 2393 void Ror(const Register& rd, const Register& rn, const Register& rm) { 2394 VIXL_ASSERT(allow_macro_instructions_); 2395 VIXL_ASSERT(!rd.IsZero()); 2396 VIXL_ASSERT(!rn.IsZero()); 2397 VIXL_ASSERT(!rm.IsZero()); 2398 SingleEmissionCheckScope guard(this); 2399 rorv(rd, rn, rm); 2400 } 2401 void Sbfiz(const Register& rd, 2402 const Register& rn, 2403 unsigned lsb, 2404 unsigned width) { 2405 VIXL_ASSERT(allow_macro_instructions_); 2406 VIXL_ASSERT(!rd.IsZero()); 2407 VIXL_ASSERT(!rn.IsZero()); 2408 SingleEmissionCheckScope guard(this); 2409 sbfiz(rd, rn, lsb, width); 2410 } 2411 void Sbfm(const Register& rd, 2412 const Register& rn, 2413 unsigned immr, 2414 unsigned imms) { 2415 VIXL_ASSERT(allow_macro_instructions_); 2416 VIXL_ASSERT(!rd.IsZero()); 2417 VIXL_ASSERT(!rn.IsZero()); 2418 SingleEmissionCheckScope guard(this); 2419 sbfm(rd, rn, immr, imms); 2420 } 2421 void Sbfx(const Register& rd, 2422 const Register& rn, 2423 unsigned lsb, 2424 unsigned width) { 2425 VIXL_ASSERT(allow_macro_instructions_); 2426 VIXL_ASSERT(!rd.IsZero()); 2427 VIXL_ASSERT(!rn.IsZero()); 2428 SingleEmissionCheckScope guard(this); 2429 sbfx(rd, rn, lsb, width); 2430 } 2431 void Scvtf(const VRegister& vd, const Register& rn, int fbits = 0) { 2432 VIXL_ASSERT(allow_macro_instructions_); 2433 VIXL_ASSERT(!rn.IsZero()); 2434 SingleEmissionCheckScope guard(this); 2435 scvtf(vd, rn, fbits); 2436 } 2437 void Sdiv(const Register& rd, const Register& rn, const Register& rm) { 2438 VIXL_ASSERT(allow_macro_instructions_); 2439 VIXL_ASSERT(!rd.IsZero()); 2440 VIXL_ASSERT(!rn.IsZero()); 2441 VIXL_ASSERT(!rm.IsZero()); 2442 SingleEmissionCheckScope guard(this); 2443 sdiv(rd, rn, rm); 2444 } 2445 void Smaddl(const Register& rd, 2446 const Register& rn, 2447 const Register& rm, 2448 const Register& ra) { 2449 VIXL_ASSERT(allow_macro_instructions_); 2450 VIXL_ASSERT(!rd.IsZero()); 2451 VIXL_ASSERT(!rn.IsZero()); 2452 VIXL_ASSERT(!rm.IsZero()); 2453 VIXL_ASSERT(!ra.IsZero()); 2454 SingleEmissionCheckScope guard(this); 2455 smaddl(rd, rn, rm, ra); 2456 } 2457 void Smsubl(const Register& rd, 2458 const Register& rn, 2459 const Register& rm, 2460 const Register& ra) { 2461 VIXL_ASSERT(allow_macro_instructions_); 2462 VIXL_ASSERT(!rd.IsZero()); 2463 VIXL_ASSERT(!rn.IsZero()); 2464 VIXL_ASSERT(!rm.IsZero()); 2465 VIXL_ASSERT(!ra.IsZero()); 2466 SingleEmissionCheckScope guard(this); 2467 smsubl(rd, rn, rm, ra); 2468 } 2469 void Smull(const Register& rd, const Register& rn, const Register& rm) { 2470 VIXL_ASSERT(allow_macro_instructions_); 2471 VIXL_ASSERT(!rd.IsZero()); 2472 VIXL_ASSERT(!rn.IsZero()); 2473 VIXL_ASSERT(!rm.IsZero()); 2474 SingleEmissionCheckScope guard(this); 2475 smull(rd, rn, rm); 2476 } 2477 void Smulh(const Register& xd, const Register& xn, const Register& xm) { 2478 VIXL_ASSERT(allow_macro_instructions_); 2479 VIXL_ASSERT(!xd.IsZero()); 2480 VIXL_ASSERT(!xn.IsZero()); 2481 VIXL_ASSERT(!xm.IsZero()); 2482 SingleEmissionCheckScope guard(this); 2483 smulh(xd, xn, xm); 2484 } 2485 void Stlr(const Register& rt, const MemOperand& dst) { 2486 VIXL_ASSERT(allow_macro_instructions_); 2487 SingleEmissionCheckScope guard(this); 2488 VIXL_ASSERT(dst.IsImmediateOffset()); 2489 if (dst.GetOffset() == 0) { 2490 stlr(rt, dst); 2491 } else { 2492 stlur(rt, dst); 2493 } 2494 } 2495 void Stlrb(const Register& rt, const MemOperand& dst) { 2496 VIXL_ASSERT(allow_macro_instructions_); 2497 SingleEmissionCheckScope guard(this); 2498 VIXL_ASSERT(dst.IsImmediateOffset()); 2499 if (dst.GetOffset() == 0) { 2500 stlrb(rt, dst); 2501 } else { 2502 stlurb(rt, dst); 2503 } 2504 } 2505 void Stlrh(const Register& rt, const MemOperand& dst) { 2506 VIXL_ASSERT(allow_macro_instructions_); 2507 SingleEmissionCheckScope guard(this); 2508 VIXL_ASSERT(dst.IsImmediateOffset()); 2509 if (dst.GetOffset() == 0) { 2510 stlrh(rt, dst); 2511 } else { 2512 stlurh(rt, dst); 2513 } 2514 } 2515 void Stllr(const Register& rt, const MemOperand& dst) { 2516 VIXL_ASSERT(allow_macro_instructions_); 2517 SingleEmissionCheckScope guard(this); 2518 stllr(rt, dst); 2519 } 2520 void Stllrb(const Register& rt, const MemOperand& dst) { 2521 VIXL_ASSERT(allow_macro_instructions_); 2522 SingleEmissionCheckScope guard(this); 2523 stllrb(rt, dst); 2524 } 2525 void Stllrh(const Register& rt, const MemOperand& dst) { 2526 VIXL_ASSERT(allow_macro_instructions_); 2527 SingleEmissionCheckScope guard(this); 2528 stllrh(rt, dst); 2529 } 2530 void Stlxp(const Register& rs, 2531 const Register& rt, 2532 const Register& rt2, 2533 const MemOperand& dst) { 2534 VIXL_ASSERT(allow_macro_instructions_); 2535 VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister())); 2536 VIXL_ASSERT(!rs.Aliases(rt)); 2537 VIXL_ASSERT(!rs.Aliases(rt2)); 2538 SingleEmissionCheckScope guard(this); 2539 stlxp(rs, rt, rt2, dst); 2540 } 2541 void Stlxr(const Register& rs, const Register& rt, const MemOperand& dst) { 2542 VIXL_ASSERT(allow_macro_instructions_); 2543 VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister())); 2544 VIXL_ASSERT(!rs.Aliases(rt)); 2545 SingleEmissionCheckScope guard(this); 2546 stlxr(rs, rt, dst); 2547 } 2548 void Stlxrb(const Register& rs, const Register& rt, const MemOperand& dst) { 2549 VIXL_ASSERT(allow_macro_instructions_); 2550 VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister())); 2551 VIXL_ASSERT(!rs.Aliases(rt)); 2552 SingleEmissionCheckScope guard(this); 2553 stlxrb(rs, rt, dst); 2554 } 2555 void Stlxrh(const Register& rs, const Register& rt, const MemOperand& dst) { 2556 VIXL_ASSERT(allow_macro_instructions_); 2557 VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister())); 2558 VIXL_ASSERT(!rs.Aliases(rt)); 2559 SingleEmissionCheckScope guard(this); 2560 stlxrh(rs, rt, dst); 2561 } 2562 void Stnp(const CPURegister& rt, 2563 const CPURegister& rt2, 2564 const MemOperand& dst) { 2565 VIXL_ASSERT(allow_macro_instructions_); 2566 SingleEmissionCheckScope guard(this); 2567 stnp(rt, rt2, dst); 2568 } 2569 void Stxp(const Register& rs, 2570 const Register& rt, 2571 const Register& rt2, 2572 const MemOperand& dst) { 2573 VIXL_ASSERT(allow_macro_instructions_); 2574 VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister())); 2575 VIXL_ASSERT(!rs.Aliases(rt)); 2576 VIXL_ASSERT(!rs.Aliases(rt2)); 2577 SingleEmissionCheckScope guard(this); 2578 stxp(rs, rt, rt2, dst); 2579 } 2580 void Stxr(const Register& rs, const Register& rt, const MemOperand& dst) { 2581 VIXL_ASSERT(allow_macro_instructions_); 2582 VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister())); 2583 VIXL_ASSERT(!rs.Aliases(rt)); 2584 SingleEmissionCheckScope guard(this); 2585 stxr(rs, rt, dst); 2586 } 2587 void Stxrb(const Register& rs, const Register& rt, const MemOperand& dst) { 2588 VIXL_ASSERT(allow_macro_instructions_); 2589 VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister())); 2590 VIXL_ASSERT(!rs.Aliases(rt)); 2591 SingleEmissionCheckScope guard(this); 2592 stxrb(rs, rt, dst); 2593 } 2594 void Stxrh(const Register& rs, const Register& rt, const MemOperand& dst) { 2595 VIXL_ASSERT(allow_macro_instructions_); 2596 VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister())); 2597 VIXL_ASSERT(!rs.Aliases(rt)); 2598 SingleEmissionCheckScope guard(this); 2599 stxrh(rs, rt, dst); 2600 } 2601 void Svc(int code) { 2602 VIXL_ASSERT(allow_macro_instructions_); 2603 SingleEmissionCheckScope guard(this); 2604 svc(code); 2605 } 2606 void Sxtb(const Register& rd, const Register& rn) { 2607 VIXL_ASSERT(allow_macro_instructions_); 2608 VIXL_ASSERT(!rd.IsZero()); 2609 VIXL_ASSERT(!rn.IsZero()); 2610 SingleEmissionCheckScope guard(this); 2611 sxtb(rd, rn); 2612 } 2613 void Sxth(const Register& rd, const Register& rn) { 2614 VIXL_ASSERT(allow_macro_instructions_); 2615 VIXL_ASSERT(!rd.IsZero()); 2616 VIXL_ASSERT(!rn.IsZero()); 2617 SingleEmissionCheckScope guard(this); 2618 sxth(rd, rn); 2619 } 2620 void Sxtw(const Register& rd, const Register& rn) { 2621 VIXL_ASSERT(allow_macro_instructions_); 2622 VIXL_ASSERT(!rd.IsZero()); 2623 VIXL_ASSERT(!rn.IsZero()); 2624 SingleEmissionCheckScope guard(this); 2625 sxtw(rd, rn); 2626 } 2627 void Tbl(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 2628 VIXL_ASSERT(allow_macro_instructions_); 2629 SingleEmissionCheckScope guard(this); 2630 tbl(vd, vn, vm); 2631 } 2632 void Tbl(const VRegister& vd, 2633 const VRegister& vn, 2634 const VRegister& vn2, 2635 const VRegister& vm) { 2636 VIXL_ASSERT(allow_macro_instructions_); 2637 SingleEmissionCheckScope guard(this); 2638 tbl(vd, vn, vn2, vm); 2639 } 2640 void Tbl(const VRegister& vd, 2641 const VRegister& vn, 2642 const VRegister& vn2, 2643 const VRegister& vn3, 2644 const VRegister& vm) { 2645 VIXL_ASSERT(allow_macro_instructions_); 2646 SingleEmissionCheckScope guard(this); 2647 tbl(vd, vn, vn2, vn3, vm); 2648 } 2649 void Tbl(const VRegister& vd, 2650 const VRegister& vn, 2651 const VRegister& vn2, 2652 const VRegister& vn3, 2653 const VRegister& vn4, 2654 const VRegister& vm) { 2655 VIXL_ASSERT(allow_macro_instructions_); 2656 SingleEmissionCheckScope guard(this); 2657 tbl(vd, vn, vn2, vn3, vn4, vm); 2658 } 2659 void Tbx(const VRegister& vd, const VRegister& vn, const VRegister& vm) { 2660 VIXL_ASSERT(allow_macro_instructions_); 2661 SingleEmissionCheckScope guard(this); 2662 tbx(vd, vn, vm); 2663 } 2664 void Tbx(const VRegister& vd, 2665 const VRegister& vn, 2666 const VRegister& vn2, 2667 const VRegister& vm) { 2668 VIXL_ASSERT(allow_macro_instructions_); 2669 SingleEmissionCheckScope guard(this); 2670 tbx(vd, vn, vn2, vm); 2671 } 2672 void Tbx(const VRegister& vd, 2673 const VRegister& vn, 2674 const VRegister& vn2, 2675 const VRegister& vn3, 2676 const VRegister& vm) { 2677 VIXL_ASSERT(allow_macro_instructions_); 2678 SingleEmissionCheckScope guard(this); 2679 tbx(vd, vn, vn2, vn3, vm); 2680 } 2681 void Tbx(const VRegister& vd, 2682 const VRegister& vn, 2683 const VRegister& vn2, 2684 const VRegister& vn3, 2685 const VRegister& vn4, 2686 const VRegister& vm) { 2687 VIXL_ASSERT(allow_macro_instructions_); 2688 SingleEmissionCheckScope guard(this); 2689 tbx(vd, vn, vn2, vn3, vn4, vm); 2690 } 2691 void Tbnz(const Register& rt, unsigned bit_pos, Label* label); 2692 void Tbz(const Register& rt, unsigned bit_pos, Label* label); 2693 void Ubfiz(const Register& rd, 2694 const Register& rn, 2695 unsigned lsb, 2696 unsigned width) { 2697 VIXL_ASSERT(allow_macro_instructions_); 2698 VIXL_ASSERT(!rd.IsZero()); 2699 VIXL_ASSERT(!rn.IsZero()); 2700 SingleEmissionCheckScope guard(this); 2701 ubfiz(rd, rn, lsb, width); 2702 } 2703 void Ubfm(const Register& rd, 2704 const Register& rn, 2705 unsigned immr, 2706 unsigned imms) { 2707 VIXL_ASSERT(allow_macro_instructions_); 2708 VIXL_ASSERT(!rd.IsZero()); 2709 VIXL_ASSERT(!rn.IsZero()); 2710 SingleEmissionCheckScope guard(this); 2711 ubfm(rd, rn, immr, imms); 2712 } 2713 void Ubfx(const Register& rd, 2714 const Register& rn, 2715 unsigned lsb, 2716 unsigned width) { 2717 VIXL_ASSERT(allow_macro_instructions_); 2718 VIXL_ASSERT(!rd.IsZero()); 2719 VIXL_ASSERT(!rn.IsZero()); 2720 SingleEmissionCheckScope guard(this); 2721 ubfx(rd, rn, lsb, width); 2722 } 2723 void Ucvtf(const VRegister& vd, const Register& rn, int fbits = 0) { 2724 VIXL_ASSERT(allow_macro_instructions_); 2725 VIXL_ASSERT(!rn.IsZero()); 2726 SingleEmissionCheckScope guard(this); 2727 ucvtf(vd, rn, fbits); 2728 } 2729 void Udiv(const Register& rd, const Register& rn, const Register& rm) { 2730 VIXL_ASSERT(allow_macro_instructions_); 2731 VIXL_ASSERT(!rd.IsZero()); 2732 VIXL_ASSERT(!rn.IsZero()); 2733 VIXL_ASSERT(!rm.IsZero()); 2734 SingleEmissionCheckScope guard(this); 2735 udiv(rd, rn, rm); 2736 } 2737 void Umaddl(const Register& rd, 2738 const Register& rn, 2739 const Register& rm, 2740 const Register& ra) { 2741 VIXL_ASSERT(allow_macro_instructions_); 2742 VIXL_ASSERT(!rd.IsZero()); 2743 VIXL_ASSERT(!rn.IsZero()); 2744 VIXL_ASSERT(!rm.IsZero()); 2745 VIXL_ASSERT(!ra.IsZero()); 2746 SingleEmissionCheckScope guard(this); 2747 umaddl(rd, rn, rm, ra); 2748 } 2749 void Umull(const Register& rd, const Register& rn, const Register& rm) { 2750 VIXL_ASSERT(allow_macro_instructions_); 2751 VIXL_ASSERT(!rd.IsZero()); 2752 VIXL_ASSERT(!rn.IsZero()); 2753 VIXL_ASSERT(!rm.IsZero()); 2754 SingleEmissionCheckScope guard(this); 2755 umull(rd, rn, rm); 2756 } 2757 void Umulh(const Register& xd, const Register& xn, const Register& xm) { 2758 VIXL_ASSERT(allow_macro_instructions_); 2759 VIXL_ASSERT(!xd.IsZero()); 2760 VIXL_ASSERT(!xn.IsZero()); 2761 VIXL_ASSERT(!xm.IsZero()); 2762 SingleEmissionCheckScope guard(this); 2763 umulh(xd, xn, xm); 2764 } 2765 void Umsubl(const Register& rd, 2766 const Register& rn, 2767 const Register& rm, 2768 const Register& ra) { 2769 VIXL_ASSERT(allow_macro_instructions_); 2770 VIXL_ASSERT(!rd.IsZero()); 2771 VIXL_ASSERT(!rn.IsZero()); 2772 VIXL_ASSERT(!rm.IsZero()); 2773 VIXL_ASSERT(!ra.IsZero()); 2774 SingleEmissionCheckScope guard(this); 2775 umsubl(rd, rn, rm, ra); 2776 } 2777 void Unreachable() { 2778 VIXL_ASSERT(allow_macro_instructions_); 2779 SingleEmissionCheckScope guard(this); 2780 if (generate_simulator_code_) { 2781 hlt(kUnreachableOpcode); 2782 } else { 2783 // Use the architecturally-defined UDF instruction to abort on hardware, 2784 // because using HLT and BRK tends to make the process difficult to debug. 2785 udf(kUnreachableOpcode); 2786 } 2787 } 2788 void Uxtb(const Register& rd, const Register& rn) { 2789 VIXL_ASSERT(allow_macro_instructions_); 2790 VIXL_ASSERT(!rd.IsZero()); 2791 VIXL_ASSERT(!rn.IsZero()); 2792 SingleEmissionCheckScope guard(this); 2793 uxtb(rd, rn); 2794 } 2795 void Uxth(const Register& rd, const Register& rn) { 2796 VIXL_ASSERT(allow_macro_instructions_); 2797 VIXL_ASSERT(!rd.IsZero()); 2798 VIXL_ASSERT(!rn.IsZero()); 2799 SingleEmissionCheckScope guard(this); 2800 uxth(rd, rn); 2801 } 2802 void Uxtw(const Register& rd, const Register& rn) { 2803 VIXL_ASSERT(allow_macro_instructions_); 2804 VIXL_ASSERT(!rd.IsZero()); 2805 VIXL_ASSERT(!rn.IsZero()); 2806 SingleEmissionCheckScope guard(this); 2807 uxtw(rd, rn); 2808 } 2809 2810 void Addg(const Register& xd, 2811 const Register& xn, 2812 int offset, 2813 int tag_offset) { 2814 VIXL_ASSERT(allow_macro_instructions_); 2815 SingleEmissionCheckScope guard(this); 2816 addg(xd, xn, offset, tag_offset); 2817 } 2818 void Gmi(const Register& xd, const Register& xn, const Register& xm) { 2819 VIXL_ASSERT(allow_macro_instructions_); 2820 SingleEmissionCheckScope guard(this); 2821 gmi(xd, xn, xm); 2822 } 2823 void Irg(const Register& xd, const Register& xn, const Register& xm = xzr) { 2824 VIXL_ASSERT(allow_macro_instructions_); 2825 SingleEmissionCheckScope guard(this); 2826 irg(xd, xn, xm); 2827 } 2828 void Subg(const Register& xd, 2829 const Register& xn, 2830 int offset, 2831 int tag_offset) { 2832 VIXL_ASSERT(allow_macro_instructions_); 2833 SingleEmissionCheckScope guard(this); 2834 subg(xd, xn, offset, tag_offset); 2835 } 2836 void Subp(const Register& xd, const Register& xn, const Register& xm) { 2837 VIXL_ASSERT(allow_macro_instructions_); 2838 SingleEmissionCheckScope guard(this); 2839 subp(xd, xn, xm); 2840 } 2841 void Subps(const Register& xd, const Register& xn, const Register& xm) { 2842 VIXL_ASSERT(allow_macro_instructions_); 2843 SingleEmissionCheckScope guard(this); 2844 subps(xd, xn, xm); 2845 } 2846 void Cmpp(const Register& xn, const Register& xm) { Subps(xzr, xn, xm); } 2847 2848// NEON 3 vector register instructions. 2849#define NEON_3VREG_MACRO_LIST(V) \ 2850 V(add, Add) \ 2851 V(addhn, Addhn) \ 2852 V(addhn2, Addhn2) \ 2853 V(addp, Addp) \ 2854 V(and_, And) \ 2855 V(bic, Bic) \ 2856 V(bif, Bif) \ 2857 V(bit, Bit) \ 2858 V(bsl, Bsl) \ 2859 V(cmeq, Cmeq) \ 2860 V(cmge, Cmge) \ 2861 V(cmgt, Cmgt) \ 2862 V(cmhi, Cmhi) \ 2863 V(cmhs, Cmhs) \ 2864 V(cmtst, Cmtst) \ 2865 V(eor, Eor) \ 2866 V(fabd, Fabd) \ 2867 V(facge, Facge) \ 2868 V(facgt, Facgt) \ 2869 V(faddp, Faddp) \ 2870 V(fcmeq, Fcmeq) \ 2871 V(fcmge, Fcmge) \ 2872 V(fcmgt, Fcmgt) \ 2873 V(fmaxnmp, Fmaxnmp) \ 2874 V(fmaxp, Fmaxp) \ 2875 V(fminnmp, Fminnmp) \ 2876 V(fminp, Fminp) \ 2877 V(fmla, Fmla) \ 2878 V(fmlal, Fmlal) \ 2879 V(fmlal2, Fmlal2) \ 2880 V(fmls, Fmls) \ 2881 V(fmlsl, Fmlsl) \ 2882 V(fmlsl2, Fmlsl2) \ 2883 V(fmulx, Fmulx) \ 2884 V(frecps, Frecps) \ 2885 V(frsqrts, Frsqrts) \ 2886 V(mla, Mla) \ 2887 V(mls, Mls) \ 2888 V(mul, Mul) \ 2889 V(orn, Orn) \ 2890 V(orr, Orr) \ 2891 V(pmul, Pmul) \ 2892 V(pmull, Pmull) \ 2893 V(pmull2, Pmull2) \ 2894 V(raddhn, Raddhn) \ 2895 V(raddhn2, Raddhn2) \ 2896 V(rsubhn, Rsubhn) \ 2897 V(rsubhn2, Rsubhn2) \ 2898 V(saba, Saba) \ 2899 V(sabal, Sabal) \ 2900 V(sabal2, Sabal2) \ 2901 V(sabd, Sabd) \ 2902 V(sabdl, Sabdl) \ 2903 V(sabdl2, Sabdl2) \ 2904 V(saddl, Saddl) \ 2905 V(saddl2, Saddl2) \ 2906 V(saddw, Saddw) \ 2907 V(saddw2, Saddw2) \ 2908 V(shadd, Shadd) \ 2909 V(shsub, Shsub) \ 2910 V(smax, Smax) \ 2911 V(smaxp, Smaxp) \ 2912 V(smin, Smin) \ 2913 V(sminp, Sminp) \ 2914 V(smlal, Smlal) \ 2915 V(smlal2, Smlal2) \ 2916 V(smlsl, Smlsl) \ 2917 V(smlsl2, Smlsl2) \ 2918 V(smull, Smull) \ 2919 V(smull2, Smull2) \ 2920 V(sqadd, Sqadd) \ 2921 V(sqdmlal, Sqdmlal) \ 2922 V(sqdmlal2, Sqdmlal2) \ 2923 V(sqdmlsl, Sqdmlsl) \ 2924 V(sqdmlsl2, Sqdmlsl2) \ 2925 V(sqdmulh, Sqdmulh) \ 2926 V(sqdmull, Sqdmull) \ 2927 V(sqdmull2, Sqdmull2) \ 2928 V(sqrdmulh, Sqrdmulh) \ 2929 V(sdot, Sdot) \ 2930 V(sqrdmlah, Sqrdmlah) \ 2931 V(udot, Udot) \ 2932 V(sqrdmlsh, Sqrdmlsh) \ 2933 V(sqrshl, Sqrshl) \ 2934 V(sqshl, Sqshl) \ 2935 V(sqsub, Sqsub) \ 2936 V(srhadd, Srhadd) \ 2937 V(srshl, Srshl) \ 2938 V(sshl, Sshl) \ 2939 V(ssubl, Ssubl) \ 2940 V(ssubl2, Ssubl2) \ 2941 V(ssubw, Ssubw) \ 2942 V(ssubw2, Ssubw2) \ 2943 V(sub, Sub) \ 2944 V(subhn, Subhn) \ 2945 V(subhn2, Subhn2) \ 2946 V(trn1, Trn1) \ 2947 V(trn2, Trn2) \ 2948 V(uaba, Uaba) \ 2949 V(uabal, Uabal) \ 2950 V(uabal2, Uabal2) \ 2951 V(uabd, Uabd) \ 2952 V(uabdl, Uabdl) \ 2953 V(uabdl2, Uabdl2) \ 2954 V(uaddl, Uaddl) \ 2955 V(uaddl2, Uaddl2) \ 2956 V(uaddw, Uaddw) \ 2957 V(uaddw2, Uaddw2) \ 2958 V(uhadd, Uhadd) \ 2959 V(uhsub, Uhsub) \ 2960 V(umax, Umax) \ 2961 V(umaxp, Umaxp) \ 2962 V(umin, Umin) \ 2963 V(uminp, Uminp) \ 2964 V(umlal, Umlal) \ 2965 V(umlal2, Umlal2) \ 2966 V(umlsl, Umlsl) \ 2967 V(umlsl2, Umlsl2) \ 2968 V(umull, Umull) \ 2969 V(umull2, Umull2) \ 2970 V(uqadd, Uqadd) \ 2971 V(uqrshl, Uqrshl) \ 2972 V(uqshl, Uqshl) \ 2973 V(uqsub, Uqsub) \ 2974 V(urhadd, Urhadd) \ 2975 V(urshl, Urshl) \ 2976 V(ushl, Ushl) \ 2977 V(usubl, Usubl) \ 2978 V(usubl2, Usubl2) \ 2979 V(usubw, Usubw) \ 2980 V(usubw2, Usubw2) \ 2981 V(uzp1, Uzp1) \ 2982 V(uzp2, Uzp2) \ 2983 V(zip1, Zip1) \ 2984 V(zip2, Zip2) \ 2985 V(smmla, Smmla) \ 2986 V(ummla, Ummla) \ 2987 V(usmmla, Usmmla) \ 2988 V(usdot, Usdot) 2989 2990#define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \ 2991 void MASM(const VRegister& vd, const VRegister& vn, const VRegister& vm) { \ 2992 VIXL_ASSERT(allow_macro_instructions_); \ 2993 SingleEmissionCheckScope guard(this); \ 2994 ASM(vd, vn, vm); \ 2995 } 2996 NEON_3VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 2997#undef DEFINE_MACRO_ASM_FUNC 2998 2999// NEON 2 vector register instructions. 3000#define NEON_2VREG_MACRO_LIST(V) \ 3001 V(abs, Abs) \ 3002 V(addp, Addp) \ 3003 V(addv, Addv) \ 3004 V(cls, Cls) \ 3005 V(clz, Clz) \ 3006 V(cnt, Cnt) \ 3007 V(fabs, Fabs) \ 3008 V(faddp, Faddp) \ 3009 V(fcvtas, Fcvtas) \ 3010 V(fcvtau, Fcvtau) \ 3011 V(fcvtms, Fcvtms) \ 3012 V(fcvtmu, Fcvtmu) \ 3013 V(fcvtns, Fcvtns) \ 3014 V(fcvtnu, Fcvtnu) \ 3015 V(fcvtps, Fcvtps) \ 3016 V(fcvtpu, Fcvtpu) \ 3017 V(fmaxnmp, Fmaxnmp) \ 3018 V(fmaxnmv, Fmaxnmv) \ 3019 V(fmaxp, Fmaxp) \ 3020 V(fmaxv, Fmaxv) \ 3021 V(fminnmp, Fminnmp) \ 3022 V(fminnmv, Fminnmv) \ 3023 V(fminp, Fminp) \ 3024 V(fminv, Fminv) \ 3025 V(fneg, Fneg) \ 3026 V(frecpe, Frecpe) \ 3027 V(frecpx, Frecpx) \ 3028 V(frint32x, Frint32x) \ 3029 V(frint32z, Frint32z) \ 3030 V(frint64x, Frint64x) \ 3031 V(frint64z, Frint64z) \ 3032 V(frinta, Frinta) \ 3033 V(frinti, Frinti) \ 3034 V(frintm, Frintm) \ 3035 V(frintn, Frintn) \ 3036 V(frintp, Frintp) \ 3037 V(frintx, Frintx) \ 3038 V(frintz, Frintz) \ 3039 V(frsqrte, Frsqrte) \ 3040 V(fsqrt, Fsqrt) \ 3041 V(mov, Mov) \ 3042 V(mvn, Mvn) \ 3043 V(neg, Neg) \ 3044 V(not_, Not) \ 3045 V(rbit, Rbit) \ 3046 V(rev16, Rev16) \ 3047 V(rev32, Rev32) \ 3048 V(rev64, Rev64) \ 3049 V(sadalp, Sadalp) \ 3050 V(saddlp, Saddlp) \ 3051 V(saddlv, Saddlv) \ 3052 V(smaxv, Smaxv) \ 3053 V(sminv, Sminv) \ 3054 V(sqabs, Sqabs) \ 3055 V(sqneg, Sqneg) \ 3056 V(sqxtn, Sqxtn) \ 3057 V(sqxtn2, Sqxtn2) \ 3058 V(sqxtun, Sqxtun) \ 3059 V(sqxtun2, Sqxtun2) \ 3060 V(suqadd, Suqadd) \ 3061 V(sxtl, Sxtl) \ 3062 V(sxtl2, Sxtl2) \ 3063 V(uadalp, Uadalp) \ 3064 V(uaddlp, Uaddlp) \ 3065 V(uaddlv, Uaddlv) \ 3066 V(umaxv, Umaxv) \ 3067 V(uminv, Uminv) \ 3068 V(uqxtn, Uqxtn) \ 3069 V(uqxtn2, Uqxtn2) \ 3070 V(urecpe, Urecpe) \ 3071 V(ursqrte, Ursqrte) \ 3072 V(usqadd, Usqadd) \ 3073 V(uxtl, Uxtl) \ 3074 V(uxtl2, Uxtl2) \ 3075 V(xtn, Xtn) \ 3076 V(xtn2, Xtn2) 3077 3078#define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \ 3079 void MASM(const VRegister& vd, const VRegister& vn) { \ 3080 VIXL_ASSERT(allow_macro_instructions_); \ 3081 SingleEmissionCheckScope guard(this); \ 3082 ASM(vd, vn); \ 3083 } 3084 NEON_2VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 3085#undef DEFINE_MACRO_ASM_FUNC 3086 3087// NEON 2 vector register with immediate instructions. 3088#define NEON_2VREG_FPIMM_MACRO_LIST(V) \ 3089 V(fcmeq, Fcmeq) \ 3090 V(fcmge, Fcmge) \ 3091 V(fcmgt, Fcmgt) \ 3092 V(fcmle, Fcmle) \ 3093 V(fcmlt, Fcmlt) 3094 3095#define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \ 3096 void MASM(const VRegister& vd, const VRegister& vn, double imm) { \ 3097 VIXL_ASSERT(allow_macro_instructions_); \ 3098 SingleEmissionCheckScope guard(this); \ 3099 ASM(vd, vn, imm); \ 3100 } 3101 NEON_2VREG_FPIMM_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 3102#undef DEFINE_MACRO_ASM_FUNC 3103 3104// NEON by element instructions. 3105#define NEON_BYELEMENT_MACRO_LIST(V) \ 3106 V(fmul, Fmul) \ 3107 V(fmla, Fmla) \ 3108 V(fmlal, Fmlal) \ 3109 V(fmlal2, Fmlal2) \ 3110 V(fmls, Fmls) \ 3111 V(fmlsl, Fmlsl) \ 3112 V(fmlsl2, Fmlsl2) \ 3113 V(fmulx, Fmulx) \ 3114 V(mul, Mul) \ 3115 V(mla, Mla) \ 3116 V(mls, Mls) \ 3117 V(sqdmulh, Sqdmulh) \ 3118 V(sqrdmulh, Sqrdmulh) \ 3119 V(sdot, Sdot) \ 3120 V(sqrdmlah, Sqrdmlah) \ 3121 V(udot, Udot) \ 3122 V(sqrdmlsh, Sqrdmlsh) \ 3123 V(sqdmull, Sqdmull) \ 3124 V(sqdmull2, Sqdmull2) \ 3125 V(sqdmlal, Sqdmlal) \ 3126 V(sqdmlal2, Sqdmlal2) \ 3127 V(sqdmlsl, Sqdmlsl) \ 3128 V(sqdmlsl2, Sqdmlsl2) \ 3129 V(smull, Smull) \ 3130 V(smull2, Smull2) \ 3131 V(smlal, Smlal) \ 3132 V(smlal2, Smlal2) \ 3133 V(smlsl, Smlsl) \ 3134 V(smlsl2, Smlsl2) \ 3135 V(umull, Umull) \ 3136 V(umull2, Umull2) \ 3137 V(umlal, Umlal) \ 3138 V(umlal2, Umlal2) \ 3139 V(umlsl, Umlsl) \ 3140 V(umlsl2, Umlsl2) \ 3141 V(sudot, Sudot) \ 3142 V(usdot, Usdot) 3143 3144 3145#define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \ 3146 void MASM(const VRegister& vd, \ 3147 const VRegister& vn, \ 3148 const VRegister& vm, \ 3149 int vm_index) { \ 3150 VIXL_ASSERT(allow_macro_instructions_); \ 3151 SingleEmissionCheckScope guard(this); \ 3152 ASM(vd, vn, vm, vm_index); \ 3153 } 3154 NEON_BYELEMENT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 3155#undef DEFINE_MACRO_ASM_FUNC 3156 3157#define NEON_2VREG_SHIFT_MACRO_LIST(V) \ 3158 V(rshrn, Rshrn) \ 3159 V(rshrn2, Rshrn2) \ 3160 V(shl, Shl) \ 3161 V(shll, Shll) \ 3162 V(shll2, Shll2) \ 3163 V(shrn, Shrn) \ 3164 V(shrn2, Shrn2) \ 3165 V(sli, Sli) \ 3166 V(sqrshrn, Sqrshrn) \ 3167 V(sqrshrn2, Sqrshrn2) \ 3168 V(sqrshrun, Sqrshrun) \ 3169 V(sqrshrun2, Sqrshrun2) \ 3170 V(sqshl, Sqshl) \ 3171 V(sqshlu, Sqshlu) \ 3172 V(sqshrn, Sqshrn) \ 3173 V(sqshrn2, Sqshrn2) \ 3174 V(sqshrun, Sqshrun) \ 3175 V(sqshrun2, Sqshrun2) \ 3176 V(sri, Sri) \ 3177 V(srshr, Srshr) \ 3178 V(srsra, Srsra) \ 3179 V(sshr, Sshr) \ 3180 V(ssra, Ssra) \ 3181 V(uqrshrn, Uqrshrn) \ 3182 V(uqrshrn2, Uqrshrn2) \ 3183 V(uqshl, Uqshl) \ 3184 V(uqshrn, Uqshrn) \ 3185 V(uqshrn2, Uqshrn2) \ 3186 V(urshr, Urshr) \ 3187 V(ursra, Ursra) \ 3188 V(ushr, Ushr) \ 3189 V(usra, Usra) 3190 3191#define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \ 3192 void MASM(const VRegister& vd, const VRegister& vn, int shift) { \ 3193 VIXL_ASSERT(allow_macro_instructions_); \ 3194 SingleEmissionCheckScope guard(this); \ 3195 ASM(vd, vn, shift); \ 3196 } 3197 NEON_2VREG_SHIFT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 3198#undef DEFINE_MACRO_ASM_FUNC 3199 3200#define NEON_2VREG_SHIFT_LONG_MACRO_LIST(V) \ 3201 V(shll, sshll, Sshll) \ 3202 V(shll, ushll, Ushll) \ 3203 V(shll2, sshll2, Sshll2) \ 3204 V(shll2, ushll2, Ushll2) 3205 3206#define DEFINE_MACRO_ASM_FUNC(ASM1, ASM2, MASM) \ 3207 void MASM(const VRegister& vd, const VRegister& vn, int shift) { \ 3208 VIXL_ASSERT(allow_macro_instructions_); \ 3209 SingleEmissionCheckScope guard(this); \ 3210 if (vn.GetLaneSizeInBits() == static_cast<unsigned>(shift)) { \ 3211 ASM1(vd, vn, shift); \ 3212 } else { \ 3213 ASM2(vd, vn, shift); \ 3214 } \ 3215 } 3216 NEON_2VREG_SHIFT_LONG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 3217#undef DEFINE_MACRO_ASM_FUNC 3218 3219// SVE 3 vector register instructions. 3220#define SVE_3VREG_COMMUTATIVE_MACRO_LIST(V) \ 3221 V(add, Add) \ 3222 V(and_, And) \ 3223 V(eor, Eor) \ 3224 V(mul, Mul) \ 3225 V(orr, Orr) \ 3226 V(sabd, Sabd) \ 3227 V(shadd, Shadd) \ 3228 V(smax, Smax) \ 3229 V(smin, Smin) \ 3230 V(smulh, Smulh) \ 3231 V(sqadd, Sqadd) \ 3232 V(srhadd, Srhadd) \ 3233 V(uabd, Uabd) \ 3234 V(uhadd, Uhadd) \ 3235 V(umax, Umax) \ 3236 V(umin, Umin) \ 3237 V(umulh, Umulh) \ 3238 V(uqadd, Uqadd) \ 3239 V(urhadd, Urhadd) 3240 3241#define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \ 3242 void MASM(const ZRegister& zd, \ 3243 const PRegisterM& pg, \ 3244 const ZRegister& zn, \ 3245 const ZRegister& zm) { \ 3246 VIXL_ASSERT(allow_macro_instructions_); \ 3247 if (zd.Aliases(zn)) { \ 3248 SingleEmissionCheckScope guard(this); \ 3249 ASM(zd, pg, zd, zm); \ 3250 } else if (zd.Aliases(zm)) { \ 3251 SingleEmissionCheckScope guard(this); \ 3252 ASM(zd, pg, zd, zn); \ 3253 } else { \ 3254 MovprfxHelperScope guard(this, zd, pg, zn); \ 3255 ASM(zd, pg, zd, zm); \ 3256 } \ 3257 } 3258 SVE_3VREG_COMMUTATIVE_MACRO_LIST(DEFINE_MACRO_ASM_FUNC) 3259#undef DEFINE_MACRO_ASM_FUNC 3260 3261 void Bic(const VRegister& vd, const int imm8, const int left_shift = 0) { 3262 VIXL_ASSERT(allow_macro_instructions_); 3263 SingleEmissionCheckScope guard(this); 3264 bic(vd, imm8, left_shift); 3265 } 3266 void Cmeq(const VRegister& vd, const VRegister& vn, int imm) { 3267 VIXL_ASSERT(allow_macro_instructions_); 3268 SingleEmissionCheckScope guard(this); 3269 cmeq(vd, vn, imm); 3270 } 3271 void Cmge(const VRegister& vd, const VRegister& vn, int imm) { 3272 VIXL_ASSERT(allow_macro_instructions_); 3273 SingleEmissionCheckScope guard(this); 3274 cmge(vd, vn, imm); 3275 } 3276 void Cmgt(const VRegister& vd, const VRegister& vn, int imm) { 3277 VIXL_ASSERT(allow_macro_instructions_); 3278 SingleEmissionCheckScope guard(this); 3279 cmgt(vd, vn, imm); 3280 } 3281 void Cmle(const VRegister& vd, const VRegister& vn, int imm) { 3282 VIXL_ASSERT(allow_macro_instructions_); 3283 SingleEmissionCheckScope guard(this); 3284 cmle(vd, vn, imm); 3285 } 3286 void Cmlt(const VRegister& vd, const VRegister& vn, int imm) { 3287 VIXL_ASSERT(allow_macro_instructions_); 3288 SingleEmissionCheckScope guard(this); 3289 cmlt(vd, vn, imm); 3290 } 3291 void Dup(const VRegister& vd, const VRegister& vn, int index) { 3292 VIXL_ASSERT(allow_macro_instructions_); 3293 SingleEmissionCheckScope guard(this); 3294 dup(vd, vn, index); 3295 } 3296 void Dup(const VRegister& vd, const Register& rn) { 3297 VIXL_ASSERT(allow_macro_instructions_); 3298 SingleEmissionCheckScope guard(this); 3299 dup(vd, rn); 3300 } 3301 void Ext(const VRegister& vd, 3302 const VRegister& vn, 3303 const VRegister& vm, 3304 int index) { 3305 VIXL_ASSERT(allow_macro_instructions_); 3306 SingleEmissionCheckScope guard(this); 3307 ext(vd, vn, vm, index); 3308 } 3309 void Fcadd(const VRegister& vd, 3310 const VRegister& vn, 3311 const VRegister& vm, 3312 int rot) { 3313 VIXL_ASSERT(allow_macro_instructions_); 3314 SingleEmissionCheckScope guard(this); 3315 fcadd(vd, vn, vm, rot); 3316 } 3317 void Fcmla(const VRegister& vd, 3318 const VRegister& vn, 3319 const VRegister& vm, 3320 int vm_index, 3321 int rot) { 3322 VIXL_ASSERT(allow_macro_instructions_); 3323 SingleEmissionCheckScope guard(this); 3324 fcmla(vd, vn, vm, vm_index, rot); 3325 } 3326 void Fcmla(const VRegister& vd, 3327 const VRegister& vn, 3328 const VRegister& vm, 3329 int rot) { 3330 VIXL_ASSERT(allow_macro_instructions_); 3331 SingleEmissionCheckScope guard(this); 3332 fcmla(vd, vn, vm, rot); 3333 } 3334 void Ins(const VRegister& vd, 3335 int vd_index, 3336 const VRegister& vn, 3337 int vn_index) { 3338 VIXL_ASSERT(allow_macro_instructions_); 3339 SingleEmissionCheckScope guard(this); 3340 ins(vd, vd_index, vn, vn_index); 3341 } 3342 void Ins(const VRegister& vd, int vd_index, const Register& rn) { 3343 VIXL_ASSERT(allow_macro_instructions_); 3344 SingleEmissionCheckScope guard(this); 3345 ins(vd, vd_index, rn); 3346 } 3347 void Ld1(const VRegister& vt, const MemOperand& src) { 3348 VIXL_ASSERT(allow_macro_instructions_); 3349 SingleEmissionCheckScope guard(this); 3350 ld1(vt, src); 3351 } 3352 void Ld1(const VRegister& vt, const VRegister& vt2, const MemOperand& src) { 3353 VIXL_ASSERT(allow_macro_instructions_); 3354 SingleEmissionCheckScope guard(this); 3355 ld1(vt, vt2, src); 3356 } 3357 void Ld1(const VRegister& vt, 3358 const VRegister& vt2, 3359 const VRegister& vt3, 3360 const MemOperand& src) { 3361 VIXL_ASSERT(allow_macro_instructions_); 3362 SingleEmissionCheckScope guard(this); 3363 ld1(vt, vt2, vt3, src); 3364 } 3365 void Ld1(const VRegister& vt, 3366 const VRegister& vt2, 3367 const VRegister& vt3, 3368 const VRegister& vt4, 3369 const MemOperand& src) { 3370 VIXL_ASSERT(allow_macro_instructions_); 3371 SingleEmissionCheckScope guard(this); 3372 ld1(vt, vt2, vt3, vt4, src); 3373 } 3374 void Ld1(const VRegister& vt, int lane, const MemOperand& src) { 3375 VIXL_ASSERT(allow_macro_instructions_); 3376 SingleEmissionCheckScope guard(this); 3377 ld1(vt, lane, src); 3378 } 3379 void Ld1r(const VRegister& vt, const MemOperand& src) { 3380 VIXL_ASSERT(allow_macro_instructions_); 3381 SingleEmissionCheckScope guard(this); 3382 ld1r(vt, src); 3383 } 3384 void Ld2(const VRegister& vt, const VRegister& vt2, const MemOperand& src) { 3385 VIXL_ASSERT(allow_macro_instructions_); 3386 SingleEmissionCheckScope guard(this); 3387 ld2(vt, vt2, src); 3388 } 3389 void Ld2(const VRegister& vt, 3390 const VRegister& vt2, 3391 int lane, 3392 const MemOperand& src) { 3393 VIXL_ASSERT(allow_macro_instructions_); 3394 SingleEmissionCheckScope guard(this); 3395 ld2(vt, vt2, lane, src); 3396 } 3397 void Ld2r(const VRegister& vt, const VRegister& vt2, const MemOperand& src) { 3398 VIXL_ASSERT(allow_macro_instructions_); 3399 SingleEmissionCheckScope guard(this); 3400 ld2r(vt, vt2, src); 3401 } 3402 void Ld3(const VRegister& vt, 3403 const VRegister& vt2, 3404 const VRegister& vt3, 3405 const MemOperand& src) { 3406 VIXL_ASSERT(allow_macro_instructions_); 3407 SingleEmissionCheckScope guard(this); 3408 ld3(vt, vt2, vt3, src); 3409 } 3410 void Ld3(const VRegister& vt, 3411 const VRegister& vt2, 3412 const VRegister& vt3, 3413 int lane, 3414 const MemOperand& src) { 3415 VIXL_ASSERT(allow_macro_instructions_); 3416 SingleEmissionCheckScope guard(this); 3417 ld3(vt, vt2, vt3, lane, src); 3418 } 3419 void Ld3r(const VRegister& vt, 3420 const VRegister& vt2, 3421 const VRegister& vt3, 3422 const MemOperand& src) { 3423 VIXL_ASSERT(allow_macro_instructions_); 3424 SingleEmissionCheckScope guard(this); 3425 ld3r(vt, vt2, vt3, src); 3426 } 3427 void Ld4(const VRegister& vt, 3428 const VRegister& vt2, 3429 const VRegister& vt3, 3430 const VRegister& vt4, 3431 const MemOperand& src) { 3432 VIXL_ASSERT(allow_macro_instructions_); 3433 SingleEmissionCheckScope guard(this); 3434 ld4(vt, vt2, vt3, vt4, src); 3435 } 3436 void Ld4(const VRegister& vt, 3437 const VRegister& vt2, 3438 const VRegister& vt3, 3439 const VRegister& vt4, 3440 int lane, 3441 const MemOperand& src) { 3442 VIXL_ASSERT(allow_macro_instructions_); 3443 SingleEmissionCheckScope guard(this); 3444 ld4(vt, vt2, vt3, vt4, lane, src); 3445 } 3446 void Ld4r(const VRegister& vt, 3447 const VRegister& vt2, 3448 const VRegister& vt3, 3449 const VRegister& vt4, 3450 const MemOperand& src) { 3451 VIXL_ASSERT(allow_macro_instructions_); 3452 SingleEmissionCheckScope guard(this); 3453 ld4r(vt, vt2, vt3, vt4, src); 3454 } 3455 void Mov(const VRegister& vd, 3456 int vd_index, 3457 const VRegister& vn, 3458 int vn_index) { 3459 VIXL_ASSERT(allow_macro_instructions_); 3460 SingleEmissionCheckScope guard(this); 3461 mov(vd, vd_index, vn, vn_index); 3462 } 3463 void Mov(const VRegister& vd, const VRegister& vn, int index) { 3464 VIXL_ASSERT(allow_macro_instructions_); 3465 SingleEmissionCheckScope guard(this); 3466 mov(vd, vn, index); 3467 } 3468 void Mov(const VRegister& vd, int vd_index, const Register& rn) { 3469 VIXL_ASSERT(allow_macro_instructions_); 3470 SingleEmissionCheckScope guard(this); 3471 mov(vd, vd_index, rn); 3472 } 3473 void Mov(const Register& rd, const VRegister& vn, int vn_index) { 3474 VIXL_ASSERT(allow_macro_instructions_); 3475 SingleEmissionCheckScope guard(this); 3476 mov(rd, vn, vn_index); 3477 } 3478 void Movi(const VRegister& vd, 3479 uint64_t imm, 3480 Shift shift = LSL, 3481 int shift_amount = 0); 3482 void Movi(const VRegister& vd, uint64_t hi, uint64_t lo); 3483 void Mvni(const VRegister& vd, 3484 const int imm8, 3485 Shift shift = LSL, 3486 const int shift_amount = 0) { 3487 VIXL_ASSERT(allow_macro_instructions_); 3488 SingleEmissionCheckScope guard(this); 3489 mvni(vd, imm8, shift, shift_amount); 3490 } 3491 void Orr(const VRegister& vd, const int imm8, const int left_shift = 0) { 3492 VIXL_ASSERT(allow_macro_instructions_); 3493 SingleEmissionCheckScope guard(this); 3494 orr(vd, imm8, left_shift); 3495 } 3496 void Scvtf(const VRegister& vd, const VRegister& vn, int fbits = 0) { 3497 VIXL_ASSERT(allow_macro_instructions_); 3498 SingleEmissionCheckScope guard(this); 3499 scvtf(vd, vn, fbits); 3500 } 3501 void Ucvtf(const VRegister& vd, const VRegister& vn, int fbits = 0) { 3502 VIXL_ASSERT(allow_macro_instructions_); 3503 SingleEmissionCheckScope guard(this); 3504 ucvtf(vd, vn, fbits); 3505 } 3506 void Fcvtzs(const VRegister& vd, const VRegister& vn, int fbits = 0) { 3507 VIXL_ASSERT(allow_macro_instructions_); 3508 SingleEmissionCheckScope guard(this); 3509 fcvtzs(vd, vn, fbits); 3510 } 3511 void Fcvtzu(const VRegister& vd, const VRegister& vn, int fbits = 0) { 3512 VIXL_ASSERT(allow_macro_instructions_); 3513 SingleEmissionCheckScope guard(this); 3514 fcvtzu(vd, vn, fbits); 3515 } 3516 void St1(const VRegister& vt, const MemOperand& dst) { 3517 VIXL_ASSERT(allow_macro_instructions_); 3518 SingleEmissionCheckScope guard(this); 3519 st1(vt, dst); 3520 } 3521 void St1(const VRegister& vt, const VRegister& vt2, const MemOperand& dst) { 3522 VIXL_ASSERT(allow_macro_instructions_); 3523 SingleEmissionCheckScope guard(this); 3524 st1(vt, vt2, dst); 3525 } 3526 void St1(const VRegister& vt, 3527 const VRegister& vt2, 3528 const VRegister& vt3, 3529 const MemOperand& dst) { 3530 VIXL_ASSERT(allow_macro_instructions_); 3531 SingleEmissionCheckScope guard(this); 3532 st1(vt, vt2, vt3, dst); 3533 } 3534 void St1(const VRegister& vt, 3535 const VRegister& vt2, 3536 const VRegister& vt3, 3537 const VRegister& vt4, 3538 const MemOperand& dst) { 3539 VIXL_ASSERT(allow_macro_instructions_); 3540 SingleEmissionCheckScope guard(this); 3541 st1(vt, vt2, vt3, vt4, dst); 3542 } 3543 void St1(const VRegister& vt, int lane, const MemOperand& dst) { 3544 VIXL_ASSERT(allow_macro_instructions_); 3545 SingleEmissionCheckScope guard(this); 3546 st1(vt, lane, dst); 3547 } 3548 void St2(const VRegister& vt, const VRegister& vt2, const MemOperand& dst) { 3549 VIXL_ASSERT(allow_macro_instructions_); 3550 SingleEmissionCheckScope guard(this); 3551 st2(vt, vt2, dst); 3552 } 3553 void St3(const VRegister& vt, 3554 const VRegister& vt2, 3555 const VRegister& vt3, 3556 const MemOperand& dst) { 3557 VIXL_ASSERT(allow_macro_instructions_); 3558 SingleEmissionCheckScope guard(this); 3559 st3(vt, vt2, vt3, dst); 3560 } 3561 void St4(const VRegister& vt, 3562 const VRegister& vt2, 3563 const VRegister& vt3, 3564 const VRegister& vt4, 3565 const MemOperand& dst) { 3566 VIXL_ASSERT(allow_macro_instructions_); 3567 SingleEmissionCheckScope guard(this); 3568 st4(vt, vt2, vt3, vt4, dst); 3569 } 3570 void St2(const VRegister& vt, 3571 const VRegister& vt2, 3572 int lane, 3573 const MemOperand& dst) { 3574 VIXL_ASSERT(allow_macro_instructions_); 3575 SingleEmissionCheckScope guard(this); 3576 st2(vt, vt2, lane, dst); 3577 } 3578 void St3(const VRegister& vt, 3579 const VRegister& vt2, 3580 const VRegister& vt3, 3581 int lane, 3582 const MemOperand& dst) { 3583 VIXL_ASSERT(allow_macro_instructions_); 3584 SingleEmissionCheckScope guard(this); 3585 st3(vt, vt2, vt3, lane, dst); 3586 } 3587 void St4(const VRegister& vt, 3588 const VRegister& vt2, 3589 const VRegister& vt3, 3590 const VRegister& vt4, 3591 int lane, 3592 const MemOperand& dst) { 3593 VIXL_ASSERT(allow_macro_instructions_); 3594 SingleEmissionCheckScope guard(this); 3595 st4(vt, vt2, vt3, vt4, lane, dst); 3596 } 3597 void Smov(const Register& rd, const VRegister& vn, int vn_index) { 3598 VIXL_ASSERT(allow_macro_instructions_); 3599 SingleEmissionCheckScope guard(this); 3600 smov(rd, vn, vn_index); 3601 } 3602 void Umov(const Register& rd, const VRegister& vn, int vn_index) { 3603 VIXL_ASSERT(allow_macro_instructions_); 3604 SingleEmissionCheckScope guard(this); 3605 umov(rd, vn, vn_index); 3606 } 3607 void Crc32b(const Register& rd, const Register& rn, const Register& rm) { 3608 VIXL_ASSERT(allow_macro_instructions_); 3609 SingleEmissionCheckScope guard(this); 3610 crc32b(rd, rn, rm); 3611 } 3612 void Crc32h(const Register& rd, const Register& rn, const Register& rm) { 3613 VIXL_ASSERT(allow_macro_instructions_); 3614 SingleEmissionCheckScope guard(this); 3615 crc32h(rd, rn, rm); 3616 } 3617 void Crc32w(const Register& rd, const Register& rn, const Register& rm) { 3618 VIXL_ASSERT(allow_macro_instructions_); 3619 SingleEmissionCheckScope guard(this); 3620 crc32w(rd, rn, rm); 3621 } 3622 void Crc32x(const Register& rd, const Register& rn, const Register& rm) { 3623 VIXL_ASSERT(allow_macro_instructions_); 3624 SingleEmissionCheckScope guard(this); 3625 crc32x(rd, rn, rm); 3626 } 3627 void Crc32cb(const Register& rd, const Register& rn, const Register& rm) { 3628 VIXL_ASSERT(allow_macro_instructions_); 3629 SingleEmissionCheckScope guard(this); 3630 crc32cb(rd, rn, rm); 3631 } 3632 void Crc32ch(const Register& rd, const Register& rn, const Register& rm) { 3633 VIXL_ASSERT(allow_macro_instructions_); 3634 SingleEmissionCheckScope guard(this); 3635 crc32ch(rd, rn, rm); 3636 } 3637 void Crc32cw(const Register& rd, const Register& rn, const Register& rm) { 3638 VIXL_ASSERT(allow_macro_instructions_); 3639 SingleEmissionCheckScope guard(this); 3640 crc32cw(rd, rn, rm); 3641 } 3642 void Crc32cx(const Register& rd, const Register& rn, const Register& rm) { 3643 VIXL_ASSERT(allow_macro_instructions_); 3644 SingleEmissionCheckScope guard(this); 3645 crc32cx(rd, rn, rm); 3646 } 3647 3648 // Scalable Vector Extensions. 3649 void Abs(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 3650 VIXL_ASSERT(allow_macro_instructions_); 3651 SingleEmissionCheckScope guard(this); 3652 abs(zd, pg, zn); 3653 } 3654 void Add(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 3655 VIXL_ASSERT(allow_macro_instructions_); 3656 SingleEmissionCheckScope guard(this); 3657 add(zd, zn, zm); 3658 } 3659 void Add(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm) { 3660 VIXL_ASSERT(allow_macro_instructions_); 3661 AddSubHelper(kAddImmediate, zd, zn, imm); 3662 } 3663 void Addpl(const Register& xd, const Register& xn, int64_t multiplier); 3664 void Addvl(const Register& xd, const Register& xn, int64_t multiplier); 3665 // Note that unlike the core ISA, SVE's `adr` is not PC-relative. 3666 void Adr(const ZRegister& zd, const SVEMemOperand& addr) { 3667 VIXL_ASSERT(allow_macro_instructions_); 3668 SingleEmissionCheckScope guard(this); 3669 adr(zd, addr); 3670 } 3671 void And(const PRegisterWithLaneSize& pd, 3672 const PRegisterZ& pg, 3673 const PRegisterWithLaneSize& pn, 3674 const PRegisterWithLaneSize& pm) { 3675 VIXL_ASSERT(allow_macro_instructions_); 3676 SingleEmissionCheckScope guard(this); 3677 and_(pd, pg, pn, pm); 3678 } 3679 void And(const ZRegister& zd, const ZRegister& zn, uint64_t imm) { 3680 VIXL_ASSERT(allow_macro_instructions_); 3681 SingleEmissionCheckScope guard(this); 3682 if (IsImmLogical(imm, zd.GetLaneSizeInBits())) { 3683 and_(zd, zn, imm); 3684 } else { 3685 // TODO: Synthesise the immediate once 'Mov' is implemented. 3686 VIXL_UNIMPLEMENTED(); 3687 } 3688 } 3689 void And(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 3690 VIXL_ASSERT(allow_macro_instructions_); 3691 VIXL_ASSERT(AreSameLaneSize(zd, zn, zm)); 3692 SingleEmissionCheckScope guard(this); 3693 and_(zd.VnD(), zn.VnD(), zm.VnD()); 3694 } 3695 void Ands(const PRegisterWithLaneSize& pd, 3696 const PRegisterZ& pg, 3697 const PRegisterWithLaneSize& pn, 3698 const PRegisterWithLaneSize& pm) { 3699 VIXL_ASSERT(allow_macro_instructions_); 3700 SingleEmissionCheckScope guard(this); 3701 ands(pd, pg, pn, pm); 3702 } 3703 void Andv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 3704 VIXL_ASSERT(allow_macro_instructions_); 3705 SingleEmissionCheckScope guard(this); 3706 andv(vd, pg, zn); 3707 } 3708 void Asr(const ZRegister& zd, 3709 const PRegisterM& pg, 3710 const ZRegister& zn, 3711 int shift) { 3712 VIXL_ASSERT(allow_macro_instructions_); 3713 MovprfxHelperScope guard(this, zd, pg, zn); 3714 asr(zd, pg, zd, shift); 3715 } 3716 void Asr(const ZRegister& zd, 3717 const PRegisterM& pg, 3718 const ZRegister& zn, 3719 const ZRegister& zm); 3720 void Asr(const ZRegister& zd, const ZRegister& zn, int shift) { 3721 VIXL_ASSERT(allow_macro_instructions_); 3722 SingleEmissionCheckScope guard(this); 3723 asr(zd, zn, shift); 3724 } 3725 void Asr(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 3726 VIXL_ASSERT(allow_macro_instructions_); 3727 SingleEmissionCheckScope guard(this); 3728 asr(zd, zn, zm); 3729 } 3730 void Asrd(const ZRegister& zd, 3731 const PRegisterM& pg, 3732 const ZRegister& zn, 3733 int shift) { 3734 VIXL_ASSERT(allow_macro_instructions_); 3735 MovprfxHelperScope guard(this, zd, pg, zn); 3736 asrd(zd, pg, zd, shift); 3737 } 3738 void Bic(const ZRegister& zd, 3739 const PRegisterM& pg, 3740 const ZRegister& zn, 3741 const ZRegister& zm); 3742 void Bic(const PRegisterWithLaneSize& pd, 3743 const PRegisterZ& pg, 3744 const PRegisterWithLaneSize& pn, 3745 const PRegisterWithLaneSize& pm) { 3746 VIXL_ASSERT(allow_macro_instructions_); 3747 SingleEmissionCheckScope guard(this); 3748 bic(pd, pg, pn, pm); 3749 } 3750 void Bic(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 3751 VIXL_ASSERT(allow_macro_instructions_); 3752 VIXL_ASSERT(AreSameLaneSize(zd, zn, zm)); 3753 SingleEmissionCheckScope guard(this); 3754 bic(zd.VnD(), zn.VnD(), zm.VnD()); 3755 } 3756 void Bic(const ZRegister& zd, const ZRegister& zn, uint64_t imm) { 3757 VIXL_ASSERT(allow_macro_instructions_); 3758 SingleEmissionCheckScope guard(this); 3759 if (IsImmLogical(imm, zd.GetLaneSizeInBits())) { 3760 bic(zd, zn, imm); 3761 } else { 3762 // TODO: Synthesise the immediate once 'Mov' is implemented. 3763 VIXL_UNIMPLEMENTED(); 3764 } 3765 } 3766 void Bics(const PRegisterWithLaneSize& pd, 3767 const PRegisterZ& pg, 3768 const PRegisterWithLaneSize& pn, 3769 const PRegisterWithLaneSize& pm) { 3770 VIXL_ASSERT(allow_macro_instructions_); 3771 SingleEmissionCheckScope guard(this); 3772 bics(pd, pg, pn, pm); 3773 } 3774 void Brka(const PRegisterWithLaneSize& pd, 3775 const PRegister& pg, 3776 const PRegisterWithLaneSize& pn) { 3777 VIXL_ASSERT(allow_macro_instructions_); 3778 SingleEmissionCheckScope guard(this); 3779 brka(pd, pg, pn); 3780 } 3781 void Brkas(const PRegisterWithLaneSize& pd, 3782 const PRegisterZ& pg, 3783 const PRegisterWithLaneSize& pn) { 3784 VIXL_ASSERT(allow_macro_instructions_); 3785 SingleEmissionCheckScope guard(this); 3786 brkas(pd, pg, pn); 3787 } 3788 void Brkb(const PRegisterWithLaneSize& pd, 3789 const PRegister& pg, 3790 const PRegisterWithLaneSize& pn) { 3791 VIXL_ASSERT(allow_macro_instructions_); 3792 SingleEmissionCheckScope guard(this); 3793 brkb(pd, pg, pn); 3794 } 3795 void Brkbs(const PRegisterWithLaneSize& pd, 3796 const PRegisterZ& pg, 3797 const PRegisterWithLaneSize& pn) { 3798 VIXL_ASSERT(allow_macro_instructions_); 3799 SingleEmissionCheckScope guard(this); 3800 brkbs(pd, pg, pn); 3801 } 3802 void Brkn(const PRegisterWithLaneSize& pd, 3803 const PRegisterZ& pg, 3804 const PRegisterWithLaneSize& pn, 3805 const PRegisterWithLaneSize& pm) { 3806 VIXL_ASSERT(allow_macro_instructions_); 3807 if (!pd.Aliases(pm)) { 3808 Mov(pd, pm); 3809 } 3810 SingleEmissionCheckScope guard(this); 3811 brkn(pd, pg, pn, pd); 3812 } 3813 void Brkns(const PRegisterWithLaneSize& pd, 3814 const PRegisterZ& pg, 3815 const PRegisterWithLaneSize& pn, 3816 const PRegisterWithLaneSize& pm) { 3817 VIXL_ASSERT(allow_macro_instructions_); 3818 if (!pd.Aliases(pm)) { 3819 Mov(pd, pm); 3820 } 3821 SingleEmissionCheckScope guard(this); 3822 brkns(pd, pg, pn, pd); 3823 } 3824 void Brkpa(const PRegisterWithLaneSize& pd, 3825 const PRegisterZ& pg, 3826 const PRegisterWithLaneSize& pn, 3827 const PRegisterWithLaneSize& pm) { 3828 VIXL_ASSERT(allow_macro_instructions_); 3829 SingleEmissionCheckScope guard(this); 3830 brkpa(pd, pg, pn, pm); 3831 } 3832 void Brkpas(const PRegisterWithLaneSize& pd, 3833 const PRegisterZ& pg, 3834 const PRegisterWithLaneSize& pn, 3835 const PRegisterWithLaneSize& pm) { 3836 VIXL_ASSERT(allow_macro_instructions_); 3837 SingleEmissionCheckScope guard(this); 3838 brkpas(pd, pg, pn, pm); 3839 } 3840 void Brkpb(const PRegisterWithLaneSize& pd, 3841 const PRegisterZ& pg, 3842 const PRegisterWithLaneSize& pn, 3843 const PRegisterWithLaneSize& pm) { 3844 VIXL_ASSERT(allow_macro_instructions_); 3845 SingleEmissionCheckScope guard(this); 3846 brkpb(pd, pg, pn, pm); 3847 } 3848 void Brkpbs(const PRegisterWithLaneSize& pd, 3849 const PRegisterZ& pg, 3850 const PRegisterWithLaneSize& pn, 3851 const PRegisterWithLaneSize& pm) { 3852 VIXL_ASSERT(allow_macro_instructions_); 3853 SingleEmissionCheckScope guard(this); 3854 brkpbs(pd, pg, pn, pm); 3855 } 3856 void Clasta(const Register& rd, 3857 const PRegister& pg, 3858 const Register& rn, 3859 const ZRegister& zm) { 3860 VIXL_ASSERT(allow_macro_instructions_); 3861 SingleEmissionCheckScope guard(this); 3862 clasta(rd, pg, rn, zm); 3863 } 3864 void Clasta(const VRegister& vd, 3865 const PRegister& pg, 3866 const VRegister& vn, 3867 const ZRegister& zm) { 3868 VIXL_ASSERT(allow_macro_instructions_); 3869 SingleEmissionCheckScope guard(this); 3870 clasta(vd, pg, vn, zm); 3871 } 3872 void Clasta(const ZRegister& zd, 3873 const PRegister& pg, 3874 const ZRegister& zn, 3875 const ZRegister& zm); 3876 void Clastb(const Register& rd, 3877 const PRegister& pg, 3878 const Register& rn, 3879 const ZRegister& zm) { 3880 VIXL_ASSERT(allow_macro_instructions_); 3881 SingleEmissionCheckScope guard(this); 3882 clastb(rd, pg, rn, zm); 3883 } 3884 void Clastb(const VRegister& vd, 3885 const PRegister& pg, 3886 const VRegister& vn, 3887 const ZRegister& zm) { 3888 VIXL_ASSERT(allow_macro_instructions_); 3889 SingleEmissionCheckScope guard(this); 3890 clastb(vd, pg, vn, zm); 3891 } 3892 void Clastb(const ZRegister& zd, 3893 const PRegister& pg, 3894 const ZRegister& zn, 3895 const ZRegister& zm); 3896 void Cls(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 3897 VIXL_ASSERT(allow_macro_instructions_); 3898 SingleEmissionCheckScope guard(this); 3899 cls(zd, pg, zn); 3900 } 3901 void Clz(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 3902 VIXL_ASSERT(allow_macro_instructions_); 3903 SingleEmissionCheckScope guard(this); 3904 clz(zd, pg, zn); 3905 } 3906 void Cmpeq(const PRegisterWithLaneSize& pd, 3907 const PRegisterZ& pg, 3908 const ZRegister& zn, 3909 const ZRegister& zm) { 3910 VIXL_ASSERT(allow_macro_instructions_); 3911 SingleEmissionCheckScope guard(this); 3912 cmpeq(pd, pg, zn, zm); 3913 } 3914 void Cmpeq(const PRegisterWithLaneSize& pd, 3915 const PRegisterZ& pg, 3916 const ZRegister& zn, 3917 IntegerOperand imm) { 3918 VIXL_ASSERT(allow_macro_instructions_); 3919 int imm5; 3920 if (imm.TryEncodeAsIntNForLane<5>(zn, &imm5)) { 3921 SingleEmissionCheckScope guard(this); 3922 cmpeq(pd, pg, zn, imm5); 3923 } else { 3924 CompareHelper(eq, pd, pg, zn, imm); 3925 } 3926 } 3927 void Cmpge(const PRegisterWithLaneSize& pd, 3928 const PRegisterZ& pg, 3929 const ZRegister& zn, 3930 const ZRegister& zm) { 3931 VIXL_ASSERT(allow_macro_instructions_); 3932 SingleEmissionCheckScope guard(this); 3933 cmpge(pd, pg, zn, zm); 3934 } 3935 void Cmpge(const PRegisterWithLaneSize& pd, 3936 const PRegisterZ& pg, 3937 const ZRegister& zn, 3938 IntegerOperand imm) { 3939 VIXL_ASSERT(allow_macro_instructions_); 3940 int imm5; 3941 if (imm.TryEncodeAsIntNForLane<5>(zn, &imm5)) { 3942 SingleEmissionCheckScope guard(this); 3943 cmpge(pd, pg, zn, imm5); 3944 } else { 3945 CompareHelper(ge, pd, pg, zn, imm); 3946 } 3947 } 3948 void Cmpgt(const PRegisterWithLaneSize& pd, 3949 const PRegisterZ& pg, 3950 const ZRegister& zn, 3951 const ZRegister& zm) { 3952 VIXL_ASSERT(allow_macro_instructions_); 3953 SingleEmissionCheckScope guard(this); 3954 cmpgt(pd, pg, zn, zm); 3955 } 3956 void Cmpgt(const PRegisterWithLaneSize& pd, 3957 const PRegisterZ& pg, 3958 const ZRegister& zn, 3959 IntegerOperand imm) { 3960 VIXL_ASSERT(allow_macro_instructions_); 3961 int imm5; 3962 if (imm.TryEncodeAsIntNForLane<5>(zn, &imm5)) { 3963 SingleEmissionCheckScope guard(this); 3964 cmpgt(pd, pg, zn, imm5); 3965 } else { 3966 CompareHelper(gt, pd, pg, zn, imm); 3967 } 3968 } 3969 void Cmphi(const PRegisterWithLaneSize& pd, 3970 const PRegisterZ& pg, 3971 const ZRegister& zn, 3972 const ZRegister& zm) { 3973 VIXL_ASSERT(allow_macro_instructions_); 3974 SingleEmissionCheckScope guard(this); 3975 cmphi(pd, pg, zn, zm); 3976 } 3977 void Cmphi(const PRegisterWithLaneSize& pd, 3978 const PRegisterZ& pg, 3979 const ZRegister& zn, 3980 IntegerOperand imm) { 3981 VIXL_ASSERT(allow_macro_instructions_); 3982 if (imm.IsUintN(7)) { 3983 SingleEmissionCheckScope guard(this); 3984 cmphi(pd, pg, zn, static_cast<unsigned>(imm.AsUintN(7))); 3985 } else { 3986 CompareHelper(hi, pd, pg, zn, imm); 3987 } 3988 } 3989 void Cmphs(const PRegisterWithLaneSize& pd, 3990 const PRegisterZ& pg, 3991 const ZRegister& zn, 3992 const ZRegister& zm) { 3993 VIXL_ASSERT(allow_macro_instructions_); 3994 SingleEmissionCheckScope guard(this); 3995 cmphs(pd, pg, zn, zm); 3996 } 3997 void Cmphs(const PRegisterWithLaneSize& pd, 3998 const PRegisterZ& pg, 3999 const ZRegister& zn, 4000 IntegerOperand imm) { 4001 if (imm.IsUintN(7)) { 4002 SingleEmissionCheckScope guard(this); 4003 cmphs(pd, pg, zn, static_cast<unsigned>(imm.AsUintN(7))); 4004 } else { 4005 CompareHelper(hs, pd, pg, zn, imm); 4006 } 4007 } 4008 void Cmple(const PRegisterWithLaneSize& pd, 4009 const PRegisterZ& pg, 4010 const ZRegister& zn, 4011 const ZRegister& zm) { 4012 VIXL_ASSERT(allow_macro_instructions_); 4013 SingleEmissionCheckScope guard(this); 4014 cmple(pd, pg, zn, zm); 4015 } 4016 void Cmple(const PRegisterWithLaneSize& pd, 4017 const PRegisterZ& pg, 4018 const ZRegister& zn, 4019 IntegerOperand imm) { 4020 VIXL_ASSERT(allow_macro_instructions_); 4021 int imm5; 4022 if (imm.TryEncodeAsIntNForLane<5>(zn, &imm5)) { 4023 SingleEmissionCheckScope guard(this); 4024 cmple(pd, pg, zn, imm5); 4025 } else { 4026 CompareHelper(le, pd, pg, zn, imm); 4027 } 4028 } 4029 void Cmplo(const PRegisterWithLaneSize& pd, 4030 const PRegisterZ& pg, 4031 const ZRegister& zn, 4032 const ZRegister& zm) { 4033 VIXL_ASSERT(allow_macro_instructions_); 4034 SingleEmissionCheckScope guard(this); 4035 cmplo(pd, pg, zn, zm); 4036 } 4037 void Cmplo(const PRegisterWithLaneSize& pd, 4038 const PRegisterZ& pg, 4039 const ZRegister& zn, 4040 IntegerOperand imm) { 4041 if (imm.IsUintN(7)) { 4042 SingleEmissionCheckScope guard(this); 4043 cmplo(pd, pg, zn, static_cast<unsigned>(imm.AsUintN(7))); 4044 } else { 4045 CompareHelper(lo, pd, pg, zn, imm); 4046 } 4047 } 4048 void Cmpls(const PRegisterWithLaneSize& pd, 4049 const PRegisterZ& pg, 4050 const ZRegister& zn, 4051 const ZRegister& zm) { 4052 VIXL_ASSERT(allow_macro_instructions_); 4053 SingleEmissionCheckScope guard(this); 4054 cmpls(pd, pg, zn, zm); 4055 } 4056 void Cmpls(const PRegisterWithLaneSize& pd, 4057 const PRegisterZ& pg, 4058 const ZRegister& zn, 4059 IntegerOperand imm) { 4060 if (imm.IsUintN(7)) { 4061 SingleEmissionCheckScope guard(this); 4062 cmpls(pd, pg, zn, static_cast<unsigned>(imm.AsUintN(7))); 4063 } else { 4064 CompareHelper(ls, pd, pg, zn, imm); 4065 } 4066 } 4067 void Cmplt(const PRegisterWithLaneSize& pd, 4068 const PRegisterZ& pg, 4069 const ZRegister& zn, 4070 const ZRegister& zm) { 4071 VIXL_ASSERT(allow_macro_instructions_); 4072 SingleEmissionCheckScope guard(this); 4073 cmplt(pd, pg, zn, zm); 4074 } 4075 void Cmplt(const PRegisterWithLaneSize& pd, 4076 const PRegisterZ& pg, 4077 const ZRegister& zn, 4078 IntegerOperand imm) { 4079 VIXL_ASSERT(allow_macro_instructions_); 4080 int imm5; 4081 if (imm.TryEncodeAsIntNForLane<5>(zn, &imm5)) { 4082 SingleEmissionCheckScope guard(this); 4083 cmplt(pd, pg, zn, imm5); 4084 } else { 4085 CompareHelper(lt, pd, pg, zn, imm); 4086 } 4087 } 4088 void Cmpne(const PRegisterWithLaneSize& pd, 4089 const PRegisterZ& pg, 4090 const ZRegister& zn, 4091 const ZRegister& zm) { 4092 VIXL_ASSERT(allow_macro_instructions_); 4093 SingleEmissionCheckScope guard(this); 4094 cmpne(pd, pg, zn, zm); 4095 } 4096 void Cmpne(const PRegisterWithLaneSize& pd, 4097 const PRegisterZ& pg, 4098 const ZRegister& zn, 4099 IntegerOperand imm) { 4100 VIXL_ASSERT(allow_macro_instructions_); 4101 int imm5; 4102 if (imm.TryEncodeAsIntNForLane<5>(zn, &imm5)) { 4103 SingleEmissionCheckScope guard(this); 4104 cmpne(pd, pg, zn, imm5); 4105 } else { 4106 CompareHelper(ne, pd, pg, zn, imm); 4107 } 4108 } 4109 void Cnot(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4110 VIXL_ASSERT(allow_macro_instructions_); 4111 SingleEmissionCheckScope guard(this); 4112 cnot(zd, pg, zn); 4113 } 4114 void Cnt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4115 VIXL_ASSERT(allow_macro_instructions_); 4116 SingleEmissionCheckScope guard(this); 4117 cnt(zd, pg, zn); 4118 } 4119 void Cntb(const Register& rd, int pattern = SVE_ALL, int multiplier = 1) { 4120 VIXL_ASSERT(allow_macro_instructions_); 4121 SingleEmissionCheckScope guard(this); 4122 cntb(rd, pattern, multiplier); 4123 } 4124 void Cntd(const Register& rd, int pattern = SVE_ALL, int multiplier = 1) { 4125 VIXL_ASSERT(allow_macro_instructions_); 4126 SingleEmissionCheckScope guard(this); 4127 cntd(rd, pattern, multiplier); 4128 } 4129 void Cnth(const Register& rd, int pattern = SVE_ALL, int multiplier = 1) { 4130 VIXL_ASSERT(allow_macro_instructions_); 4131 SingleEmissionCheckScope guard(this); 4132 cnth(rd, pattern, multiplier); 4133 } 4134 void Cntp(const Register& rd, 4135 const PRegister& pg, 4136 const PRegisterWithLaneSize& pn) { 4137 VIXL_ASSERT(allow_macro_instructions_); 4138 SingleEmissionCheckScope guard(this); 4139 // The `cntp` instruction architecturally takes an X register, but the 4140 // result will always be in the range [0, kPRegMaxSize] (and therefore 4141 // always fits in a W register), so we can accept a W-sized rd here. 4142 cntp(rd.X(), pg, pn); 4143 } 4144 void Cntw(const Register& rd, int pattern = SVE_ALL, int multiplier = 1) { 4145 VIXL_ASSERT(allow_macro_instructions_); 4146 SingleEmissionCheckScope guard(this); 4147 cntw(rd, pattern, multiplier); 4148 } 4149 void Compact(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) { 4150 VIXL_ASSERT(allow_macro_instructions_); 4151 SingleEmissionCheckScope guard(this); 4152 compact(zd, pg, zn); 4153 } 4154 void Cpy(const ZRegister& zd, const PRegister& pg, IntegerOperand imm); 4155 void Cpy(const ZRegister& zd, const PRegisterM& pg, const Register& rn) { 4156 VIXL_ASSERT(allow_macro_instructions_); 4157 SingleEmissionCheckScope guard(this); 4158 cpy(zd, pg, rn); 4159 } 4160 void Cpy(const ZRegister& zd, const PRegisterM& pg, const VRegister& vn) { 4161 VIXL_ASSERT(allow_macro_instructions_); 4162 SingleEmissionCheckScope guard(this); 4163 cpy(zd, pg, vn); 4164 } 4165 void Ctermeq(const Register& rn, const Register& rm) { 4166 VIXL_ASSERT(allow_macro_instructions_); 4167 SingleEmissionCheckScope guard(this); 4168 ctermeq(rn, rm); 4169 } 4170 void Ctermne(const Register& rn, const Register& rm) { 4171 VIXL_ASSERT(allow_macro_instructions_); 4172 SingleEmissionCheckScope guard(this); 4173 ctermne(rn, rm); 4174 } 4175 void Decb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 4176 VIXL_ASSERT(allow_macro_instructions_); 4177 SingleEmissionCheckScope guard(this); 4178 decb(rdn, pattern, multiplier); 4179 } 4180 void Decd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 4181 VIXL_ASSERT(allow_macro_instructions_); 4182 SingleEmissionCheckScope guard(this); 4183 decd(rdn, pattern, multiplier); 4184 } 4185 void Decd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 4186 VIXL_ASSERT(allow_macro_instructions_); 4187 SingleEmissionCheckScope guard(this); 4188 decd(zdn, pattern, multiplier); 4189 } 4190 void Dech(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 4191 VIXL_ASSERT(allow_macro_instructions_); 4192 SingleEmissionCheckScope guard(this); 4193 dech(rdn, pattern, multiplier); 4194 } 4195 void Dech(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 4196 VIXL_ASSERT(allow_macro_instructions_); 4197 SingleEmissionCheckScope guard(this); 4198 dech(zdn, pattern, multiplier); 4199 } 4200 void Decp(const Register& rdn, const PRegisterWithLaneSize& pg) { 4201 VIXL_ASSERT(allow_macro_instructions_); 4202 SingleEmissionCheckScope guard(this); 4203 decp(rdn, pg); 4204 } 4205 void Decp(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) { 4206 VIXL_ASSERT(allow_macro_instructions_); 4207 VIXL_ASSERT(AreSameFormat(zd, zn)); 4208 // `decp` writes every lane, so use an unpredicated movprfx. 4209 MovprfxHelperScope guard(this, zd, zn); 4210 decp(zd, pg); 4211 } 4212 void Decp(const ZRegister& zdn, const PRegister& pg) { Decp(zdn, pg, zdn); } 4213 void Decw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 4214 VIXL_ASSERT(allow_macro_instructions_); 4215 SingleEmissionCheckScope guard(this); 4216 decw(rdn, pattern, multiplier); 4217 } 4218 void Decw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 4219 VIXL_ASSERT(allow_macro_instructions_); 4220 SingleEmissionCheckScope guard(this); 4221 decw(zdn, pattern, multiplier); 4222 } 4223 void Dup(const ZRegister& zd, const Register& xn) { 4224 VIXL_ASSERT(allow_macro_instructions_); 4225 SingleEmissionCheckScope guard(this); 4226 dup(zd, xn); 4227 } 4228 void Dup(const ZRegister& zd, const ZRegister& zn, int index) { 4229 VIXL_ASSERT(allow_macro_instructions_); 4230 SingleEmissionCheckScope guard(this); 4231 dup(zd, zn, index); 4232 } 4233 void Dup(const ZRegister& zd, IntegerOperand imm); 4234 void Eon(const ZRegister& zd, const ZRegister& zn, uint64_t imm) { 4235 VIXL_ASSERT(allow_macro_instructions_); 4236 SingleEmissionCheckScope guard(this); 4237 if (IsImmLogical(imm, zd.GetLaneSizeInBits())) { 4238 eon(zd, zn, imm); 4239 } else { 4240 // TODO: Synthesise the immediate once 'Mov' is implemented. 4241 VIXL_UNIMPLEMENTED(); 4242 } 4243 } 4244 void Eor(const PRegisterWithLaneSize& pd, 4245 const PRegisterZ& pg, 4246 const PRegisterWithLaneSize& pn, 4247 const PRegisterWithLaneSize& pm) { 4248 VIXL_ASSERT(allow_macro_instructions_); 4249 SingleEmissionCheckScope guard(this); 4250 eor(pd, pg, pn, pm); 4251 } 4252 void Eor(const ZRegister& zd, const ZRegister& zn, uint64_t imm) { 4253 VIXL_ASSERT(allow_macro_instructions_); 4254 SingleEmissionCheckScope guard(this); 4255 if (IsImmLogical(imm, zd.GetLaneSizeInBits())) { 4256 eor(zd, zn, imm); 4257 } else { 4258 // TODO: Synthesise the immediate once 'Mov' is implemented. 4259 VIXL_UNIMPLEMENTED(); 4260 } 4261 } 4262 void Eor(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 4263 VIXL_ASSERT(allow_macro_instructions_); 4264 VIXL_ASSERT(AreSameLaneSize(zd, zn, zm)); 4265 SingleEmissionCheckScope guard(this); 4266 eor(zd.VnD(), zn.VnD(), zm.VnD()); 4267 } 4268 void Eors(const PRegisterWithLaneSize& pd, 4269 const PRegisterZ& pg, 4270 const PRegisterWithLaneSize& pn, 4271 const PRegisterWithLaneSize& pm) { 4272 VIXL_ASSERT(allow_macro_instructions_); 4273 SingleEmissionCheckScope guard(this); 4274 eors(pd, pg, pn, pm); 4275 } 4276 void Eorv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 4277 VIXL_ASSERT(allow_macro_instructions_); 4278 SingleEmissionCheckScope guard(this); 4279 eorv(vd, pg, zn); 4280 } 4281 void Ext(const ZRegister& zd, 4282 const ZRegister& zn, 4283 const ZRegister& zm, 4284 unsigned offset) { 4285 VIXL_ASSERT(allow_macro_instructions_); 4286 SingleEmissionCheckScope guard(this); 4287 ext(zd, zn, zm, offset); 4288 } 4289 void Fabd(const ZRegister& zd, 4290 const PRegisterM& pg, 4291 const ZRegister& zn, 4292 const ZRegister& zm, 4293 FPMacroNaNPropagationOption nan_option); 4294 void Fabs(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4295 VIXL_ASSERT(allow_macro_instructions_); 4296 SingleEmissionCheckScope guard(this); 4297 fabs(zd, pg, zn); 4298 } 4299 void Facge(const PRegisterWithLaneSize& pd, 4300 const PRegisterZ& pg, 4301 const ZRegister& zn, 4302 const ZRegister& zm) { 4303 VIXL_ASSERT(allow_macro_instructions_); 4304 SingleEmissionCheckScope guard(this); 4305 facge(pd, pg, zn, zm); 4306 } 4307 void Facgt(const PRegisterWithLaneSize& pd, 4308 const PRegisterZ& pg, 4309 const ZRegister& zn, 4310 const ZRegister& zm) { 4311 VIXL_ASSERT(allow_macro_instructions_); 4312 SingleEmissionCheckScope guard(this); 4313 facgt(pd, pg, zn, zm); 4314 } 4315 void Facle(const PRegisterWithLaneSize& pd, 4316 const PRegisterZ& pg, 4317 const ZRegister& zn, 4318 const ZRegister& zm) { 4319 VIXL_ASSERT(allow_macro_instructions_); 4320 SingleEmissionCheckScope guard(this); 4321 facge(pd, pg, zm, zn); 4322 } 4323 void Faclt(const PRegisterWithLaneSize& pd, 4324 const PRegisterZ& pg, 4325 const ZRegister& zn, 4326 const ZRegister& zm) { 4327 VIXL_ASSERT(allow_macro_instructions_); 4328 SingleEmissionCheckScope guard(this); 4329 facgt(pd, pg, zm, zn); 4330 } 4331 void Fadd(const ZRegister& zd, 4332 const PRegisterM& pg, 4333 const ZRegister& zn, 4334 double imm) { 4335 VIXL_ASSERT(allow_macro_instructions_); 4336 MovprfxHelperScope guard(this, zd, pg, zn); 4337 fadd(zd, pg, zd, imm); 4338 } 4339 void Fadd(const ZRegister& zd, 4340 const PRegisterM& pg, 4341 const ZRegister& zn, 4342 const ZRegister& zm, 4343 FPMacroNaNPropagationOption nan_option); 4344 void Fadd(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 4345 VIXL_ASSERT(allow_macro_instructions_); 4346 SingleEmissionCheckScope guard(this); 4347 fadd(zd, zn, zm); 4348 } 4349 void Fadda(const VRegister& vd, 4350 const PRegister& pg, 4351 const VRegister& vn, 4352 const ZRegister& zm) { 4353 VIXL_ASSERT(allow_macro_instructions_); 4354 SingleEmissionCheckScope guard(this); 4355 fadda(vd, pg, vn, zm); 4356 } 4357 void Faddv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 4358 VIXL_ASSERT(allow_macro_instructions_); 4359 SingleEmissionCheckScope guard(this); 4360 faddv(vd, pg, zn); 4361 } 4362 void Fcadd(const ZRegister& zd, 4363 const PRegisterM& pg, 4364 const ZRegister& zn, 4365 const ZRegister& zm, 4366 int rot); 4367 void Fcmeq(const PRegisterWithLaneSize& pd, 4368 const PRegisterZ& pg, 4369 const ZRegister& zn, 4370 double zero) { 4371 VIXL_ASSERT(allow_macro_instructions_); 4372 SingleEmissionCheckScope guard(this); 4373 if (zero == 0.0) { 4374 fcmeq(pd, pg, zn, zero); 4375 } else { 4376 // TODO: Synthesise other immediates. 4377 VIXL_UNIMPLEMENTED(); 4378 } 4379 } 4380 void Fcmeq(const PRegisterWithLaneSize& pd, 4381 const PRegisterZ& pg, 4382 const ZRegister& zn, 4383 const ZRegister& zm) { 4384 VIXL_ASSERT(allow_macro_instructions_); 4385 SingleEmissionCheckScope guard(this); 4386 fcmeq(pd, pg, zn, zm); 4387 } 4388 void Fcmge(const PRegisterWithLaneSize& pd, 4389 const PRegisterZ& pg, 4390 const ZRegister& zn, 4391 double zero) { 4392 VIXL_ASSERT(allow_macro_instructions_); 4393 SingleEmissionCheckScope guard(this); 4394 if (zero == 0.0) { 4395 fcmge(pd, pg, zn, zero); 4396 } else { 4397 // TODO: Synthesise other immediates. 4398 VIXL_UNIMPLEMENTED(); 4399 } 4400 } 4401 void Fcmge(const PRegisterWithLaneSize& pd, 4402 const PRegisterZ& pg, 4403 const ZRegister& zn, 4404 const ZRegister& zm) { 4405 VIXL_ASSERT(allow_macro_instructions_); 4406 SingleEmissionCheckScope guard(this); 4407 fcmge(pd, pg, zn, zm); 4408 } 4409 void Fcmgt(const PRegisterWithLaneSize& pd, 4410 const PRegisterZ& pg, 4411 const ZRegister& zn, 4412 double zero) { 4413 VIXL_ASSERT(allow_macro_instructions_); 4414 SingleEmissionCheckScope guard(this); 4415 if (zero == 0.0) { 4416 fcmgt(pd, pg, zn, zero); 4417 } else { 4418 // TODO: Synthesise other immediates. 4419 VIXL_UNIMPLEMENTED(); 4420 } 4421 } 4422 void Fcmgt(const PRegisterWithLaneSize& pd, 4423 const PRegisterZ& pg, 4424 const ZRegister& zn, 4425 const ZRegister& zm) { 4426 VIXL_ASSERT(allow_macro_instructions_); 4427 SingleEmissionCheckScope guard(this); 4428 fcmgt(pd, pg, zn, zm); 4429 } 4430 void Fcmla(const ZRegister& zd, 4431 const PRegisterM& pg, 4432 const ZRegister& za, 4433 const ZRegister& zn, 4434 const ZRegister& zm, 4435 int rot); 4436 void Fcmla(const ZRegister& zda, 4437 const ZRegister& zn, 4438 const ZRegister& zm, 4439 int index, 4440 int rot) { 4441 VIXL_ASSERT(allow_macro_instructions_); 4442 SingleEmissionCheckScope guard(this); 4443 fcmla(zda, zn, zm, index, rot); 4444 } 4445 void Fcmle(const PRegisterWithLaneSize& pd, 4446 const PRegisterZ& pg, 4447 const ZRegister& zn, 4448 double zero) { 4449 VIXL_ASSERT(allow_macro_instructions_); 4450 SingleEmissionCheckScope guard(this); 4451 if (zero == 0.0) { 4452 fcmle(pd, pg, zn, zero); 4453 } else { 4454 // TODO: Synthesise other immediates. 4455 VIXL_UNIMPLEMENTED(); 4456 } 4457 } 4458 void Fcmle(const PRegisterWithLaneSize& pd, 4459 const PRegisterZ& pg, 4460 const ZRegister& zn, 4461 const ZRegister& zm) { 4462 VIXL_ASSERT(allow_macro_instructions_); 4463 SingleEmissionCheckScope guard(this); 4464 fcmge(pd, pg, zm, zn); 4465 } 4466 void Fcmlt(const PRegisterWithLaneSize& pd, 4467 const PRegisterZ& pg, 4468 const ZRegister& zn, 4469 double zero) { 4470 VIXL_ASSERT(allow_macro_instructions_); 4471 SingleEmissionCheckScope guard(this); 4472 if (zero == 0.0) { 4473 fcmlt(pd, pg, zn, zero); 4474 } else { 4475 // TODO: Synthesise other immediates. 4476 VIXL_UNIMPLEMENTED(); 4477 } 4478 } 4479 void Fcmlt(const PRegisterWithLaneSize& pd, 4480 const PRegisterZ& pg, 4481 const ZRegister& zn, 4482 const ZRegister& zm) { 4483 VIXL_ASSERT(allow_macro_instructions_); 4484 SingleEmissionCheckScope guard(this); 4485 fcmgt(pd, pg, zm, zn); 4486 } 4487 void Fcmne(const PRegisterWithLaneSize& pd, 4488 const PRegisterZ& pg, 4489 const ZRegister& zn, 4490 double zero) { 4491 VIXL_ASSERT(allow_macro_instructions_); 4492 SingleEmissionCheckScope guard(this); 4493 if (zero == 0.0) { 4494 fcmne(pd, pg, zn, zero); 4495 } else { 4496 // TODO: Synthesise other immediates. 4497 VIXL_UNIMPLEMENTED(); 4498 } 4499 } 4500 void Fcmne(const PRegisterWithLaneSize& pd, 4501 const PRegisterZ& pg, 4502 const ZRegister& zn, 4503 const ZRegister& zm) { 4504 VIXL_ASSERT(allow_macro_instructions_); 4505 SingleEmissionCheckScope guard(this); 4506 fcmne(pd, pg, zn, zm); 4507 } 4508 void Fcmuo(const PRegisterWithLaneSize& pd, 4509 const PRegisterZ& pg, 4510 const ZRegister& zn, 4511 const ZRegister& zm) { 4512 VIXL_ASSERT(allow_macro_instructions_); 4513 SingleEmissionCheckScope guard(this); 4514 fcmuo(pd, pg, zn, zm); 4515 } 4516 void Fcpy(const ZRegister& zd, const PRegisterM& pg, double imm); 4517 void Fcpy(const ZRegister& zd, const PRegisterM& pg, float imm); 4518 void Fcpy(const ZRegister& zd, const PRegisterM& pg, Float16 imm); 4519 void Fcvt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4520 VIXL_ASSERT(allow_macro_instructions_); 4521 SingleEmissionCheckScope guard(this); 4522 fcvt(zd, pg, zn); 4523 } 4524 void Fcvt(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) { 4525 VIXL_ASSERT(allow_macro_instructions_); 4526 // The element type in this predicated movprfx is determined by the larger 4527 // type between the source and destination. 4528 int lane_size = std::max(zd.GetLaneSizeInBits(), zn.GetLaneSizeInBits()); 4529 MovprfxHelperScope guard(this, 4530 zd.WithLaneSize(lane_size), 4531 pg, 4532 zn.WithLaneSize(lane_size)); 4533 fcvt(zd, pg.Merging(), zn); 4534 } 4535 void Fcvtzs(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4536 VIXL_ASSERT(allow_macro_instructions_); 4537 SingleEmissionCheckScope guard(this); 4538 fcvtzs(zd, pg, zn); 4539 } 4540 void Fcvtzu(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4541 VIXL_ASSERT(allow_macro_instructions_); 4542 SingleEmissionCheckScope guard(this); 4543 fcvtzu(zd, pg, zn); 4544 } 4545 void Fdiv(const ZRegister& zd, 4546 const PRegisterM& pg, 4547 const ZRegister& zn, 4548 const ZRegister& zm); 4549 void Fdup(const ZRegister& zd, double imm); 4550 void Fdup(const ZRegister& zd, float imm); 4551 void Fdup(const ZRegister& zd, Float16 imm); 4552 void Fexpa(const ZRegister& zd, const ZRegister& zn) { 4553 VIXL_ASSERT(allow_macro_instructions_); 4554 SingleEmissionCheckScope guard(this); 4555 fexpa(zd, zn); 4556 } 4557 void Fmad(const ZRegister& zdn, 4558 const PRegisterM& pg, 4559 const ZRegister& zm, 4560 const ZRegister& za) { 4561 VIXL_ASSERT(allow_macro_instructions_); 4562 SingleEmissionCheckScope guard(this); 4563 fmad(zdn, pg, zm, za); 4564 } 4565 void Fmax(const ZRegister& zd, 4566 const PRegisterM& pg, 4567 const ZRegister& zn, 4568 double imm) { 4569 VIXL_ASSERT(allow_macro_instructions_); 4570 MovprfxHelperScope guard(this, zd, pg, zn); 4571 fmax(zd, pg, zd, imm); 4572 } 4573 void Fmax( 4574 const ZRegister& zd, 4575 const PRegisterM& pg, 4576 const ZRegister& zn, 4577 const ZRegister& zm, 4578 FPMacroNaNPropagationOption nan_option = NoFPMacroNaNPropagationSelected); 4579 void Fmaxnm(const ZRegister& zd, 4580 const PRegisterM& pg, 4581 const ZRegister& zn, 4582 double imm) { 4583 VIXL_ASSERT(allow_macro_instructions_); 4584 MovprfxHelperScope guard(this, zd, pg, zn); 4585 fmaxnm(zd, pg, zd, imm); 4586 } 4587 void Fmaxnm(const ZRegister& zd, 4588 const PRegisterM& pg, 4589 const ZRegister& zn, 4590 const ZRegister& zm, 4591 FPMacroNaNPropagationOption nan_option); 4592 void Fmaxnmv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 4593 VIXL_ASSERT(allow_macro_instructions_); 4594 SingleEmissionCheckScope guard(this); 4595 fmaxnmv(vd, pg, zn); 4596 } 4597 void Fmaxv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 4598 VIXL_ASSERT(allow_macro_instructions_); 4599 SingleEmissionCheckScope guard(this); 4600 fmaxv(vd, pg, zn); 4601 } 4602 void Fmin(const ZRegister& zd, 4603 const PRegisterM& pg, 4604 const ZRegister& zn, 4605 double imm) { 4606 VIXL_ASSERT(allow_macro_instructions_); 4607 MovprfxHelperScope guard(this, zd, pg, zn); 4608 fmin(zd, pg, zd, imm); 4609 } 4610 void Fmin( 4611 const ZRegister& zd, 4612 const PRegisterM& pg, 4613 const ZRegister& zn, 4614 const ZRegister& zm, 4615 FPMacroNaNPropagationOption nan_option = NoFPMacroNaNPropagationSelected); 4616 void Fminnm(const ZRegister& zd, 4617 const PRegisterM& pg, 4618 const ZRegister& zn, 4619 double imm) { 4620 VIXL_ASSERT(allow_macro_instructions_); 4621 MovprfxHelperScope guard(this, zd, pg, zn); 4622 fminnm(zd, pg, zd, imm); 4623 } 4624 void Fminnm(const ZRegister& zd, 4625 const PRegisterM& pg, 4626 const ZRegister& zn, 4627 const ZRegister& zm, 4628 FPMacroNaNPropagationOption nan_option); 4629 void Fminnmv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 4630 VIXL_ASSERT(allow_macro_instructions_); 4631 SingleEmissionCheckScope guard(this); 4632 fminnmv(vd, pg, zn); 4633 } 4634 void Fminv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 4635 VIXL_ASSERT(allow_macro_instructions_); 4636 SingleEmissionCheckScope guard(this); 4637 fminv(vd, pg, zn); 4638 } 4639 // zd = za + (zn * zm) 4640 void Fmla( 4641 const ZRegister& zd, 4642 const PRegisterM& pg, 4643 const ZRegister& za, 4644 const ZRegister& zn, 4645 const ZRegister& zm, 4646 FPMacroNaNPropagationOption nan_option = NoFPMacroNaNPropagationSelected); 4647 void Fmla(const ZRegister& zd, 4648 const ZRegister& za, 4649 const ZRegister& zn, 4650 const ZRegister& zm, 4651 int index); 4652 // zd = za - (zn * zm) 4653 void Fmls( 4654 const ZRegister& zd, 4655 const PRegisterM& pg, 4656 const ZRegister& za, 4657 const ZRegister& zn, 4658 const ZRegister& zm, 4659 FPMacroNaNPropagationOption nan_option = NoFPMacroNaNPropagationSelected); 4660 void Fmls(const ZRegister& zd, 4661 const ZRegister& za, 4662 const ZRegister& zn, 4663 const ZRegister& zm, 4664 int index); 4665 void Fmov(const ZRegister& zd, double imm) { 4666 VIXL_ASSERT(allow_macro_instructions_); 4667 Fdup(zd, imm); 4668 } 4669 void Fmov(const ZRegister& zd, float imm) { 4670 VIXL_ASSERT(allow_macro_instructions_); 4671 Fdup(zd, imm); 4672 } 4673 void Fmov(const ZRegister& zd, Float16 imm) { 4674 VIXL_ASSERT(allow_macro_instructions_); 4675 Fdup(zd, imm); 4676 } 4677 void Fmov(const ZRegister& zd, const PRegisterM& pg, double imm) { 4678 VIXL_ASSERT(allow_macro_instructions_); 4679 Fcpy(zd, pg, imm); 4680 } 4681 void Fmov(const ZRegister& zd, const PRegisterM& pg, float imm) { 4682 VIXL_ASSERT(allow_macro_instructions_); 4683 Fcpy(zd, pg, imm); 4684 } 4685 void Fmov(const ZRegister& zd, const PRegisterM& pg, Float16 imm) { 4686 VIXL_ASSERT(allow_macro_instructions_); 4687 Fcpy(zd, pg, imm); 4688 } 4689 void Fmsb(const ZRegister& zdn, 4690 const PRegisterM& pg, 4691 const ZRegister& zm, 4692 const ZRegister& za) { 4693 VIXL_ASSERT(allow_macro_instructions_); 4694 SingleEmissionCheckScope guard(this); 4695 fmsb(zdn, pg, zm, za); 4696 } 4697 void Fmul(const ZRegister& zd, 4698 const PRegisterM& pg, 4699 const ZRegister& zn, 4700 double imm) { 4701 VIXL_ASSERT(allow_macro_instructions_); 4702 MovprfxHelperScope guard(this, zd, pg, zn); 4703 fmul(zd, pg, zd, imm); 4704 } 4705 void Fmul(const ZRegister& zd, 4706 const PRegisterM& pg, 4707 const ZRegister& zn, 4708 const ZRegister& zm, 4709 FPMacroNaNPropagationOption nan_option); 4710 void Fmul(const ZRegister& zd, 4711 const ZRegister& zn, 4712 const ZRegister& zm, 4713 unsigned index) { 4714 VIXL_ASSERT(allow_macro_instructions_); 4715 SingleEmissionCheckScope guard(this); 4716 fmul(zd, zn, zm, index); 4717 } 4718 void Fmul(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 4719 VIXL_ASSERT(allow_macro_instructions_); 4720 SingleEmissionCheckScope guard(this); 4721 fmul(zd, zn, zm); 4722 } 4723 void Fmulx(const ZRegister& zd, 4724 const PRegisterM& pg, 4725 const ZRegister& zn, 4726 const ZRegister& zm, 4727 FPMacroNaNPropagationOption nan_option); 4728 void Fneg(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4729 VIXL_ASSERT(allow_macro_instructions_); 4730 SingleEmissionCheckScope guard(this); 4731 fneg(zd, pg, zn); 4732 } 4733 void Fnmla( 4734 const ZRegister& zda, 4735 const PRegisterM& pg, 4736 const ZRegister& za, 4737 const ZRegister& zn, 4738 const ZRegister& zm, 4739 FPMacroNaNPropagationOption nan_option = NoFPMacroNaNPropagationSelected); 4740 void Fnmls( 4741 const ZRegister& zd, 4742 const PRegisterM& pg, 4743 const ZRegister& za, 4744 const ZRegister& zn, 4745 const ZRegister& zm, 4746 FPMacroNaNPropagationOption nan_option = NoFPMacroNaNPropagationSelected); 4747 void Frecpe(const ZRegister& zd, const ZRegister& zn) { 4748 VIXL_ASSERT(allow_macro_instructions_); 4749 SingleEmissionCheckScope guard(this); 4750 frecpe(zd, zn); 4751 } 4752 void Frecps(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 4753 VIXL_ASSERT(allow_macro_instructions_); 4754 SingleEmissionCheckScope guard(this); 4755 frecps(zd, zn, zm); 4756 } 4757 void Frecpx(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4758 VIXL_ASSERT(allow_macro_instructions_); 4759 SingleEmissionCheckScope guard(this); 4760 frecpx(zd, pg, zn); 4761 } 4762 void Frecpx(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) { 4763 VIXL_ASSERT(allow_macro_instructions_); 4764 MovprfxHelperScope guard(this, zd, pg, zn); 4765 frecpx(zd, pg.Merging(), zn); 4766 } 4767 void Frinta(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4768 VIXL_ASSERT(allow_macro_instructions_); 4769 SingleEmissionCheckScope guard(this); 4770 frinta(zd, pg, zn); 4771 } 4772 void Frinta(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) { 4773 VIXL_ASSERT(allow_macro_instructions_); 4774 MovprfxHelperScope guard(this, zd, pg, zn); 4775 frinta(zd, pg.Merging(), zn); 4776 } 4777 void Frinti(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4778 VIXL_ASSERT(allow_macro_instructions_); 4779 SingleEmissionCheckScope guard(this); 4780 frinti(zd, pg, zn); 4781 } 4782 void Frinti(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) { 4783 VIXL_ASSERT(allow_macro_instructions_); 4784 MovprfxHelperScope guard(this, zd, pg, zn); 4785 frinti(zd, pg.Merging(), zn); 4786 } 4787 void Frintm(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4788 VIXL_ASSERT(allow_macro_instructions_); 4789 SingleEmissionCheckScope guard(this); 4790 frintm(zd, pg, zn); 4791 } 4792 void Frintm(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) { 4793 VIXL_ASSERT(allow_macro_instructions_); 4794 MovprfxHelperScope guard(this, zd, pg, zn); 4795 frintm(zd, pg.Merging(), zn); 4796 } 4797 void Frintn(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4798 VIXL_ASSERT(allow_macro_instructions_); 4799 SingleEmissionCheckScope guard(this); 4800 frintn(zd, pg, zn); 4801 } 4802 void Frintn(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) { 4803 VIXL_ASSERT(allow_macro_instructions_); 4804 MovprfxHelperScope guard(this, zd, pg, zn); 4805 frintn(zd, pg.Merging(), zn); 4806 } 4807 void Frintp(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4808 VIXL_ASSERT(allow_macro_instructions_); 4809 SingleEmissionCheckScope guard(this); 4810 frintp(zd, pg, zn); 4811 } 4812 void Frintp(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) { 4813 VIXL_ASSERT(allow_macro_instructions_); 4814 MovprfxHelperScope guard(this, zd, pg, zn); 4815 frintp(zd, pg.Merging(), zn); 4816 } 4817 void Frintx(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4818 VIXL_ASSERT(allow_macro_instructions_); 4819 SingleEmissionCheckScope guard(this); 4820 frintx(zd, pg, zn); 4821 } 4822 void Frintx(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) { 4823 VIXL_ASSERT(allow_macro_instructions_); 4824 MovprfxHelperScope guard(this, zd, pg, zn); 4825 frintx(zd, pg.Merging(), zn); 4826 } 4827 void Frintz(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4828 VIXL_ASSERT(allow_macro_instructions_); 4829 SingleEmissionCheckScope guard(this); 4830 frintz(zd, pg, zn); 4831 } 4832 void Frintz(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) { 4833 VIXL_ASSERT(allow_macro_instructions_); 4834 MovprfxHelperScope guard(this, zd, pg, zn); 4835 frintz(zd, pg.Merging(), zn); 4836 } 4837 void Frsqrte(const ZRegister& zd, const ZRegister& zn) { 4838 VIXL_ASSERT(allow_macro_instructions_); 4839 SingleEmissionCheckScope guard(this); 4840 frsqrte(zd, zn); 4841 } 4842 void Frsqrts(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 4843 VIXL_ASSERT(allow_macro_instructions_); 4844 SingleEmissionCheckScope guard(this); 4845 frsqrts(zd, zn, zm); 4846 } 4847 void Fscale(const ZRegister& zd, 4848 const PRegisterM& pg, 4849 const ZRegister& zn, 4850 const ZRegister& zm); 4851 void Fsqrt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 4852 VIXL_ASSERT(allow_macro_instructions_); 4853 SingleEmissionCheckScope guard(this); 4854 fsqrt(zd, pg, zn); 4855 } 4856 void Fsqrt(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) { 4857 VIXL_ASSERT(allow_macro_instructions_); 4858 MovprfxHelperScope guard(this, zd, pg, zn); 4859 fsqrt(zd, pg.Merging(), zn); 4860 } 4861 void Fsub(const ZRegister& zd, 4862 const PRegisterM& pg, 4863 const ZRegister& zn, 4864 double imm) { 4865 VIXL_ASSERT(allow_macro_instructions_); 4866 MovprfxHelperScope guard(this, zd, pg, zn); 4867 fsub(zd, pg, zd, imm); 4868 } 4869 void Fsub(const ZRegister& zd, 4870 const PRegisterM& pg, 4871 double imm, 4872 const ZRegister& zn) { 4873 VIXL_ASSERT(allow_macro_instructions_); 4874 MovprfxHelperScope guard(this, zd, pg, zn); 4875 fsubr(zd, pg, zd, imm); 4876 } 4877 void Fsub(const ZRegister& zd, 4878 const PRegisterM& pg, 4879 const ZRegister& zn, 4880 const ZRegister& zm); 4881 void Fsub(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 4882 VIXL_ASSERT(allow_macro_instructions_); 4883 SingleEmissionCheckScope guard(this); 4884 fsub(zd, zn, zm); 4885 } 4886 void Ftmad(const ZRegister& zd, 4887 const ZRegister& zn, 4888 const ZRegister& zm, 4889 int imm3); 4890 void Ftsmul(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 4891 VIXL_ASSERT(allow_macro_instructions_); 4892 SingleEmissionCheckScope guard(this); 4893 ftsmul(zd, zn, zm); 4894 } 4895 void Ftssel(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 4896 VIXL_ASSERT(allow_macro_instructions_); 4897 SingleEmissionCheckScope guard(this); 4898 ftssel(zd, zn, zm); 4899 } 4900 void Incb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 4901 VIXL_ASSERT(allow_macro_instructions_); 4902 SingleEmissionCheckScope guard(this); 4903 incb(rdn, pattern, multiplier); 4904 } 4905 void Incd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 4906 VIXL_ASSERT(allow_macro_instructions_); 4907 SingleEmissionCheckScope guard(this); 4908 incd(rdn, pattern, multiplier); 4909 } 4910 void Incd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 4911 VIXL_ASSERT(allow_macro_instructions_); 4912 SingleEmissionCheckScope guard(this); 4913 incd(zdn, pattern, multiplier); 4914 } 4915 void Inch(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 4916 VIXL_ASSERT(allow_macro_instructions_); 4917 SingleEmissionCheckScope guard(this); 4918 inch(rdn, pattern, multiplier); 4919 } 4920 void Inch(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 4921 VIXL_ASSERT(allow_macro_instructions_); 4922 SingleEmissionCheckScope guard(this); 4923 inch(zdn, pattern, multiplier); 4924 } 4925 void Incp(const Register& rdn, const PRegisterWithLaneSize& pg) { 4926 VIXL_ASSERT(allow_macro_instructions_); 4927 SingleEmissionCheckScope guard(this); 4928 incp(rdn, pg); 4929 } 4930 void Incp(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) { 4931 VIXL_ASSERT(allow_macro_instructions_); 4932 VIXL_ASSERT(AreSameFormat(zd, zn)); 4933 // `incp` writes every lane, so use an unpredicated movprfx. 4934 MovprfxHelperScope guard(this, zd, zn); 4935 incp(zd, pg); 4936 } 4937 void Incp(const ZRegister& zdn, const PRegister& pg) { Incp(zdn, pg, zdn); } 4938 void Incw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 4939 VIXL_ASSERT(allow_macro_instructions_); 4940 SingleEmissionCheckScope guard(this); 4941 incw(rdn, pattern, multiplier); 4942 } 4943 void Incw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 4944 VIXL_ASSERT(allow_macro_instructions_); 4945 SingleEmissionCheckScope guard(this); 4946 incw(zdn, pattern, multiplier); 4947 } 4948 void Index(const ZRegister& zd, const Operand& start, const Operand& step); 4949 void Insr(const ZRegister& zdn, const Register& rm) { 4950 VIXL_ASSERT(allow_macro_instructions_); 4951 SingleEmissionCheckScope guard(this); 4952 insr(zdn, rm); 4953 } 4954 void Insr(const ZRegister& zdn, const VRegister& vm) { 4955 VIXL_ASSERT(allow_macro_instructions_); 4956 SingleEmissionCheckScope guard(this); 4957 insr(zdn, vm); 4958 } 4959 void Insr(const ZRegister& zdn, IntegerOperand imm); 4960 void Lasta(const Register& rd, const PRegister& pg, const ZRegister& zn) { 4961 VIXL_ASSERT(allow_macro_instructions_); 4962 SingleEmissionCheckScope guard(this); 4963 lasta(rd, pg, zn); 4964 } 4965 void Lasta(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 4966 VIXL_ASSERT(allow_macro_instructions_); 4967 SingleEmissionCheckScope guard(this); 4968 lasta(vd, pg, zn); 4969 } 4970 void Lastb(const Register& rd, const PRegister& pg, const ZRegister& zn) { 4971 VIXL_ASSERT(allow_macro_instructions_); 4972 SingleEmissionCheckScope guard(this); 4973 lastb(rd, pg, zn); 4974 } 4975 void Lastb(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 4976 VIXL_ASSERT(allow_macro_instructions_); 4977 SingleEmissionCheckScope guard(this); 4978 lastb(vd, pg, zn); 4979 } 4980 void Ld1b(const ZRegister& zt, 4981 const PRegisterZ& pg, 4982 const SVEMemOperand& addr); 4983 void Ld1h(const ZRegister& zt, 4984 const PRegisterZ& pg, 4985 const SVEMemOperand& addr); 4986 void Ld1w(const ZRegister& zt, 4987 const PRegisterZ& pg, 4988 const SVEMemOperand& addr); 4989 void Ld1d(const ZRegister& zt, 4990 const PRegisterZ& pg, 4991 const SVEMemOperand& addr); 4992 void Ld1rb(const ZRegister& zt, 4993 const PRegisterZ& pg, 4994 const SVEMemOperand& addr) { 4995 VIXL_ASSERT(allow_macro_instructions_); 4996 SVELoadBroadcastImmHelper(zt, 4997 pg, 4998 addr, 4999 &MacroAssembler::ld1rb, 5000 kBRegSizeInBytes); 5001 } 5002 void Ld1rh(const ZRegister& zt, 5003 const PRegisterZ& pg, 5004 const SVEMemOperand& addr) { 5005 VIXL_ASSERT(allow_macro_instructions_); 5006 SVELoadBroadcastImmHelper(zt, 5007 pg, 5008 addr, 5009 &MacroAssembler::ld1rh, 5010 kHRegSizeInBytes); 5011 } 5012 void Ld1rw(const ZRegister& zt, 5013 const PRegisterZ& pg, 5014 const SVEMemOperand& addr) { 5015 VIXL_ASSERT(allow_macro_instructions_); 5016 SVELoadBroadcastImmHelper(zt, 5017 pg, 5018 addr, 5019 &MacroAssembler::ld1rw, 5020 kSRegSizeInBytes); 5021 } 5022 void Ld1rd(const ZRegister& zt, 5023 const PRegisterZ& pg, 5024 const SVEMemOperand& addr) { 5025 VIXL_ASSERT(allow_macro_instructions_); 5026 SVELoadBroadcastImmHelper(zt, 5027 pg, 5028 addr, 5029 &MacroAssembler::ld1rd, 5030 kDRegSizeInBytes); 5031 } 5032 void Ld1rqb(const ZRegister& zt, 5033 const PRegisterZ& pg, 5034 const SVEMemOperand& addr); 5035 void Ld1rqd(const ZRegister& zt, 5036 const PRegisterZ& pg, 5037 const SVEMemOperand& addr); 5038 void Ld1rqh(const ZRegister& zt, 5039 const PRegisterZ& pg, 5040 const SVEMemOperand& addr); 5041 void Ld1rqw(const ZRegister& zt, 5042 const PRegisterZ& pg, 5043 const SVEMemOperand& addr); 5044 void Ld1rob(const ZRegister& zt, 5045 const PRegisterZ& pg, 5046 const SVEMemOperand& addr); 5047 void Ld1rod(const ZRegister& zt, 5048 const PRegisterZ& pg, 5049 const SVEMemOperand& addr); 5050 void Ld1roh(const ZRegister& zt, 5051 const PRegisterZ& pg, 5052 const SVEMemOperand& addr); 5053 void Ld1row(const ZRegister& zt, 5054 const PRegisterZ& pg, 5055 const SVEMemOperand& addr); 5056 void Ld1rsb(const ZRegister& zt, 5057 const PRegisterZ& pg, 5058 const SVEMemOperand& addr) { 5059 VIXL_ASSERT(allow_macro_instructions_); 5060 SVELoadBroadcastImmHelper(zt, 5061 pg, 5062 addr, 5063 &MacroAssembler::ld1rsb, 5064 kBRegSizeInBytes); 5065 } 5066 void Ld1rsh(const ZRegister& zt, 5067 const PRegisterZ& pg, 5068 const SVEMemOperand& addr) { 5069 VIXL_ASSERT(allow_macro_instructions_); 5070 SVELoadBroadcastImmHelper(zt, 5071 pg, 5072 addr, 5073 &MacroAssembler::ld1rsh, 5074 kHRegSizeInBytes); 5075 } 5076 void Ld1rsw(const ZRegister& zt, 5077 const PRegisterZ& pg, 5078 const SVEMemOperand& addr) { 5079 VIXL_ASSERT(allow_macro_instructions_); 5080 SVELoadBroadcastImmHelper(zt, 5081 pg, 5082 addr, 5083 &MacroAssembler::ld1rsw, 5084 kSRegSizeInBytes); 5085 } 5086 void Ld1sb(const ZRegister& zt, 5087 const PRegisterZ& pg, 5088 const SVEMemOperand& addr); 5089 void Ld1sh(const ZRegister& zt, 5090 const PRegisterZ& pg, 5091 const SVEMemOperand& addr); 5092 void Ld1sw(const ZRegister& zt, 5093 const PRegisterZ& pg, 5094 const SVEMemOperand& addr); 5095 void Ld2b(const ZRegister& zt1, 5096 const ZRegister& zt2, 5097 const PRegisterZ& pg, 5098 const SVEMemOperand& addr) { 5099 VIXL_ASSERT(allow_macro_instructions_); 5100 SingleEmissionCheckScope guard(this); 5101 ld2b(zt1, zt2, pg, addr); 5102 } 5103 void Ld2h(const ZRegister& zt1, 5104 const ZRegister& zt2, 5105 const PRegisterZ& pg, 5106 const SVEMemOperand& addr) { 5107 VIXL_ASSERT(allow_macro_instructions_); 5108 SingleEmissionCheckScope guard(this); 5109 ld2h(zt1, zt2, pg, addr); 5110 } 5111 void Ld2w(const ZRegister& zt1, 5112 const ZRegister& zt2, 5113 const PRegisterZ& pg, 5114 const SVEMemOperand& addr) { 5115 VIXL_ASSERT(allow_macro_instructions_); 5116 SingleEmissionCheckScope guard(this); 5117 ld2w(zt1, zt2, pg, addr); 5118 } 5119 void Ld2d(const ZRegister& zt1, 5120 const ZRegister& zt2, 5121 const PRegisterZ& pg, 5122 const SVEMemOperand& addr) { 5123 VIXL_ASSERT(allow_macro_instructions_); 5124 SingleEmissionCheckScope guard(this); 5125 ld2d(zt1, zt2, pg, addr); 5126 } 5127 void Ld3b(const ZRegister& zt1, 5128 const ZRegister& zt2, 5129 const ZRegister& zt3, 5130 const PRegisterZ& pg, 5131 const SVEMemOperand& addr) { 5132 VIXL_ASSERT(allow_macro_instructions_); 5133 SingleEmissionCheckScope guard(this); 5134 ld3b(zt1, zt2, zt3, pg, addr); 5135 } 5136 void Ld3h(const ZRegister& zt1, 5137 const ZRegister& zt2, 5138 const ZRegister& zt3, 5139 const PRegisterZ& pg, 5140 const SVEMemOperand& addr) { 5141 VIXL_ASSERT(allow_macro_instructions_); 5142 SingleEmissionCheckScope guard(this); 5143 ld3h(zt1, zt2, zt3, pg, addr); 5144 } 5145 void Ld3w(const ZRegister& zt1, 5146 const ZRegister& zt2, 5147 const ZRegister& zt3, 5148 const PRegisterZ& pg, 5149 const SVEMemOperand& addr) { 5150 VIXL_ASSERT(allow_macro_instructions_); 5151 SingleEmissionCheckScope guard(this); 5152 ld3w(zt1, zt2, zt3, pg, addr); 5153 } 5154 void Ld3d(const ZRegister& zt1, 5155 const ZRegister& zt2, 5156 const ZRegister& zt3, 5157 const PRegisterZ& pg, 5158 const SVEMemOperand& addr) { 5159 VIXL_ASSERT(allow_macro_instructions_); 5160 SingleEmissionCheckScope guard(this); 5161 ld3d(zt1, zt2, zt3, pg, addr); 5162 } 5163 void Ld4b(const ZRegister& zt1, 5164 const ZRegister& zt2, 5165 const ZRegister& zt3, 5166 const ZRegister& zt4, 5167 const PRegisterZ& pg, 5168 const SVEMemOperand& addr) { 5169 VIXL_ASSERT(allow_macro_instructions_); 5170 SingleEmissionCheckScope guard(this); 5171 ld4b(zt1, zt2, zt3, zt4, pg, addr); 5172 } 5173 void Ld4h(const ZRegister& zt1, 5174 const ZRegister& zt2, 5175 const ZRegister& zt3, 5176 const ZRegister& zt4, 5177 const PRegisterZ& pg, 5178 const SVEMemOperand& addr) { 5179 VIXL_ASSERT(allow_macro_instructions_); 5180 SingleEmissionCheckScope guard(this); 5181 ld4h(zt1, zt2, zt3, zt4, pg, addr); 5182 } 5183 void Ld4w(const ZRegister& zt1, 5184 const ZRegister& zt2, 5185 const ZRegister& zt3, 5186 const ZRegister& zt4, 5187 const PRegisterZ& pg, 5188 const SVEMemOperand& addr) { 5189 VIXL_ASSERT(allow_macro_instructions_); 5190 SingleEmissionCheckScope guard(this); 5191 ld4w(zt1, zt2, zt3, zt4, pg, addr); 5192 } 5193 void Ld4d(const ZRegister& zt1, 5194 const ZRegister& zt2, 5195 const ZRegister& zt3, 5196 const ZRegister& zt4, 5197 const PRegisterZ& pg, 5198 const SVEMemOperand& addr) { 5199 VIXL_ASSERT(allow_macro_instructions_); 5200 SingleEmissionCheckScope guard(this); 5201 ld4d(zt1, zt2, zt3, zt4, pg, addr); 5202 } 5203 void Ldff1b(const ZRegister& zt, 5204 const PRegisterZ& pg, 5205 const SVEMemOperand& addr); 5206 void Ldff1h(const ZRegister& zt, 5207 const PRegisterZ& pg, 5208 const SVEMemOperand& addr); 5209 void Ldff1w(const ZRegister& zt, 5210 const PRegisterZ& pg, 5211 const SVEMemOperand& addr); 5212 void Ldff1d(const ZRegister& zt, 5213 const PRegisterZ& pg, 5214 const SVEMemOperand& addr); 5215 void Ldff1sb(const ZRegister& zt, 5216 const PRegisterZ& pg, 5217 const SVEMemOperand& addr); 5218 void Ldff1sh(const ZRegister& zt, 5219 const PRegisterZ& pg, 5220 const SVEMemOperand& addr); 5221 void Ldff1sw(const ZRegister& zt, 5222 const PRegisterZ& pg, 5223 const SVEMemOperand& addr); 5224 void Ldff1b(const ZRegister& zt, 5225 const PRegisterZ& pg, 5226 const Register& xn, 5227 const ZRegister& zm) { 5228 VIXL_ASSERT(allow_macro_instructions_); 5229 SingleEmissionCheckScope guard(this); 5230 ldff1b(zt, pg, xn, zm); 5231 } 5232 void Ldff1b(const ZRegister& zt, 5233 const PRegisterZ& pg, 5234 const ZRegister& zn, 5235 int imm5) { 5236 VIXL_ASSERT(allow_macro_instructions_); 5237 SingleEmissionCheckScope guard(this); 5238 ldff1b(zt, pg, zn, imm5); 5239 } 5240 void Ldff1d(const ZRegister& zt, 5241 const PRegisterZ& pg, 5242 const Register& xn, 5243 const ZRegister& zm) { 5244 VIXL_ASSERT(allow_macro_instructions_); 5245 SingleEmissionCheckScope guard(this); 5246 ldff1d(zt, pg, xn, zm); 5247 } 5248 void Ldff1d(const ZRegister& zt, 5249 const PRegisterZ& pg, 5250 const ZRegister& zn, 5251 int imm5) { 5252 VIXL_ASSERT(allow_macro_instructions_); 5253 SingleEmissionCheckScope guard(this); 5254 ldff1d(zt, pg, zn, imm5); 5255 } 5256 void Ldff1h(const ZRegister& zt, 5257 const PRegisterZ& pg, 5258 const Register& xn, 5259 const ZRegister& zm) { 5260 VIXL_ASSERT(allow_macro_instructions_); 5261 SingleEmissionCheckScope guard(this); 5262 ldff1h(zt, pg, xn, zm); 5263 } 5264 void Ldff1h(const ZRegister& zt, 5265 const PRegisterZ& pg, 5266 const ZRegister& zn, 5267 int imm5) { 5268 VIXL_ASSERT(allow_macro_instructions_); 5269 SingleEmissionCheckScope guard(this); 5270 ldff1h(zt, pg, zn, imm5); 5271 } 5272 void Ldff1sb(const ZRegister& zt, 5273 const PRegisterZ& pg, 5274 const Register& xn, 5275 const ZRegister& zm) { 5276 VIXL_ASSERT(allow_macro_instructions_); 5277 SingleEmissionCheckScope guard(this); 5278 ldff1sb(zt, pg, xn, zm); 5279 } 5280 void Ldff1sb(const ZRegister& zt, 5281 const PRegisterZ& pg, 5282 const ZRegister& zn, 5283 int imm5) { 5284 VIXL_ASSERT(allow_macro_instructions_); 5285 SingleEmissionCheckScope guard(this); 5286 ldff1sb(zt, pg, zn, imm5); 5287 } 5288 void Ldff1sh(const ZRegister& zt, 5289 const PRegisterZ& pg, 5290 const Register& xn, 5291 const ZRegister& zm) { 5292 VIXL_ASSERT(allow_macro_instructions_); 5293 SingleEmissionCheckScope guard(this); 5294 ldff1sh(zt, pg, xn, zm); 5295 } 5296 void Ldff1sh(const ZRegister& zt, 5297 const PRegisterZ& pg, 5298 const ZRegister& zn, 5299 int imm5) { 5300 VIXL_ASSERT(allow_macro_instructions_); 5301 SingleEmissionCheckScope guard(this); 5302 ldff1sh(zt, pg, zn, imm5); 5303 } 5304 void Ldff1sw(const ZRegister& zt, 5305 const PRegisterZ& pg, 5306 const Register& xn, 5307 const ZRegister& zm) { 5308 VIXL_ASSERT(allow_macro_instructions_); 5309 SingleEmissionCheckScope guard(this); 5310 ldff1sw(zt, pg, xn, zm); 5311 } 5312 void Ldff1sw(const ZRegister& zt, 5313 const PRegisterZ& pg, 5314 const ZRegister& zn, 5315 int imm5) { 5316 VIXL_ASSERT(allow_macro_instructions_); 5317 SingleEmissionCheckScope guard(this); 5318 ldff1sw(zt, pg, zn, imm5); 5319 } 5320 void Ldff1w(const ZRegister& zt, 5321 const PRegisterZ& pg, 5322 const Register& xn, 5323 const ZRegister& zm) { 5324 VIXL_ASSERT(allow_macro_instructions_); 5325 SingleEmissionCheckScope guard(this); 5326 ldff1w(zt, pg, xn, zm); 5327 } 5328 void Ldff1w(const ZRegister& zt, 5329 const PRegisterZ& pg, 5330 const ZRegister& zn, 5331 int imm5) { 5332 VIXL_ASSERT(allow_macro_instructions_); 5333 SingleEmissionCheckScope guard(this); 5334 ldff1w(zt, pg, zn, imm5); 5335 } 5336 void Ldnf1b(const ZRegister& zt, 5337 const PRegisterZ& pg, 5338 const SVEMemOperand& addr) { 5339 VIXL_ASSERT(allow_macro_instructions_); 5340 SingleEmissionCheckScope guard(this); 5341 ldnf1b(zt, pg, addr); 5342 } 5343 void Ldnf1d(const ZRegister& zt, 5344 const PRegisterZ& pg, 5345 const SVEMemOperand& addr) { 5346 VIXL_ASSERT(allow_macro_instructions_); 5347 SingleEmissionCheckScope guard(this); 5348 ldnf1d(zt, pg, addr); 5349 } 5350 void Ldnf1h(const ZRegister& zt, 5351 const PRegisterZ& pg, 5352 const SVEMemOperand& addr) { 5353 VIXL_ASSERT(allow_macro_instructions_); 5354 SingleEmissionCheckScope guard(this); 5355 ldnf1h(zt, pg, addr); 5356 } 5357 void Ldnf1sb(const ZRegister& zt, 5358 const PRegisterZ& pg, 5359 const SVEMemOperand& addr) { 5360 VIXL_ASSERT(allow_macro_instructions_); 5361 SingleEmissionCheckScope guard(this); 5362 ldnf1sb(zt, pg, addr); 5363 } 5364 void Ldnf1sh(const ZRegister& zt, 5365 const PRegisterZ& pg, 5366 const SVEMemOperand& addr) { 5367 VIXL_ASSERT(allow_macro_instructions_); 5368 SingleEmissionCheckScope guard(this); 5369 ldnf1sh(zt, pg, addr); 5370 } 5371 void Ldnf1sw(const ZRegister& zt, 5372 const PRegisterZ& pg, 5373 const SVEMemOperand& addr) { 5374 VIXL_ASSERT(allow_macro_instructions_); 5375 SingleEmissionCheckScope guard(this); 5376 ldnf1sw(zt, pg, addr); 5377 } 5378 void Ldnf1w(const ZRegister& zt, 5379 const PRegisterZ& pg, 5380 const SVEMemOperand& addr) { 5381 VIXL_ASSERT(allow_macro_instructions_); 5382 SingleEmissionCheckScope guard(this); 5383 ldnf1w(zt, pg, addr); 5384 } 5385 void Ldnt1b(const ZRegister& zt, 5386 const PRegisterZ& pg, 5387 const SVEMemOperand& addr); 5388 void Ldnt1d(const ZRegister& zt, 5389 const PRegisterZ& pg, 5390 const SVEMemOperand& addr); 5391 void Ldnt1h(const ZRegister& zt, 5392 const PRegisterZ& pg, 5393 const SVEMemOperand& addr); 5394 void Ldnt1w(const ZRegister& zt, 5395 const PRegisterZ& pg, 5396 const SVEMemOperand& addr); 5397 void Ldr(const CPURegister& rt, const SVEMemOperand& addr) { 5398 VIXL_ASSERT(allow_macro_instructions_); 5399 SVELoadStoreScalarImmHelper(rt, addr, &MacroAssembler::ldr); 5400 } 5401 void Lsl(const ZRegister& zd, 5402 const PRegisterM& pg, 5403 const ZRegister& zn, 5404 int shift) { 5405 VIXL_ASSERT(allow_macro_instructions_); 5406 MovprfxHelperScope guard(this, zd, pg, zn); 5407 lsl(zd, pg, zd, shift); 5408 } 5409 void Lsl(const ZRegister& zd, 5410 const PRegisterM& pg, 5411 const ZRegister& zn, 5412 const ZRegister& zm); 5413 void Lsl(const ZRegister& zd, const ZRegister& zn, int shift) { 5414 VIXL_ASSERT(allow_macro_instructions_); 5415 SingleEmissionCheckScope guard(this); 5416 lsl(zd, zn, shift); 5417 } 5418 void Lsl(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 5419 VIXL_ASSERT(allow_macro_instructions_); 5420 SingleEmissionCheckScope guard(this); 5421 lsl(zd, zn, zm); 5422 } 5423 void Lsr(const ZRegister& zd, 5424 const PRegisterM& pg, 5425 const ZRegister& zn, 5426 int shift) { 5427 VIXL_ASSERT(allow_macro_instructions_); 5428 MovprfxHelperScope guard(this, zd, pg, zn); 5429 lsr(zd, pg, zd, shift); 5430 } 5431 void Lsr(const ZRegister& zd, 5432 const PRegisterM& pg, 5433 const ZRegister& zn, 5434 const ZRegister& zm); 5435 void Lsr(const ZRegister& zd, const ZRegister& zn, int shift) { 5436 VIXL_ASSERT(allow_macro_instructions_); 5437 SingleEmissionCheckScope guard(this); 5438 lsr(zd, zn, shift); 5439 } 5440 void Lsr(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 5441 VIXL_ASSERT(allow_macro_instructions_); 5442 SingleEmissionCheckScope guard(this); 5443 lsr(zd, zn, zm); 5444 } 5445 void Mov(const PRegister& pd, const PRegister& pn) { 5446 VIXL_ASSERT(allow_macro_instructions_); 5447 SingleEmissionCheckScope guard(this); 5448 mov(pd.VnB(), pn.VnB()); 5449 } 5450 void Mov(const PRegisterWithLaneSize& pd, 5451 const PRegisterM& pg, 5452 const PRegisterWithLaneSize& pn) { 5453 VIXL_ASSERT(allow_macro_instructions_); 5454 SingleEmissionCheckScope guard(this); 5455 mov(pd, pg, pn); 5456 } 5457 void Mov(const PRegisterWithLaneSize& pd, 5458 const PRegisterZ& pg, 5459 const PRegisterWithLaneSize& pn) { 5460 VIXL_ASSERT(allow_macro_instructions_); 5461 SingleEmissionCheckScope guard(this); 5462 mov(pd, pg, pn); 5463 } 5464 void Mov(const ZRegister& zd, const Register& xn) { 5465 VIXL_ASSERT(allow_macro_instructions_); 5466 SingleEmissionCheckScope guard(this); 5467 mov(zd, xn); 5468 } 5469 5470 void Mov(const ZRegister& zd, const VRegister& vn) { 5471 VIXL_ASSERT(allow_macro_instructions_); 5472 SingleEmissionCheckScope guard(this); 5473 mov(zd, vn); 5474 } 5475 5476 void Mov(const ZRegister& zd, const ZRegister& zn) { 5477 VIXL_ASSERT(allow_macro_instructions_); 5478 SingleEmissionCheckScope guard(this); 5479 mov(zd, zn); 5480 } 5481 void Mov(const ZRegister& zd, const ZRegister& zn, unsigned index) { 5482 VIXL_ASSERT(allow_macro_instructions_); 5483 SingleEmissionCheckScope guard(this); 5484 mov(zd, zn, index); 5485 } 5486 void Mov(const ZRegister& zd, const PRegister& pg, IntegerOperand imm) { 5487 VIXL_ASSERT(allow_macro_instructions_); 5488 Cpy(zd, pg, imm); 5489 } 5490 // TODO: support zeroing predicated moves using movprfx. 5491 void Mov(const ZRegister& zd, const PRegisterM& pg, const Register& rn) { 5492 VIXL_ASSERT(allow_macro_instructions_); 5493 SingleEmissionCheckScope guard(this); 5494 mov(zd, pg, rn); 5495 } 5496 void Mov(const ZRegister& zd, const PRegisterM& pg, const VRegister& vn) { 5497 VIXL_ASSERT(allow_macro_instructions_); 5498 SingleEmissionCheckScope guard(this); 5499 mov(zd, pg, vn); 5500 } 5501 void Mov(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 5502 VIXL_ASSERT(allow_macro_instructions_); 5503 SingleEmissionCheckScope guard(this); 5504 mov(zd, pg, zn); 5505 } 5506 void Mov(const ZRegister& zd, IntegerOperand imm) { 5507 VIXL_ASSERT(allow_macro_instructions_); 5508 Dup(zd, imm); 5509 } 5510 void Movs(const PRegister& pd, const PRegister& pn) { 5511 VIXL_ASSERT(allow_macro_instructions_); 5512 SingleEmissionCheckScope guard(this); 5513 movs(pd, pn); 5514 } 5515 void Movs(const PRegisterWithLaneSize& pd, 5516 const PRegisterZ& pg, 5517 const PRegisterWithLaneSize& pn) { 5518 VIXL_ASSERT(allow_macro_instructions_); 5519 SingleEmissionCheckScope guard(this); 5520 movs(pd, pg, pn); 5521 } 5522 // zd = za + (zn * zm) 5523 void Mla(const ZRegister& zd, 5524 const PRegisterM& pg, 5525 const ZRegister& za, 5526 const ZRegister& zn, 5527 const ZRegister& zm); 5528 // zd = za - (zn * zm) 5529 void Mls(const ZRegister& zd, 5530 const PRegisterM& pg, 5531 const ZRegister& za, 5532 const ZRegister& zn, 5533 const ZRegister& zm); 5534 void Mul(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm); 5535 void Nand(const PRegisterWithLaneSize& pd, 5536 const PRegisterZ& pg, 5537 const PRegisterWithLaneSize& pn, 5538 const PRegisterWithLaneSize& pm) { 5539 VIXL_ASSERT(allow_macro_instructions_); 5540 SingleEmissionCheckScope guard(this); 5541 nand(pd, pg, pn, pm); 5542 } 5543 void Nands(const PRegisterWithLaneSize& pd, 5544 const PRegisterZ& pg, 5545 const PRegisterWithLaneSize& pn, 5546 const PRegisterWithLaneSize& pm) { 5547 VIXL_ASSERT(allow_macro_instructions_); 5548 SingleEmissionCheckScope guard(this); 5549 nands(pd, pg, pn, pm); 5550 } 5551 // There is no instruction with this form, but we can implement it using 5552 // `subr`. 5553 void Neg(const ZRegister& zd, const ZRegister& zn) { 5554 VIXL_ASSERT(allow_macro_instructions_); 5555 MovprfxHelperScope guard(this, zd, zn); 5556 subr(zd, zd, 0); 5557 } 5558 void Neg(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 5559 VIXL_ASSERT(allow_macro_instructions_); 5560 SingleEmissionCheckScope guard(this); 5561 neg(zd, pg, zn); 5562 } 5563 void Nor(const PRegisterWithLaneSize& pd, 5564 const PRegisterZ& pg, 5565 const PRegisterWithLaneSize& pn, 5566 const PRegisterWithLaneSize& pm) { 5567 VIXL_ASSERT(allow_macro_instructions_); 5568 SingleEmissionCheckScope guard(this); 5569 nor(pd, pg, pn, pm); 5570 } 5571 void Nors(const PRegisterWithLaneSize& pd, 5572 const PRegisterZ& pg, 5573 const PRegisterWithLaneSize& pn, 5574 const PRegisterWithLaneSize& pm) { 5575 VIXL_ASSERT(allow_macro_instructions_); 5576 SingleEmissionCheckScope guard(this); 5577 nors(pd, pg, pn, pm); 5578 } 5579 void Not(const PRegisterWithLaneSize& pd, 5580 const PRegisterZ& pg, 5581 const PRegisterWithLaneSize& pn) { 5582 VIXL_ASSERT(allow_macro_instructions_); 5583 SingleEmissionCheckScope guard(this); 5584 not_(pd, pg, pn); 5585 } 5586 void Not(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 5587 VIXL_ASSERT(allow_macro_instructions_); 5588 SingleEmissionCheckScope guard(this); 5589 not_(zd, pg, zn); 5590 } 5591 void Nots(const PRegisterWithLaneSize& pd, 5592 const PRegisterZ& pg, 5593 const PRegisterWithLaneSize& pn) { 5594 VIXL_ASSERT(allow_macro_instructions_); 5595 SingleEmissionCheckScope guard(this); 5596 nots(pd, pg, pn); 5597 } 5598 void Orn(const PRegisterWithLaneSize& pd, 5599 const PRegisterZ& pg, 5600 const PRegisterWithLaneSize& pn, 5601 const PRegisterWithLaneSize& pm) { 5602 VIXL_ASSERT(allow_macro_instructions_); 5603 SingleEmissionCheckScope guard(this); 5604 orn(pd, pg, pn, pm); 5605 } 5606 void Orn(const ZRegister& zd, const ZRegister& zn, uint64_t imm) { 5607 VIXL_ASSERT(allow_macro_instructions_); 5608 SingleEmissionCheckScope guard(this); 5609 if (IsImmLogical(imm, zd.GetLaneSizeInBits())) { 5610 orn(zd, zn, imm); 5611 } else { 5612 // TODO: Synthesise the immediate once 'Mov' is implemented. 5613 VIXL_UNIMPLEMENTED(); 5614 } 5615 } 5616 void Orns(const PRegisterWithLaneSize& pd, 5617 const PRegisterZ& pg, 5618 const PRegisterWithLaneSize& pn, 5619 const PRegisterWithLaneSize& pm) { 5620 VIXL_ASSERT(allow_macro_instructions_); 5621 SingleEmissionCheckScope guard(this); 5622 orns(pd, pg, pn, pm); 5623 } 5624 void Orr(const PRegisterWithLaneSize& pd, 5625 const PRegisterZ& pg, 5626 const PRegisterWithLaneSize& pn, 5627 const PRegisterWithLaneSize& pm) { 5628 VIXL_ASSERT(allow_macro_instructions_); 5629 SingleEmissionCheckScope guard(this); 5630 orr(pd, pg, pn, pm); 5631 } 5632 void Orr(const ZRegister& zd, const ZRegister& zn, uint64_t imm) { 5633 VIXL_ASSERT(allow_macro_instructions_); 5634 SingleEmissionCheckScope guard(this); 5635 if (IsImmLogical(imm, zd.GetLaneSizeInBits())) { 5636 orr(zd, zn, imm); 5637 } else { 5638 // TODO: Synthesise the immediate once 'Mov' is implemented. 5639 VIXL_UNIMPLEMENTED(); 5640 } 5641 } 5642 void Orr(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 5643 VIXL_ASSERT(allow_macro_instructions_); 5644 VIXL_ASSERT(AreSameLaneSize(zd, zn, zm)); 5645 SingleEmissionCheckScope guard(this); 5646 orr(zd.VnD(), zn.VnD(), zm.VnD()); 5647 } 5648 void Orrs(const PRegisterWithLaneSize& pd, 5649 const PRegisterZ& pg, 5650 const PRegisterWithLaneSize& pn, 5651 const PRegisterWithLaneSize& pm) { 5652 VIXL_ASSERT(allow_macro_instructions_); 5653 SingleEmissionCheckScope guard(this); 5654 orrs(pd, pg, pn, pm); 5655 } 5656 void Orv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 5657 VIXL_ASSERT(allow_macro_instructions_); 5658 SingleEmissionCheckScope guard(this); 5659 orv(vd, pg, zn); 5660 } 5661 void Pfalse(const PRegister& pd) { 5662 VIXL_ASSERT(allow_macro_instructions_); 5663 VIXL_ASSERT(pd.IsUnqualified()); 5664 SingleEmissionCheckScope guard(this); 5665 // No matter what the lane size is, overall this operation just writes zeros 5666 // throughout the register. 5667 pfalse(pd.VnB()); 5668 } 5669 void Pfirst(const PRegisterWithLaneSize& pd, 5670 const PRegister& pg, 5671 const PRegisterWithLaneSize& pn); 5672 void Pnext(const PRegisterWithLaneSize& pd, 5673 const PRegister& pg, 5674 const PRegisterWithLaneSize& pn); 5675 void Prfb(PrefetchOperation prfop, 5676 const PRegister& pg, 5677 const SVEMemOperand addr) { 5678 VIXL_ASSERT(allow_macro_instructions_); 5679 SingleEmissionCheckScope guard(this); 5680 prfb(prfop, pg, addr); 5681 } 5682 void Prfh(PrefetchOperation prfop, 5683 const PRegister& pg, 5684 const SVEMemOperand addr) { 5685 VIXL_ASSERT(allow_macro_instructions_); 5686 SingleEmissionCheckScope guard(this); 5687 prfh(prfop, pg, addr); 5688 } 5689 void Prfw(PrefetchOperation prfop, 5690 const PRegister& pg, 5691 const SVEMemOperand addr) { 5692 VIXL_ASSERT(allow_macro_instructions_); 5693 SingleEmissionCheckScope guard(this); 5694 prfw(prfop, pg, addr); 5695 } 5696 void Prfd(PrefetchOperation prfop, 5697 const PRegister& pg, 5698 const SVEMemOperand addr) { 5699 VIXL_ASSERT(allow_macro_instructions_); 5700 SingleEmissionCheckScope guard(this); 5701 prfd(prfop, pg, addr); 5702 } 5703 void Ptest(const PRegister& pg, const PRegisterWithLaneSize& pn) { 5704 VIXL_ASSERT(allow_macro_instructions_); 5705 SingleEmissionCheckScope guard(this); 5706 ptest(pg, pn); 5707 } 5708 void Ptrue(const PRegisterWithLaneSize& pd, 5709 SVEPredicateConstraint pattern, 5710 FlagsUpdate s); 5711 void Ptrue(const PRegisterWithLaneSize& pd, 5712 SVEPredicateConstraint pattern = SVE_ALL) { 5713 VIXL_ASSERT(allow_macro_instructions_); 5714 SingleEmissionCheckScope guard(this); 5715 ptrue(pd, pattern); 5716 } 5717 void Ptrues(const PRegisterWithLaneSize& pd, 5718 SVEPredicateConstraint pattern = SVE_ALL) { 5719 VIXL_ASSERT(allow_macro_instructions_); 5720 SingleEmissionCheckScope guard(this); 5721 ptrues(pd, pattern); 5722 } 5723 void Punpkhi(const PRegisterWithLaneSize& pd, 5724 const PRegisterWithLaneSize& pn) { 5725 VIXL_ASSERT(allow_macro_instructions_); 5726 SingleEmissionCheckScope guard(this); 5727 punpkhi(pd, pn); 5728 } 5729 void Punpklo(const PRegisterWithLaneSize& pd, 5730 const PRegisterWithLaneSize& pn) { 5731 VIXL_ASSERT(allow_macro_instructions_); 5732 SingleEmissionCheckScope guard(this); 5733 punpklo(pd, pn); 5734 } 5735 void Rbit(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 5736 VIXL_ASSERT(allow_macro_instructions_); 5737 SingleEmissionCheckScope guard(this); 5738 rbit(zd, pg, zn); 5739 } 5740 void Rdffr(const PRegister& pd) { 5741 VIXL_ASSERT(allow_macro_instructions_); 5742 // Although this is essentially just a move, it writes every bit and so can 5743 // only support b-sized lane because other lane sizes would simplicity clear 5744 // bits in `pd`. 5745 VIXL_ASSERT(!pd.HasLaneSize() || pd.IsLaneSizeB()); 5746 VIXL_ASSERT(pd.IsUnqualified()); 5747 SingleEmissionCheckScope guard(this); 5748 rdffr(pd.VnB()); 5749 } 5750 void Rdffr(const PRegisterWithLaneSize& pd, const PRegisterZ& pg) { 5751 VIXL_ASSERT(allow_macro_instructions_); 5752 SingleEmissionCheckScope guard(this); 5753 rdffr(pd, pg); 5754 } 5755 void Rdffrs(const PRegisterWithLaneSize& pd, const PRegisterZ& pg) { 5756 VIXL_ASSERT(allow_macro_instructions_); 5757 SingleEmissionCheckScope guard(this); 5758 rdffrs(pd, pg); 5759 } 5760 // Note that there is no `rdpl` instruction, but this macro emulates it (for 5761 // symmetry with `Rdvl`). 5762 void Rdpl(const Register& xd, int64_t multiplier) { 5763 VIXL_ASSERT(allow_macro_instructions_); 5764 Addpl(xd, xzr, multiplier); 5765 } 5766 void Rdvl(const Register& xd, int64_t multiplier) { 5767 VIXL_ASSERT(allow_macro_instructions_); 5768 Addvl(xd, xzr, multiplier); 5769 } 5770 void Rev(const PRegisterWithLaneSize& pd, const PRegisterWithLaneSize& pn) { 5771 VIXL_ASSERT(allow_macro_instructions_); 5772 SingleEmissionCheckScope guard(this); 5773 rev(pd, pn); 5774 } 5775 void Rev(const ZRegister& zd, const ZRegister& zn) { 5776 VIXL_ASSERT(allow_macro_instructions_); 5777 SingleEmissionCheckScope guard(this); 5778 rev(zd, zn); 5779 } 5780 void Revb(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 5781 VIXL_ASSERT(allow_macro_instructions_); 5782 SingleEmissionCheckScope guard(this); 5783 revb(zd, pg, zn); 5784 } 5785 void Revh(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 5786 VIXL_ASSERT(allow_macro_instructions_); 5787 SingleEmissionCheckScope guard(this); 5788 revh(zd, pg, zn); 5789 } 5790 void Revw(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 5791 VIXL_ASSERT(allow_macro_instructions_); 5792 SingleEmissionCheckScope guard(this); 5793 revw(zd, pg, zn); 5794 } 5795 void Saddv(const VRegister& dd, const PRegister& pg, const ZRegister& zn) { 5796 VIXL_ASSERT(allow_macro_instructions_); 5797 SingleEmissionCheckScope guard(this); 5798 saddv(dd, pg, zn); 5799 } 5800 void Scvtf(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 5801 VIXL_ASSERT(allow_macro_instructions_); 5802 SingleEmissionCheckScope guard(this); 5803 scvtf(zd, pg, zn); 5804 } 5805 void Sdiv(const ZRegister& zd, 5806 const PRegisterM& pg, 5807 const ZRegister& zn, 5808 const ZRegister& zm); 5809 void Sdot(const ZRegister& zd, 5810 const ZRegister& za, 5811 const ZRegister& zn, 5812 const ZRegister& zm); 5813 void Sdot(const ZRegister& zd, 5814 const ZRegister& za, 5815 const ZRegister& zn, 5816 const ZRegister& zm, 5817 int index); 5818 void Sel(const PRegisterWithLaneSize& pd, 5819 const PRegister& pg, 5820 const PRegisterWithLaneSize& pn, 5821 const PRegisterWithLaneSize& pm) { 5822 VIXL_ASSERT(allow_macro_instructions_); 5823 SingleEmissionCheckScope guard(this); 5824 sel(pd, pg, pn, pm); 5825 } 5826 void Sel(const ZRegister& zd, 5827 const PRegister& pg, 5828 const ZRegister& zn, 5829 const ZRegister& zm) { 5830 VIXL_ASSERT(allow_macro_instructions_); 5831 SingleEmissionCheckScope guard(this); 5832 sel(zd, pg, zn, zm); 5833 } 5834 void Setffr() { 5835 VIXL_ASSERT(allow_macro_instructions_); 5836 SingleEmissionCheckScope guard(this); 5837 setffr(); 5838 } 5839 void Smax(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm); 5840 void Smaxv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 5841 VIXL_ASSERT(allow_macro_instructions_); 5842 SingleEmissionCheckScope guard(this); 5843 smaxv(vd, pg, zn); 5844 } 5845 void Smin(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm); 5846 void Sminv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 5847 VIXL_ASSERT(allow_macro_instructions_); 5848 SingleEmissionCheckScope guard(this); 5849 sminv(vd, pg, zn); 5850 } 5851 void Splice(const ZRegister& zd, 5852 const PRegister& pg, 5853 const ZRegister& zn, 5854 const ZRegister& zm); 5855 void Sqadd(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 5856 VIXL_ASSERT(allow_macro_instructions_); 5857 SingleEmissionCheckScope guard(this); 5858 sqadd(zd, zn, zm); 5859 } 5860 void Sqadd(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm) { 5861 VIXL_ASSERT(allow_macro_instructions_); 5862 VIXL_ASSERT(imm.IsUint8() || 5863 (imm.IsUint16() && ((imm.AsUint16() & 0xff) == 0))); 5864 MovprfxHelperScope guard(this, zd, zn); 5865 sqadd(zd, zd, imm.AsUint16()); 5866 } 5867 void Sqdecb(const Register& xd, 5868 const Register& wn, 5869 int pattern = SVE_ALL, 5870 int multiplier = 1) { 5871 VIXL_ASSERT(allow_macro_instructions_); 5872 SingleEmissionCheckScope guard(this); 5873 sqdecb(xd, wn, pattern, multiplier); 5874 } 5875 void Sqdecb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 5876 VIXL_ASSERT(allow_macro_instructions_); 5877 SingleEmissionCheckScope guard(this); 5878 sqdecb(rdn, pattern, multiplier); 5879 } 5880 void Sqdecd(const Register& xd, 5881 const Register& wn, 5882 int pattern = SVE_ALL, 5883 int multiplier = 1) { 5884 VIXL_ASSERT(allow_macro_instructions_); 5885 SingleEmissionCheckScope guard(this); 5886 sqdecd(xd, wn, pattern, multiplier); 5887 } 5888 void Sqdecd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 5889 VIXL_ASSERT(allow_macro_instructions_); 5890 SingleEmissionCheckScope guard(this); 5891 sqdecd(rdn, pattern, multiplier); 5892 } 5893 void Sqdecd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 5894 VIXL_ASSERT(allow_macro_instructions_); 5895 SingleEmissionCheckScope guard(this); 5896 sqdecd(zdn, pattern, multiplier); 5897 } 5898 void Sqdech(const Register& xd, 5899 const Register& wn, 5900 int pattern = SVE_ALL, 5901 int multiplier = 1) { 5902 VIXL_ASSERT(allow_macro_instructions_); 5903 SingleEmissionCheckScope guard(this); 5904 sqdech(xd, wn, pattern, multiplier); 5905 } 5906 void Sqdech(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 5907 VIXL_ASSERT(allow_macro_instructions_); 5908 SingleEmissionCheckScope guard(this); 5909 sqdech(rdn, pattern, multiplier); 5910 } 5911 void Sqdech(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 5912 VIXL_ASSERT(allow_macro_instructions_); 5913 SingleEmissionCheckScope guard(this); 5914 sqdech(zdn, pattern, multiplier); 5915 } 5916 void Sqdecp(const Register& xdn, 5917 const PRegisterWithLaneSize& pg, 5918 const Register& wdn) { 5919 VIXL_ASSERT(allow_macro_instructions_); 5920 SingleEmissionCheckScope guard(this); 5921 sqdecp(xdn, pg, wdn); 5922 } 5923 void Sqdecp(const Register& xdn, const PRegisterWithLaneSize& pg) { 5924 VIXL_ASSERT(allow_macro_instructions_); 5925 SingleEmissionCheckScope guard(this); 5926 sqdecp(xdn, pg); 5927 } 5928 void Sqdecp(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) { 5929 VIXL_ASSERT(allow_macro_instructions_); 5930 VIXL_ASSERT(AreSameFormat(zd, zn)); 5931 // `sqdecp` writes every lane, so use an unpredicated movprfx. 5932 MovprfxHelperScope guard(this, zd, zn); 5933 sqdecp(zd, pg); 5934 } 5935 void Sqdecp(const ZRegister& zdn, const PRegister& pg) { 5936 Sqdecp(zdn, pg, zdn); 5937 } 5938 void Sqdecw(const Register& xd, 5939 const Register& wn, 5940 int pattern = SVE_ALL, 5941 int multiplier = 1) { 5942 VIXL_ASSERT(allow_macro_instructions_); 5943 SingleEmissionCheckScope guard(this); 5944 sqdecw(xd, wn, pattern, multiplier); 5945 } 5946 void Sqdecw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 5947 VIXL_ASSERT(allow_macro_instructions_); 5948 SingleEmissionCheckScope guard(this); 5949 sqdecw(rdn, pattern, multiplier); 5950 } 5951 void Sqdecw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 5952 VIXL_ASSERT(allow_macro_instructions_); 5953 SingleEmissionCheckScope guard(this); 5954 sqdecw(zdn, pattern, multiplier); 5955 } 5956 void Sqincb(const Register& xd, 5957 const Register& wn, 5958 int pattern = SVE_ALL, 5959 int multiplier = 1) { 5960 VIXL_ASSERT(allow_macro_instructions_); 5961 SingleEmissionCheckScope guard(this); 5962 sqincb(xd, wn, pattern, multiplier); 5963 } 5964 void Sqincb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 5965 VIXL_ASSERT(allow_macro_instructions_); 5966 SingleEmissionCheckScope guard(this); 5967 sqincb(rdn, pattern, multiplier); 5968 } 5969 void Sqincd(const Register& xd, 5970 const Register& wn, 5971 int pattern = SVE_ALL, 5972 int multiplier = 1) { 5973 VIXL_ASSERT(allow_macro_instructions_); 5974 SingleEmissionCheckScope guard(this); 5975 sqincd(xd, wn, pattern, multiplier); 5976 } 5977 void Sqincd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 5978 VIXL_ASSERT(allow_macro_instructions_); 5979 SingleEmissionCheckScope guard(this); 5980 sqincd(rdn, pattern, multiplier); 5981 } 5982 void Sqincd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 5983 VIXL_ASSERT(allow_macro_instructions_); 5984 SingleEmissionCheckScope guard(this); 5985 sqincd(zdn, pattern, multiplier); 5986 } 5987 void Sqinch(const Register& xd, 5988 const Register& wn, 5989 int pattern = SVE_ALL, 5990 int multiplier = 1) { 5991 VIXL_ASSERT(allow_macro_instructions_); 5992 SingleEmissionCheckScope guard(this); 5993 sqinch(xd, wn, pattern, multiplier); 5994 } 5995 void Sqinch(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 5996 VIXL_ASSERT(allow_macro_instructions_); 5997 SingleEmissionCheckScope guard(this); 5998 sqinch(rdn, pattern, multiplier); 5999 } 6000 void Sqinch(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 6001 VIXL_ASSERT(allow_macro_instructions_); 6002 SingleEmissionCheckScope guard(this); 6003 sqinch(zdn, pattern, multiplier); 6004 } 6005 void Sqincp(const Register& xdn, 6006 const PRegisterWithLaneSize& pg, 6007 const Register& wdn) { 6008 VIXL_ASSERT(allow_macro_instructions_); 6009 SingleEmissionCheckScope guard(this); 6010 sqincp(xdn, pg, wdn); 6011 } 6012 void Sqincp(const Register& xdn, const PRegisterWithLaneSize& pg) { 6013 VIXL_ASSERT(allow_macro_instructions_); 6014 SingleEmissionCheckScope guard(this); 6015 sqincp(xdn, pg); 6016 } 6017 void Sqincp(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) { 6018 VIXL_ASSERT(allow_macro_instructions_); 6019 VIXL_ASSERT(AreSameFormat(zd, zn)); 6020 // `sqincp` writes every lane, so use an unpredicated movprfx. 6021 MovprfxHelperScope guard(this, zd, zn); 6022 sqincp(zd, pg); 6023 } 6024 void Sqincp(const ZRegister& zdn, const PRegister& pg) { 6025 Sqincp(zdn, pg, zdn); 6026 } 6027 void Sqincw(const Register& xd, 6028 const Register& wn, 6029 int pattern = SVE_ALL, 6030 int multiplier = 1) { 6031 VIXL_ASSERT(allow_macro_instructions_); 6032 SingleEmissionCheckScope guard(this); 6033 sqincw(xd, wn, pattern, multiplier); 6034 } 6035 void Sqincw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 6036 VIXL_ASSERT(allow_macro_instructions_); 6037 SingleEmissionCheckScope guard(this); 6038 sqincw(rdn, pattern, multiplier); 6039 } 6040 void Sqincw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 6041 VIXL_ASSERT(allow_macro_instructions_); 6042 SingleEmissionCheckScope guard(this); 6043 sqincw(zdn, pattern, multiplier); 6044 } 6045 void Sqsub(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6046 VIXL_ASSERT(allow_macro_instructions_); 6047 SingleEmissionCheckScope guard(this); 6048 sqsub(zd, zn, zm); 6049 } 6050 void Sqsub(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm) { 6051 VIXL_ASSERT(allow_macro_instructions_); 6052 VIXL_ASSERT(imm.IsUint8() || 6053 (imm.IsUint16() && ((imm.AsUint16() & 0xff) == 0))); 6054 MovprfxHelperScope guard(this, zd, zn); 6055 sqsub(zd, zd, imm.AsUint16()); 6056 } 6057 void St1b(const ZRegister& zt, 6058 const PRegister& pg, 6059 const SVEMemOperand& addr); 6060 void St1h(const ZRegister& zt, 6061 const PRegister& pg, 6062 const SVEMemOperand& addr); 6063 void St1w(const ZRegister& zt, 6064 const PRegister& pg, 6065 const SVEMemOperand& addr); 6066 void St1d(const ZRegister& zt, 6067 const PRegister& pg, 6068 const SVEMemOperand& addr); 6069 void St2b(const ZRegister& zt1, 6070 const ZRegister& zt2, 6071 const PRegister& pg, 6072 const SVEMemOperand& addr) { 6073 VIXL_ASSERT(allow_macro_instructions_); 6074 SingleEmissionCheckScope guard(this); 6075 st2b(zt1, zt2, pg, addr); 6076 } 6077 void St2h(const ZRegister& zt1, 6078 const ZRegister& zt2, 6079 const PRegister& pg, 6080 const SVEMemOperand& addr) { 6081 VIXL_ASSERT(allow_macro_instructions_); 6082 SingleEmissionCheckScope guard(this); 6083 st2h(zt1, zt2, pg, addr); 6084 } 6085 void St2w(const ZRegister& zt1, 6086 const ZRegister& zt2, 6087 const PRegister& pg, 6088 const SVEMemOperand& addr) { 6089 VIXL_ASSERT(allow_macro_instructions_); 6090 SingleEmissionCheckScope guard(this); 6091 st2w(zt1, zt2, pg, addr); 6092 } 6093 void St2d(const ZRegister& zt1, 6094 const ZRegister& zt2, 6095 const PRegister& pg, 6096 const SVEMemOperand& addr) { 6097 VIXL_ASSERT(allow_macro_instructions_); 6098 SingleEmissionCheckScope guard(this); 6099 st2d(zt1, zt2, pg, addr); 6100 } 6101 void St3b(const ZRegister& zt1, 6102 const ZRegister& zt2, 6103 const ZRegister& zt3, 6104 const PRegister& pg, 6105 const SVEMemOperand& addr) { 6106 VIXL_ASSERT(allow_macro_instructions_); 6107 SingleEmissionCheckScope guard(this); 6108 st3b(zt1, zt2, zt3, pg, addr); 6109 } 6110 void St3h(const ZRegister& zt1, 6111 const ZRegister& zt2, 6112 const ZRegister& zt3, 6113 const PRegister& pg, 6114 const SVEMemOperand& addr) { 6115 VIXL_ASSERT(allow_macro_instructions_); 6116 SingleEmissionCheckScope guard(this); 6117 st3h(zt1, zt2, zt3, pg, addr); 6118 } 6119 void St3w(const ZRegister& zt1, 6120 const ZRegister& zt2, 6121 const ZRegister& zt3, 6122 const PRegister& pg, 6123 const SVEMemOperand& addr) { 6124 VIXL_ASSERT(allow_macro_instructions_); 6125 SingleEmissionCheckScope guard(this); 6126 st3w(zt1, zt2, zt3, pg, addr); 6127 } 6128 void St3d(const ZRegister& zt1, 6129 const ZRegister& zt2, 6130 const ZRegister& zt3, 6131 const PRegister& pg, 6132 const SVEMemOperand& addr) { 6133 VIXL_ASSERT(allow_macro_instructions_); 6134 SingleEmissionCheckScope guard(this); 6135 st3d(zt1, zt2, zt3, pg, addr); 6136 } 6137 void St4b(const ZRegister& zt1, 6138 const ZRegister& zt2, 6139 const ZRegister& zt3, 6140 const ZRegister& zt4, 6141 const PRegister& pg, 6142 const SVEMemOperand& addr) { 6143 VIXL_ASSERT(allow_macro_instructions_); 6144 SingleEmissionCheckScope guard(this); 6145 st4b(zt1, zt2, zt3, zt4, pg, addr); 6146 } 6147 void St4h(const ZRegister& zt1, 6148 const ZRegister& zt2, 6149 const ZRegister& zt3, 6150 const ZRegister& zt4, 6151 const PRegister& pg, 6152 const SVEMemOperand& addr) { 6153 VIXL_ASSERT(allow_macro_instructions_); 6154 SingleEmissionCheckScope guard(this); 6155 st4h(zt1, zt2, zt3, zt4, pg, addr); 6156 } 6157 void St4w(const ZRegister& zt1, 6158 const ZRegister& zt2, 6159 const ZRegister& zt3, 6160 const ZRegister& zt4, 6161 const PRegister& pg, 6162 const SVEMemOperand& addr) { 6163 VIXL_ASSERT(allow_macro_instructions_); 6164 SingleEmissionCheckScope guard(this); 6165 st4w(zt1, zt2, zt3, zt4, pg, addr); 6166 } 6167 void St4d(const ZRegister& zt1, 6168 const ZRegister& zt2, 6169 const ZRegister& zt3, 6170 const ZRegister& zt4, 6171 const PRegister& pg, 6172 const SVEMemOperand& addr) { 6173 VIXL_ASSERT(allow_macro_instructions_); 6174 SingleEmissionCheckScope guard(this); 6175 st4d(zt1, zt2, zt3, zt4, pg, addr); 6176 } 6177 void Stnt1b(const ZRegister& zt, 6178 const PRegister& pg, 6179 const SVEMemOperand& addr); 6180 void Stnt1d(const ZRegister& zt, 6181 const PRegister& pg, 6182 const SVEMemOperand& addr); 6183 void Stnt1h(const ZRegister& zt, 6184 const PRegister& pg, 6185 const SVEMemOperand& addr); 6186 void Stnt1w(const ZRegister& zt, 6187 const PRegister& pg, 6188 const SVEMemOperand& addr); 6189 void Str(const CPURegister& rt, const SVEMemOperand& addr) { 6190 VIXL_ASSERT(allow_macro_instructions_); 6191 SVELoadStoreScalarImmHelper(rt, addr, &MacroAssembler::str); 6192 } 6193 void Sub(const ZRegister& zd, 6194 const PRegisterM& pg, 6195 const ZRegister& zn, 6196 const ZRegister& zm); 6197 void Sub(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6198 VIXL_ASSERT(allow_macro_instructions_); 6199 SingleEmissionCheckScope guard(this); 6200 sub(zd, zn, zm); 6201 } 6202 void Sub(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm) { 6203 VIXL_ASSERT(allow_macro_instructions_); 6204 AddSubHelper(kSubImmediate, zd, zn, imm); 6205 } 6206 void Sub(const ZRegister& zd, IntegerOperand imm, const ZRegister& zm); 6207 void Sunpkhi(const ZRegister& zd, const ZRegister& zn) { 6208 VIXL_ASSERT(allow_macro_instructions_); 6209 SingleEmissionCheckScope guard(this); 6210 sunpkhi(zd, zn); 6211 } 6212 void Sunpklo(const ZRegister& zd, const ZRegister& zn) { 6213 VIXL_ASSERT(allow_macro_instructions_); 6214 SingleEmissionCheckScope guard(this); 6215 sunpklo(zd, zn); 6216 } 6217 void Sxtb(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 6218 VIXL_ASSERT(allow_macro_instructions_); 6219 SingleEmissionCheckScope guard(this); 6220 sxtb(zd, pg, zn); 6221 } 6222 void Sxth(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 6223 VIXL_ASSERT(allow_macro_instructions_); 6224 SingleEmissionCheckScope guard(this); 6225 sxth(zd, pg, zn); 6226 } 6227 void Sxtw(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 6228 VIXL_ASSERT(allow_macro_instructions_); 6229 SingleEmissionCheckScope guard(this); 6230 sxtw(zd, pg, zn); 6231 } 6232 void Tbl(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6233 VIXL_ASSERT(allow_macro_instructions_); 6234 SingleEmissionCheckScope guard(this); 6235 tbl(zd, zn, zm); 6236 } 6237 void Trn1(const PRegisterWithLaneSize& pd, 6238 const PRegisterWithLaneSize& pn, 6239 const PRegisterWithLaneSize& pm) { 6240 VIXL_ASSERT(allow_macro_instructions_); 6241 SingleEmissionCheckScope guard(this); 6242 trn1(pd, pn, pm); 6243 } 6244 void Trn1(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6245 VIXL_ASSERT(allow_macro_instructions_); 6246 SingleEmissionCheckScope guard(this); 6247 trn1(zd, zn, zm); 6248 } 6249 void Trn2(const PRegisterWithLaneSize& pd, 6250 const PRegisterWithLaneSize& pn, 6251 const PRegisterWithLaneSize& pm) { 6252 VIXL_ASSERT(allow_macro_instructions_); 6253 SingleEmissionCheckScope guard(this); 6254 trn2(pd, pn, pm); 6255 } 6256 void Trn2(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6257 VIXL_ASSERT(allow_macro_instructions_); 6258 SingleEmissionCheckScope guard(this); 6259 trn2(zd, zn, zm); 6260 } 6261 void Uaddv(const VRegister& dd, const PRegister& pg, const ZRegister& zn) { 6262 VIXL_ASSERT(allow_macro_instructions_); 6263 SingleEmissionCheckScope guard(this); 6264 uaddv(dd, pg, zn); 6265 } 6266 void Ucvtf(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 6267 VIXL_ASSERT(allow_macro_instructions_); 6268 SingleEmissionCheckScope guard(this); 6269 ucvtf(zd, pg, zn); 6270 } 6271 void Udiv(const ZRegister& zd, 6272 const PRegisterM& pg, 6273 const ZRegister& zn, 6274 const ZRegister& zm); 6275 void Udot(const ZRegister& zd, 6276 const ZRegister& za, 6277 const ZRegister& zn, 6278 const ZRegister& zm); 6279 void Udot(const ZRegister& zd, 6280 const ZRegister& za, 6281 const ZRegister& zn, 6282 const ZRegister& zm, 6283 int index); 6284 void Umax(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm); 6285 void Umaxv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 6286 VIXL_ASSERT(allow_macro_instructions_); 6287 SingleEmissionCheckScope guard(this); 6288 umaxv(vd, pg, zn); 6289 } 6290 void Umin(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm); 6291 void Uminv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) { 6292 VIXL_ASSERT(allow_macro_instructions_); 6293 SingleEmissionCheckScope guard(this); 6294 uminv(vd, pg, zn); 6295 } 6296 void Uqadd(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6297 VIXL_ASSERT(allow_macro_instructions_); 6298 SingleEmissionCheckScope guard(this); 6299 uqadd(zd, zn, zm); 6300 } 6301 void Uqadd(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm) { 6302 VIXL_ASSERT(allow_macro_instructions_); 6303 VIXL_ASSERT(imm.IsUint8() || 6304 (imm.IsUint16() && ((imm.AsUint16() & 0xff) == 0))); 6305 MovprfxHelperScope guard(this, zd, zn); 6306 uqadd(zd, zd, imm.AsUint16()); 6307 } 6308 void Uqdecb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 6309 VIXL_ASSERT(allow_macro_instructions_); 6310 SingleEmissionCheckScope guard(this); 6311 uqdecb(rdn, pattern, multiplier); 6312 } 6313 void Uqdecd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 6314 VIXL_ASSERT(allow_macro_instructions_); 6315 SingleEmissionCheckScope guard(this); 6316 uqdecd(rdn, pattern, multiplier); 6317 } 6318 void Uqdecd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 6319 VIXL_ASSERT(allow_macro_instructions_); 6320 SingleEmissionCheckScope guard(this); 6321 uqdecd(zdn, pattern, multiplier); 6322 } 6323 void Uqdech(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 6324 VIXL_ASSERT(allow_macro_instructions_); 6325 SingleEmissionCheckScope guard(this); 6326 uqdech(rdn, pattern, multiplier); 6327 } 6328 void Uqdech(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 6329 VIXL_ASSERT(allow_macro_instructions_); 6330 SingleEmissionCheckScope guard(this); 6331 uqdech(zdn, pattern, multiplier); 6332 } 6333 // The saturation is based on the size of `rn`. The result is zero-extended 6334 // into `rd`, which must be at least as big. 6335 void Uqdecp(const Register& rd, 6336 const PRegisterWithLaneSize& pg, 6337 const Register& rn) { 6338 VIXL_ASSERT(allow_macro_instructions_); 6339 VIXL_ASSERT(rd.Aliases(rn)); 6340 VIXL_ASSERT(rd.GetSizeInBytes() >= rn.GetSizeInBytes()); 6341 SingleEmissionCheckScope guard(this); 6342 if (rn.Is64Bits()) { 6343 uqdecp(rd, pg); 6344 } else { 6345 // Convert <Xd> into <Wd>, to make this more consistent with Sqdecp. 6346 uqdecp(rd.W(), pg); 6347 } 6348 } 6349 void Uqdecp(const Register& rdn, const PRegisterWithLaneSize& pg) { 6350 Uqdecp(rdn, pg, rdn); 6351 } 6352 void Uqdecp(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) { 6353 VIXL_ASSERT(allow_macro_instructions_); 6354 VIXL_ASSERT(AreSameFormat(zd, zn)); 6355 // `sqdecp` writes every lane, so use an unpredicated movprfx. 6356 MovprfxHelperScope guard(this, zd, zn); 6357 uqdecp(zd, pg); 6358 } 6359 void Uqdecp(const ZRegister& zdn, const PRegister& pg) { 6360 Uqdecp(zdn, pg, zdn); 6361 } 6362 void Uqdecw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 6363 VIXL_ASSERT(allow_macro_instructions_); 6364 SingleEmissionCheckScope guard(this); 6365 uqdecw(rdn, pattern, multiplier); 6366 } 6367 void Uqdecw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 6368 VIXL_ASSERT(allow_macro_instructions_); 6369 SingleEmissionCheckScope guard(this); 6370 uqdecw(zdn, pattern, multiplier); 6371 } 6372 void Uqincb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 6373 VIXL_ASSERT(allow_macro_instructions_); 6374 SingleEmissionCheckScope guard(this); 6375 uqincb(rdn, pattern, multiplier); 6376 } 6377 void Uqincd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 6378 VIXL_ASSERT(allow_macro_instructions_); 6379 SingleEmissionCheckScope guard(this); 6380 uqincd(rdn, pattern, multiplier); 6381 } 6382 void Uqincd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 6383 VIXL_ASSERT(allow_macro_instructions_); 6384 SingleEmissionCheckScope guard(this); 6385 uqincd(zdn, pattern, multiplier); 6386 } 6387 void Uqinch(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 6388 VIXL_ASSERT(allow_macro_instructions_); 6389 SingleEmissionCheckScope guard(this); 6390 uqinch(rdn, pattern, multiplier); 6391 } 6392 void Uqinch(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 6393 VIXL_ASSERT(allow_macro_instructions_); 6394 SingleEmissionCheckScope guard(this); 6395 uqinch(zdn, pattern, multiplier); 6396 } 6397 // The saturation is based on the size of `rn`. The result is zero-extended 6398 // into `rd`, which must be at least as big. 6399 void Uqincp(const Register& rd, 6400 const PRegisterWithLaneSize& pg, 6401 const Register& rn) { 6402 VIXL_ASSERT(allow_macro_instructions_); 6403 VIXL_ASSERT(rd.Aliases(rn)); 6404 VIXL_ASSERT(rd.GetSizeInBytes() >= rn.GetSizeInBytes()); 6405 SingleEmissionCheckScope guard(this); 6406 if (rn.Is64Bits()) { 6407 uqincp(rd, pg); 6408 } else { 6409 // Convert <Xd> into <Wd>, to make this more consistent with Sqincp. 6410 uqincp(rd.W(), pg); 6411 } 6412 } 6413 void Uqincp(const Register& rdn, const PRegisterWithLaneSize& pg) { 6414 Uqincp(rdn, pg, rdn); 6415 } 6416 void Uqincp(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) { 6417 VIXL_ASSERT(allow_macro_instructions_); 6418 VIXL_ASSERT(AreSameFormat(zd, zn)); 6419 // `sqincp` writes every lane, so use an unpredicated movprfx. 6420 MovprfxHelperScope guard(this, zd, zn); 6421 uqincp(zd, pg); 6422 } 6423 void Uqincp(const ZRegister& zdn, const PRegister& pg) { 6424 Uqincp(zdn, pg, zdn); 6425 } 6426 void Uqincw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) { 6427 VIXL_ASSERT(allow_macro_instructions_); 6428 SingleEmissionCheckScope guard(this); 6429 uqincw(rdn, pattern, multiplier); 6430 } 6431 void Uqincw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) { 6432 VIXL_ASSERT(allow_macro_instructions_); 6433 SingleEmissionCheckScope guard(this); 6434 uqincw(zdn, pattern, multiplier); 6435 } 6436 void Uqsub(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6437 VIXL_ASSERT(allow_macro_instructions_); 6438 SingleEmissionCheckScope guard(this); 6439 uqsub(zd, zn, zm); 6440 } 6441 void Uqsub(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm) { 6442 VIXL_ASSERT(allow_macro_instructions_); 6443 VIXL_ASSERT(imm.IsUint8() || 6444 (imm.IsUint16() && ((imm.AsUint16() & 0xff) == 0))); 6445 MovprfxHelperScope guard(this, zd, zn); 6446 uqsub(zd, zd, imm.AsUint16()); 6447 } 6448 void Uunpkhi(const ZRegister& zd, const ZRegister& zn) { 6449 VIXL_ASSERT(allow_macro_instructions_); 6450 SingleEmissionCheckScope guard(this); 6451 uunpkhi(zd, zn); 6452 } 6453 void Uunpklo(const ZRegister& zd, const ZRegister& zn) { 6454 VIXL_ASSERT(allow_macro_instructions_); 6455 SingleEmissionCheckScope guard(this); 6456 uunpklo(zd, zn); 6457 } 6458 void Uxtb(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 6459 VIXL_ASSERT(allow_macro_instructions_); 6460 SingleEmissionCheckScope guard(this); 6461 uxtb(zd, pg, zn); 6462 } 6463 void Uxth(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 6464 VIXL_ASSERT(allow_macro_instructions_); 6465 SingleEmissionCheckScope guard(this); 6466 uxth(zd, pg, zn); 6467 } 6468 void Uxtw(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 6469 VIXL_ASSERT(allow_macro_instructions_); 6470 SingleEmissionCheckScope guard(this); 6471 uxtw(zd, pg, zn); 6472 } 6473 void Uzp1(const PRegisterWithLaneSize& pd, 6474 const PRegisterWithLaneSize& pn, 6475 const PRegisterWithLaneSize& pm) { 6476 VIXL_ASSERT(allow_macro_instructions_); 6477 SingleEmissionCheckScope guard(this); 6478 uzp1(pd, pn, pm); 6479 } 6480 void Uzp1(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6481 VIXL_ASSERT(allow_macro_instructions_); 6482 SingleEmissionCheckScope guard(this); 6483 uzp1(zd, zn, zm); 6484 } 6485 void Uzp2(const PRegisterWithLaneSize& pd, 6486 const PRegisterWithLaneSize& pn, 6487 const PRegisterWithLaneSize& pm) { 6488 VIXL_ASSERT(allow_macro_instructions_); 6489 SingleEmissionCheckScope guard(this); 6490 uzp2(pd, pn, pm); 6491 } 6492 void Uzp2(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6493 VIXL_ASSERT(allow_macro_instructions_); 6494 SingleEmissionCheckScope guard(this); 6495 uzp2(zd, zn, zm); 6496 } 6497 void Whilele(const PRegisterWithLaneSize& pd, 6498 const Register& rn, 6499 const Register& rm) { 6500 VIXL_ASSERT(allow_macro_instructions_); 6501 SingleEmissionCheckScope guard(this); 6502 whilele(pd, rn, rm); 6503 } 6504 void Whilelo(const PRegisterWithLaneSize& pd, 6505 const Register& rn, 6506 const Register& rm) { 6507 VIXL_ASSERT(allow_macro_instructions_); 6508 SingleEmissionCheckScope guard(this); 6509 whilelo(pd, rn, rm); 6510 } 6511 void Whilels(const PRegisterWithLaneSize& pd, 6512 const Register& rn, 6513 const Register& rm) { 6514 VIXL_ASSERT(allow_macro_instructions_); 6515 SingleEmissionCheckScope guard(this); 6516 whilels(pd, rn, rm); 6517 } 6518 void Whilelt(const PRegisterWithLaneSize& pd, 6519 const Register& rn, 6520 const Register& rm) { 6521 VIXL_ASSERT(allow_macro_instructions_); 6522 SingleEmissionCheckScope guard(this); 6523 whilelt(pd, rn, rm); 6524 } 6525 void Wrffr(const PRegister& pn) { 6526 VIXL_ASSERT(allow_macro_instructions_); 6527 // Although this is essentially just a move, it writes every bit and so can 6528 // only support b-sized lane because other lane sizes would implicitly clear 6529 // bits in `ffr`. 6530 VIXL_ASSERT(!pn.HasLaneSize() || pn.IsLaneSizeB()); 6531 VIXL_ASSERT(pn.IsUnqualified()); 6532 SingleEmissionCheckScope guard(this); 6533 wrffr(pn.VnB()); 6534 } 6535 void Zip1(const PRegisterWithLaneSize& pd, 6536 const PRegisterWithLaneSize& pn, 6537 const PRegisterWithLaneSize& pm) { 6538 VIXL_ASSERT(allow_macro_instructions_); 6539 SingleEmissionCheckScope guard(this); 6540 zip1(pd, pn, pm); 6541 } 6542 void Zip1(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6543 VIXL_ASSERT(allow_macro_instructions_); 6544 SingleEmissionCheckScope guard(this); 6545 zip1(zd, zn, zm); 6546 } 6547 void Zip2(const PRegisterWithLaneSize& pd, 6548 const PRegisterWithLaneSize& pn, 6549 const PRegisterWithLaneSize& pm) { 6550 VIXL_ASSERT(allow_macro_instructions_); 6551 SingleEmissionCheckScope guard(this); 6552 zip2(pd, pn, pm); 6553 } 6554 void Zip2(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6555 VIXL_ASSERT(allow_macro_instructions_); 6556 SingleEmissionCheckScope guard(this); 6557 zip2(zd, zn, zm); 6558 } 6559 6560 // SVE2 6561 void Adclb(const ZRegister& zd, 6562 const ZRegister& za, 6563 const ZRegister& zn, 6564 const ZRegister& zm); 6565 void Adclt(const ZRegister& zd, 6566 const ZRegister& za, 6567 const ZRegister& zn, 6568 const ZRegister& zm); 6569 void Addhnb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6570 VIXL_ASSERT(allow_macro_instructions_); 6571 SingleEmissionCheckScope guard(this); 6572 addhnb(zd, zn, zm); 6573 } 6574 void Addhnt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6575 VIXL_ASSERT(allow_macro_instructions_); 6576 SingleEmissionCheckScope guard(this); 6577 addhnt(zd, zn, zm); 6578 } 6579 void Addp(const ZRegister& zd, 6580 const PRegisterM& pg, 6581 const ZRegister& zn, 6582 const ZRegister& zm); 6583 void Bcax(const ZRegister& zd, 6584 const ZRegister& zn, 6585 const ZRegister& zm, 6586 const ZRegister& zk); 6587 void Bdep(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6588 VIXL_ASSERT(allow_macro_instructions_); 6589 SingleEmissionCheckScope guard(this); 6590 bdep(zd, zn, zm); 6591 } 6592 void Bext(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6593 VIXL_ASSERT(allow_macro_instructions_); 6594 SingleEmissionCheckScope guard(this); 6595 bext(zd, zn, zm); 6596 } 6597 void Bgrp(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6598 VIXL_ASSERT(allow_macro_instructions_); 6599 SingleEmissionCheckScope guard(this); 6600 bgrp(zd, zn, zm); 6601 } 6602 void Bsl(const ZRegister& zd, 6603 const ZRegister& zn, 6604 const ZRegister& zm, 6605 const ZRegister& zk); 6606 void Bsl1n(const ZRegister& zd, 6607 const ZRegister& zn, 6608 const ZRegister& zm, 6609 const ZRegister& zk); 6610 void Bsl2n(const ZRegister& zd, 6611 const ZRegister& zn, 6612 const ZRegister& zm, 6613 const ZRegister& zk); 6614 void Cadd(const ZRegister& zd, 6615 const ZRegister& zn, 6616 const ZRegister& zm, 6617 int rot); 6618 void Cdot(const ZRegister& zd, 6619 const ZRegister& za, 6620 const ZRegister& zn, 6621 const ZRegister& zm, 6622 int index, 6623 int rot); 6624 void Cdot(const ZRegister& zd, 6625 const ZRegister& za, 6626 const ZRegister& zn, 6627 const ZRegister& zm, 6628 int rot); 6629 void Cmla(const ZRegister& zd, 6630 const ZRegister& za, 6631 const ZRegister& zn, 6632 const ZRegister& zm, 6633 int index, 6634 int rot); 6635 void Cmla(const ZRegister& zd, 6636 const ZRegister& za, 6637 const ZRegister& zn, 6638 const ZRegister& zm, 6639 int rot); 6640 void Eor3(const ZRegister& zd, 6641 const ZRegister& zn, 6642 const ZRegister& zm, 6643 const ZRegister& zk); 6644 void Eorbt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6645 VIXL_ASSERT(allow_macro_instructions_); 6646 SingleEmissionCheckScope guard(this); 6647 eorbt(zd, zn, zm); 6648 } 6649 void Eortb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6650 VIXL_ASSERT(allow_macro_instructions_); 6651 SingleEmissionCheckScope guard(this); 6652 eortb(zd, zn, zm); 6653 } 6654 void Faddp(const ZRegister& zd, 6655 const PRegisterM& pg, 6656 const ZRegister& zn, 6657 const ZRegister& zm); 6658 void Fcvtlt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 6659 VIXL_ASSERT(allow_macro_instructions_); 6660 SingleEmissionCheckScope guard(this); 6661 fcvtlt(zd, pg, zn); 6662 } 6663 void Fcvtnt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 6664 VIXL_ASSERT(allow_macro_instructions_); 6665 SingleEmissionCheckScope guard(this); 6666 fcvtnt(zd, pg, zn); 6667 } 6668 void Fcvtx(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) { 6669 VIXL_ASSERT(allow_macro_instructions_); 6670 VIXL_ASSERT(zn.IsLaneSizeD()); 6671 MovprfxHelperScope guard(this, zd.VnD(), pg, zd.VnD()); 6672 fcvtx(zd, pg.Merging(), zn); 6673 } 6674 void Fcvtxnt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) { 6675 VIXL_ASSERT(allow_macro_instructions_); 6676 SingleEmissionCheckScope guard(this); 6677 fcvtxnt(zd, pg, zn); 6678 } 6679 void Flogb(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) { 6680 VIXL_ASSERT(allow_macro_instructions_); 6681 MovprfxHelperScope guard(this, zd, pg, zd); 6682 flogb(zd, pg.Merging(), zn); 6683 } 6684 void Fmaxnmp(const ZRegister& zd, 6685 const PRegisterM& pg, 6686 const ZRegister& zn, 6687 const ZRegister& zm); 6688 void Fmaxp(const ZRegister& zd, 6689 const PRegisterM& pg, 6690 const ZRegister& zn, 6691 const ZRegister& zm); 6692 void Fminnmp(const ZRegister& zd, 6693 const PRegisterM& pg, 6694 const ZRegister& zn, 6695 const ZRegister& zm); 6696 void Fminp(const ZRegister& zd, 6697 const PRegisterM& pg, 6698 const ZRegister& zn, 6699 const ZRegister& zm); 6700 void Fmlalb(const ZRegister& zd, 6701 const ZRegister& za, 6702 const ZRegister& zn, 6703 const ZRegister& zm); 6704 void Fmlalt(const ZRegister& zd, 6705 const ZRegister& za, 6706 const ZRegister& zn, 6707 const ZRegister& zm); 6708 void Fmlslb(const ZRegister& zd, 6709 const ZRegister& za, 6710 const ZRegister& zn, 6711 const ZRegister& zm); 6712 void Fmlslt(const ZRegister& zd, 6713 const ZRegister& za, 6714 const ZRegister& zn, 6715 const ZRegister& zm); 6716 void Fmlalb(const ZRegister& zd, 6717 const ZRegister& za, 6718 const ZRegister& zn, 6719 const ZRegister& zm, 6720 int index); 6721 void Fmlalt(const ZRegister& zd, 6722 const ZRegister& za, 6723 const ZRegister& zn, 6724 const ZRegister& zm, 6725 int index); 6726 void Fmlslb(const ZRegister& zd, 6727 const ZRegister& za, 6728 const ZRegister& zn, 6729 const ZRegister& zm, 6730 int index); 6731 void Fmlslt(const ZRegister& zd, 6732 const ZRegister& za, 6733 const ZRegister& zn, 6734 const ZRegister& zm, 6735 int index); 6736 void Histcnt(const ZRegister& zd, 6737 const PRegisterZ& pg, 6738 const ZRegister& zn, 6739 const ZRegister& zm) { 6740 VIXL_ASSERT(allow_macro_instructions_); 6741 SingleEmissionCheckScope guard(this); 6742 histcnt(zd, pg, zn, zm); 6743 } 6744 void Histseg(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6745 VIXL_ASSERT(allow_macro_instructions_); 6746 SingleEmissionCheckScope guard(this); 6747 histseg(zd, zn, zm); 6748 } 6749 void Ldnt1sb(const ZRegister& zt, 6750 const PRegisterZ& pg, 6751 const SVEMemOperand& addr) { 6752 VIXL_ASSERT(allow_macro_instructions_); 6753 SingleEmissionCheckScope guard(this); 6754 ldnt1sb(zt, pg, addr); 6755 } 6756 void Ldnt1sh(const ZRegister& zt, 6757 const PRegisterZ& pg, 6758 const SVEMemOperand& addr) { 6759 VIXL_ASSERT(allow_macro_instructions_); 6760 SingleEmissionCheckScope guard(this); 6761 ldnt1sh(zt, pg, addr); 6762 } 6763 void Ldnt1sw(const ZRegister& zt, 6764 const PRegisterZ& pg, 6765 const SVEMemOperand& addr) { 6766 VIXL_ASSERT(allow_macro_instructions_); 6767 SingleEmissionCheckScope guard(this); 6768 ldnt1sw(zt, pg, addr); 6769 } 6770 void Match(const PRegisterWithLaneSize& pd, 6771 const PRegisterZ& pg, 6772 const ZRegister& zn, 6773 const ZRegister& zm) { 6774 VIXL_ASSERT(allow_macro_instructions_); 6775 SingleEmissionCheckScope guard(this); 6776 match(pd, pg, zn, zm); 6777 } 6778 void Mla(const ZRegister& zd, 6779 const ZRegister& za, 6780 const ZRegister& zn, 6781 const ZRegister& zm, 6782 int index); 6783 void Mls(const ZRegister& zd, 6784 const ZRegister& za, 6785 const ZRegister& zn, 6786 const ZRegister& zm, 6787 int index); 6788 void Mul(const ZRegister& zd, 6789 const ZRegister& zn, 6790 const ZRegister& zm, 6791 int index) { 6792 VIXL_ASSERT(allow_macro_instructions_); 6793 SingleEmissionCheckScope guard(this); 6794 mul(zd, zn, zm, index); 6795 } 6796 void Mul(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6797 VIXL_ASSERT(allow_macro_instructions_); 6798 SingleEmissionCheckScope guard(this); 6799 mul(zd, zn, zm); 6800 } 6801 void Nbsl(const ZRegister& zd, 6802 const ZRegister& zn, 6803 const ZRegister& zm, 6804 const ZRegister& zk); 6805 void Nmatch(const PRegisterWithLaneSize& pd, 6806 const PRegisterZ& pg, 6807 const ZRegister& zn, 6808 const ZRegister& zm) { 6809 VIXL_ASSERT(allow_macro_instructions_); 6810 SingleEmissionCheckScope guard(this); 6811 nmatch(pd, pg, zn, zm); 6812 } 6813 void Pmul(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6814 VIXL_ASSERT(allow_macro_instructions_); 6815 SingleEmissionCheckScope guard(this); 6816 pmul(zd, zn, zm); 6817 } 6818 void Pmullb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6819 VIXL_ASSERT(allow_macro_instructions_); 6820 SingleEmissionCheckScope guard(this); 6821 pmullb(zd, zn, zm); 6822 } 6823 void Pmullt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6824 VIXL_ASSERT(allow_macro_instructions_); 6825 SingleEmissionCheckScope guard(this); 6826 pmullt(zd, zn, zm); 6827 } 6828 void Raddhnb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6829 VIXL_ASSERT(allow_macro_instructions_); 6830 SingleEmissionCheckScope guard(this); 6831 raddhnb(zd, zn, zm); 6832 } 6833 void Raddhnt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6834 VIXL_ASSERT(allow_macro_instructions_); 6835 SingleEmissionCheckScope guard(this); 6836 raddhnt(zd, zn, zm); 6837 } 6838 void Rshrnb(const ZRegister& zd, const ZRegister& zn, int shift) { 6839 VIXL_ASSERT(allow_macro_instructions_); 6840 SingleEmissionCheckScope guard(this); 6841 rshrnb(zd, zn, shift); 6842 } 6843 void Rshrnt(const ZRegister& zd, const ZRegister& zn, int shift) { 6844 VIXL_ASSERT(allow_macro_instructions_); 6845 SingleEmissionCheckScope guard(this); 6846 rshrnt(zd, zn, shift); 6847 } 6848 void Rsubhnb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6849 VIXL_ASSERT(allow_macro_instructions_); 6850 SingleEmissionCheckScope guard(this); 6851 rsubhnb(zd, zn, zm); 6852 } 6853 void Rsubhnt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6854 VIXL_ASSERT(allow_macro_instructions_); 6855 SingleEmissionCheckScope guard(this); 6856 rsubhnt(zd, zn, zm); 6857 } 6858 void Saba(const ZRegister& zd, 6859 const ZRegister& za, 6860 const ZRegister& zn, 6861 const ZRegister& zm); 6862 void Sabalb(const ZRegister& zd, 6863 const ZRegister& za, 6864 const ZRegister& zn, 6865 const ZRegister& zm); 6866 void Sabalt(const ZRegister& zd, 6867 const ZRegister& za, 6868 const ZRegister& zn, 6869 const ZRegister& zm); 6870 void Sabdlb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6871 VIXL_ASSERT(allow_macro_instructions_); 6872 SingleEmissionCheckScope guard(this); 6873 sabdlb(zd, zn, zm); 6874 } 6875 void Sabdlt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6876 VIXL_ASSERT(allow_macro_instructions_); 6877 SingleEmissionCheckScope guard(this); 6878 sabdlt(zd, zn, zm); 6879 } 6880 void Sadalp(const ZRegister& zda, const PRegisterM& pg, const ZRegister& zn) { 6881 VIXL_ASSERT(allow_macro_instructions_); 6882 SingleEmissionCheckScope guard(this); 6883 sadalp(zda, pg, zn); 6884 } 6885 void Saddlb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6886 VIXL_ASSERT(allow_macro_instructions_); 6887 SingleEmissionCheckScope guard(this); 6888 saddlb(zd, zn, zm); 6889 } 6890 void Saddlbt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6891 VIXL_ASSERT(allow_macro_instructions_); 6892 SingleEmissionCheckScope guard(this); 6893 saddlbt(zd, zn, zm); 6894 } 6895 void Saddlt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6896 VIXL_ASSERT(allow_macro_instructions_); 6897 SingleEmissionCheckScope guard(this); 6898 saddlt(zd, zn, zm); 6899 } 6900 void Saddwb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6901 VIXL_ASSERT(allow_macro_instructions_); 6902 SingleEmissionCheckScope guard(this); 6903 saddwb(zd, zn, zm); 6904 } 6905 void Saddwt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6906 VIXL_ASSERT(allow_macro_instructions_); 6907 SingleEmissionCheckScope guard(this); 6908 saddwt(zd, zn, zm); 6909 } 6910 void Sbclb(const ZRegister& zd, 6911 const ZRegister& za, 6912 const ZRegister& zn, 6913 const ZRegister& zm); 6914 void Sbclt(const ZRegister& zd, 6915 const ZRegister& za, 6916 const ZRegister& zn, 6917 const ZRegister& zm); 6918 void Shrnb(const ZRegister& zd, const ZRegister& zn, int shift) { 6919 VIXL_ASSERT(allow_macro_instructions_); 6920 SingleEmissionCheckScope guard(this); 6921 shrnb(zd, zn, shift); 6922 } 6923 void Shrnt(const ZRegister& zd, const ZRegister& zn, int shift) { 6924 VIXL_ASSERT(allow_macro_instructions_); 6925 SingleEmissionCheckScope guard(this); 6926 shrnt(zd, zn, shift); 6927 } 6928 void Shsub(const ZRegister& zd, 6929 const PRegisterM& pg, 6930 const ZRegister& zn, 6931 const ZRegister& zm); 6932 void Sli(const ZRegister& zd, const ZRegister& zn, int shift) { 6933 VIXL_ASSERT(allow_macro_instructions_); 6934 SingleEmissionCheckScope guard(this); 6935 sli(zd, zn, shift); 6936 } 6937 void Smaxp(const ZRegister& zd, 6938 const PRegisterM& pg, 6939 const ZRegister& zn, 6940 const ZRegister& zm); 6941 void Sminp(const ZRegister& zd, 6942 const PRegisterM& pg, 6943 const ZRegister& zn, 6944 const ZRegister& zm); 6945 void Smlalb(const ZRegister& zd, 6946 const ZRegister& za, 6947 const ZRegister& zn, 6948 const ZRegister& zm, 6949 int index); 6950 void Smlalb(const ZRegister& zd, 6951 const ZRegister& za, 6952 const ZRegister& zn, 6953 const ZRegister& zm); 6954 void Smlalt(const ZRegister& zd, 6955 const ZRegister& za, 6956 const ZRegister& zn, 6957 const ZRegister& zm, 6958 int index); 6959 void Smlalt(const ZRegister& zd, 6960 const ZRegister& za, 6961 const ZRegister& zn, 6962 const ZRegister& zm); 6963 void Smlslb(const ZRegister& zd, 6964 const ZRegister& za, 6965 const ZRegister& zn, 6966 const ZRegister& zm, 6967 int index); 6968 void Smlslb(const ZRegister& zd, 6969 const ZRegister& za, 6970 const ZRegister& zn, 6971 const ZRegister& zm); 6972 void Smlslt(const ZRegister& zd, 6973 const ZRegister& za, 6974 const ZRegister& zn, 6975 const ZRegister& zm, 6976 int index); 6977 void Smlslt(const ZRegister& zd, 6978 const ZRegister& za, 6979 const ZRegister& zn, 6980 const ZRegister& zm); 6981 void Smulh(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6982 VIXL_ASSERT(allow_macro_instructions_); 6983 SingleEmissionCheckScope guard(this); 6984 smulh(zd, zn, zm); 6985 } 6986 void Smullb(const ZRegister& zd, 6987 const ZRegister& zn, 6988 const ZRegister& zm, 6989 int index) { 6990 VIXL_ASSERT(allow_macro_instructions_); 6991 SingleEmissionCheckScope guard(this); 6992 smullb(zd, zn, zm, index); 6993 } 6994 void Smullb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 6995 VIXL_ASSERT(allow_macro_instructions_); 6996 SingleEmissionCheckScope guard(this); 6997 smullb(zd, zn, zm); 6998 } 6999 void Smullt(const ZRegister& zd, 7000 const ZRegister& zn, 7001 const ZRegister& zm, 7002 int index) { 7003 VIXL_ASSERT(allow_macro_instructions_); 7004 SingleEmissionCheckScope guard(this); 7005 smullt(zd, zn, zm, index); 7006 } 7007 void Smullt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7008 VIXL_ASSERT(allow_macro_instructions_); 7009 SingleEmissionCheckScope guard(this); 7010 smullt(zd, zn, zm); 7011 } 7012 void Sqabs(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) { 7013 VIXL_ASSERT(allow_macro_instructions_); 7014 MovprfxHelperScope guard(this, zd, pg, zd); 7015 sqabs(zd, pg.Merging(), zn); 7016 } 7017 void Sqcadd(const ZRegister& zd, 7018 const ZRegister& zn, 7019 const ZRegister& zm, 7020 int rot); 7021 void Sqdmlalb(const ZRegister& zd, 7022 const ZRegister& za, 7023 const ZRegister& zn, 7024 const ZRegister& zm, 7025 int index); 7026 void Sqdmlalb(const ZRegister& zd, 7027 const ZRegister& za, 7028 const ZRegister& zn, 7029 const ZRegister& zm); 7030 void Sqdmlalbt(const ZRegister& zd, 7031 const ZRegister& za, 7032 const ZRegister& zn, 7033 const ZRegister& zm); 7034 void Sqdmlalt(const ZRegister& zd, 7035 const ZRegister& za, 7036 const ZRegister& zn, 7037 const ZRegister& zm, 7038 int index); 7039 void Sqdmlalt(const ZRegister& zd, 7040 const ZRegister& za, 7041 const ZRegister& zn, 7042 const ZRegister& zm); 7043 void Sqdmlslb(const ZRegister& zd, 7044 const ZRegister& za, 7045 const ZRegister& zn, 7046 const ZRegister& zm, 7047 int index); 7048 void Sqdmlslb(const ZRegister& zd, 7049 const ZRegister& za, 7050 const ZRegister& zn, 7051 const ZRegister& zm); 7052 void Sqdmlslbt(const ZRegister& zd, 7053 const ZRegister& za, 7054 const ZRegister& zn, 7055 const ZRegister& zm); 7056 void Sqdmlslt(const ZRegister& zd, 7057 const ZRegister& za, 7058 const ZRegister& zn, 7059 const ZRegister& zm, 7060 int index); 7061 void Sqdmlslt(const ZRegister& zd, 7062 const ZRegister& za, 7063 const ZRegister& zn, 7064 const ZRegister& zm); 7065 void Sqdmulh(const ZRegister& zd, 7066 const ZRegister& zn, 7067 const ZRegister& zm, 7068 int index) { 7069 VIXL_ASSERT(allow_macro_instructions_); 7070 SingleEmissionCheckScope guard(this); 7071 sqdmulh(zd, zn, zm, index); 7072 } 7073 void Sqdmulh(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7074 VIXL_ASSERT(allow_macro_instructions_); 7075 SingleEmissionCheckScope guard(this); 7076 sqdmulh(zd, zn, zm); 7077 } 7078 void Sqdmullb(const ZRegister& zd, 7079 const ZRegister& zn, 7080 const ZRegister& zm, 7081 int index) { 7082 VIXL_ASSERT(allow_macro_instructions_); 7083 SingleEmissionCheckScope guard(this); 7084 sqdmullb(zd, zn, zm, index); 7085 } 7086 void Sqdmullb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7087 VIXL_ASSERT(allow_macro_instructions_); 7088 SingleEmissionCheckScope guard(this); 7089 sqdmullb(zd, zn, zm); 7090 } 7091 void Sqdmullt(const ZRegister& zd, 7092 const ZRegister& zn, 7093 const ZRegister& zm, 7094 int index) { 7095 VIXL_ASSERT(allow_macro_instructions_); 7096 SingleEmissionCheckScope guard(this); 7097 sqdmullt(zd, zn, zm, index); 7098 } 7099 void Sqdmullt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7100 VIXL_ASSERT(allow_macro_instructions_); 7101 SingleEmissionCheckScope guard(this); 7102 sqdmullt(zd, zn, zm); 7103 } 7104 void Sqneg(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) { 7105 VIXL_ASSERT(allow_macro_instructions_); 7106 MovprfxHelperScope guard(this, zd, pg, zd); 7107 sqneg(zd, pg.Merging(), zn); 7108 } 7109 void Sqrdcmlah(const ZRegister& zd, 7110 const ZRegister& za, 7111 const ZRegister& zn, 7112 const ZRegister& zm, 7113 int index, 7114 int rot); 7115 void Sqrdcmlah(const ZRegister& zd, 7116 const ZRegister& za, 7117 const ZRegister& zn, 7118 const ZRegister& zm, 7119 int rot); 7120 void Sqrdmlah(const ZRegister& zd, 7121 const ZRegister& za, 7122 const ZRegister& zn, 7123 const ZRegister& zm); 7124 void Sqrdmlah(const ZRegister& zd, 7125 const ZRegister& za, 7126 const ZRegister& zn, 7127 const ZRegister& zm, 7128 int index); 7129 void Sqrdmlsh(const ZRegister& zd, 7130 const ZRegister& za, 7131 const ZRegister& zn, 7132 const ZRegister& zm); 7133 void Sqrdmlsh(const ZRegister& zd, 7134 const ZRegister& za, 7135 const ZRegister& zn, 7136 const ZRegister& zm, 7137 int index); 7138 void Sqrdmulh(const ZRegister& zd, 7139 const ZRegister& zn, 7140 const ZRegister& zm, 7141 int index) { 7142 VIXL_ASSERT(allow_macro_instructions_); 7143 SingleEmissionCheckScope guard(this); 7144 sqrdmulh(zd, zn, zm, index); 7145 } 7146 void Sqrdmulh(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7147 VIXL_ASSERT(allow_macro_instructions_); 7148 SingleEmissionCheckScope guard(this); 7149 sqrdmulh(zd, zn, zm); 7150 } 7151 void Sqrshl(const ZRegister& zd, 7152 const PRegisterM& pg, 7153 const ZRegister& zn, 7154 const ZRegister& zm); 7155 void Sqrshrnb(const ZRegister& zd, const ZRegister& zn, int shift) { 7156 VIXL_ASSERT(allow_macro_instructions_); 7157 SingleEmissionCheckScope guard(this); 7158 sqrshrnb(zd, zn, shift); 7159 } 7160 void Sqrshrnt(const ZRegister& zd, const ZRegister& zn, int shift) { 7161 VIXL_ASSERT(allow_macro_instructions_); 7162 SingleEmissionCheckScope guard(this); 7163 sqrshrnt(zd, zn, shift); 7164 } 7165 void Sqrshrunb(const ZRegister& zd, const ZRegister& zn, int shift) { 7166 VIXL_ASSERT(allow_macro_instructions_); 7167 SingleEmissionCheckScope guard(this); 7168 sqrshrunb(zd, zn, shift); 7169 } 7170 void Sqrshrunt(const ZRegister& zd, const ZRegister& zn, int shift) { 7171 VIXL_ASSERT(allow_macro_instructions_); 7172 SingleEmissionCheckScope guard(this); 7173 sqrshrunt(zd, zn, shift); 7174 } 7175 void Sqshl(const ZRegister& zd, 7176 const PRegisterM& pg, 7177 const ZRegister& zn, 7178 int shift) { 7179 VIXL_ASSERT(allow_macro_instructions_); 7180 MovprfxHelperScope guard(this, zd, pg, zn); 7181 sqshl(zd, pg, zd, shift); 7182 } 7183 void Sqshl(const ZRegister& zd, 7184 const PRegisterM& pg, 7185 const ZRegister& zn, 7186 const ZRegister& zm); 7187 void Sqshlu(const ZRegister& zd, 7188 const PRegisterM& pg, 7189 const ZRegister& zn, 7190 int shift) { 7191 VIXL_ASSERT(allow_macro_instructions_); 7192 MovprfxHelperScope guard(this, zd, pg, zn); 7193 sqshlu(zd, pg, zd, shift); 7194 } 7195 void Sqshrnb(const ZRegister& zd, const ZRegister& zn, int shift) { 7196 VIXL_ASSERT(allow_macro_instructions_); 7197 SingleEmissionCheckScope guard(this); 7198 sqshrnb(zd, zn, shift); 7199 } 7200 void Sqshrnt(const ZRegister& zd, const ZRegister& zn, int shift) { 7201 VIXL_ASSERT(allow_macro_instructions_); 7202 SingleEmissionCheckScope guard(this); 7203 sqshrnt(zd, zn, shift); 7204 } 7205 void Sqshrunb(const ZRegister& zd, const ZRegister& zn, int shift) { 7206 VIXL_ASSERT(allow_macro_instructions_); 7207 SingleEmissionCheckScope guard(this); 7208 sqshrunb(zd, zn, shift); 7209 } 7210 void Sqshrunt(const ZRegister& zd, const ZRegister& zn, int shift) { 7211 VIXL_ASSERT(allow_macro_instructions_); 7212 SingleEmissionCheckScope guard(this); 7213 sqshrunt(zd, zn, shift); 7214 } 7215 void Sqsub(const ZRegister& zd, 7216 const PRegisterM& pg, 7217 const ZRegister& zn, 7218 const ZRegister& zm); 7219 void Sqxtnb(const ZRegister& zd, const ZRegister& zn) { 7220 VIXL_ASSERT(allow_macro_instructions_); 7221 SingleEmissionCheckScope guard(this); 7222 sqxtnb(zd, zn); 7223 } 7224 void Sqxtnt(const ZRegister& zd, const ZRegister& zn) { 7225 VIXL_ASSERT(allow_macro_instructions_); 7226 SingleEmissionCheckScope guard(this); 7227 sqxtnt(zd, zn); 7228 } 7229 void Sqxtunb(const ZRegister& zd, const ZRegister& zn) { 7230 VIXL_ASSERT(allow_macro_instructions_); 7231 SingleEmissionCheckScope guard(this); 7232 sqxtunb(zd, zn); 7233 } 7234 void Sqxtunt(const ZRegister& zd, const ZRegister& zn) { 7235 VIXL_ASSERT(allow_macro_instructions_); 7236 SingleEmissionCheckScope guard(this); 7237 sqxtunt(zd, zn); 7238 } 7239 void Sri(const ZRegister& zd, const ZRegister& zn, int shift) { 7240 VIXL_ASSERT(allow_macro_instructions_); 7241 SingleEmissionCheckScope guard(this); 7242 sri(zd, zn, shift); 7243 } 7244 void Srshl(const ZRegister& zd, 7245 const PRegisterM& pg, 7246 const ZRegister& zn, 7247 const ZRegister& zm); 7248 void Srshr(const ZRegister& zd, 7249 const PRegisterM& pg, 7250 const ZRegister& zn, 7251 int shift) { 7252 VIXL_ASSERT(allow_macro_instructions_); 7253 MovprfxHelperScope guard(this, zd, pg, zn); 7254 srshr(zd, pg, zd, shift); 7255 } 7256 void Srsra(const ZRegister& zd, 7257 const ZRegister& za, 7258 const ZRegister& zn, 7259 int shift); 7260 void Sshllb(const ZRegister& zd, const ZRegister& zn, int shift) { 7261 VIXL_ASSERT(allow_macro_instructions_); 7262 SingleEmissionCheckScope guard(this); 7263 sshllb(zd, zn, shift); 7264 } 7265 void Sshllt(const ZRegister& zd, const ZRegister& zn, int shift) { 7266 VIXL_ASSERT(allow_macro_instructions_); 7267 SingleEmissionCheckScope guard(this); 7268 sshllt(zd, zn, shift); 7269 } 7270 void Ssra(const ZRegister& zd, 7271 const ZRegister& za, 7272 const ZRegister& zn, 7273 int shift); 7274 void Ssublb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7275 VIXL_ASSERT(allow_macro_instructions_); 7276 SingleEmissionCheckScope guard(this); 7277 ssublb(zd, zn, zm); 7278 } 7279 void Ssublbt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7280 VIXL_ASSERT(allow_macro_instructions_); 7281 SingleEmissionCheckScope guard(this); 7282 ssublbt(zd, zn, zm); 7283 } 7284 void Ssublt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7285 VIXL_ASSERT(allow_macro_instructions_); 7286 SingleEmissionCheckScope guard(this); 7287 ssublt(zd, zn, zm); 7288 } 7289 void Ssubltb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7290 VIXL_ASSERT(allow_macro_instructions_); 7291 SingleEmissionCheckScope guard(this); 7292 ssubltb(zd, zn, zm); 7293 } 7294 void Ssubwb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7295 VIXL_ASSERT(allow_macro_instructions_); 7296 SingleEmissionCheckScope guard(this); 7297 ssubwb(zd, zn, zm); 7298 } 7299 void Ssubwt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7300 VIXL_ASSERT(allow_macro_instructions_); 7301 SingleEmissionCheckScope guard(this); 7302 ssubwt(zd, zn, zm); 7303 } 7304 void Subhnb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7305 VIXL_ASSERT(allow_macro_instructions_); 7306 SingleEmissionCheckScope guard(this); 7307 subhnb(zd, zn, zm); 7308 } 7309 void Subhnt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7310 VIXL_ASSERT(allow_macro_instructions_); 7311 SingleEmissionCheckScope guard(this); 7312 subhnt(zd, zn, zm); 7313 } 7314 void Suqadd(const ZRegister& zd, 7315 const PRegisterM& pg, 7316 const ZRegister& zn, 7317 const ZRegister& zm); 7318 void Tbl(const ZRegister& zd, 7319 const ZRegister& zn1, 7320 const ZRegister& zn2, 7321 const ZRegister& zm) { 7322 VIXL_ASSERT(allow_macro_instructions_); 7323 SingleEmissionCheckScope guard(this); 7324 tbl(zd, zn1, zn2, zm); 7325 } 7326 void Tbx(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7327 VIXL_ASSERT(allow_macro_instructions_); 7328 SingleEmissionCheckScope guard(this); 7329 tbx(zd, zn, zm); 7330 } 7331 void Uaba(const ZRegister& zd, 7332 const ZRegister& za, 7333 const ZRegister& zn, 7334 const ZRegister& zm); 7335 void Uabalb(const ZRegister& zd, 7336 const ZRegister& za, 7337 const ZRegister& zn, 7338 const ZRegister& zm); 7339 void Uabalt(const ZRegister& zd, 7340 const ZRegister& za, 7341 const ZRegister& zn, 7342 const ZRegister& zm); 7343 void Uabdlb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7344 VIXL_ASSERT(allow_macro_instructions_); 7345 SingleEmissionCheckScope guard(this); 7346 uabdlb(zd, zn, zm); 7347 } 7348 void Uabdlt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7349 VIXL_ASSERT(allow_macro_instructions_); 7350 SingleEmissionCheckScope guard(this); 7351 uabdlt(zd, zn, zm); 7352 } 7353 void Uadalp(const ZRegister& zda, const PRegisterM& pg, const ZRegister& zn) { 7354 VIXL_ASSERT(allow_macro_instructions_); 7355 SingleEmissionCheckScope guard(this); 7356 uadalp(zda, pg, zn); 7357 } 7358 void Uaddlb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7359 VIXL_ASSERT(allow_macro_instructions_); 7360 SingleEmissionCheckScope guard(this); 7361 uaddlb(zd, zn, zm); 7362 } 7363 void Uaddlt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7364 VIXL_ASSERT(allow_macro_instructions_); 7365 SingleEmissionCheckScope guard(this); 7366 uaddlt(zd, zn, zm); 7367 } 7368 void Uaddwb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7369 VIXL_ASSERT(allow_macro_instructions_); 7370 SingleEmissionCheckScope guard(this); 7371 uaddwb(zd, zn, zm); 7372 } 7373 void Uaddwt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7374 VIXL_ASSERT(allow_macro_instructions_); 7375 SingleEmissionCheckScope guard(this); 7376 uaddwt(zd, zn, zm); 7377 } 7378 void Uhsub(const ZRegister& zd, 7379 const PRegisterM& pg, 7380 const ZRegister& zn, 7381 const ZRegister& zm); 7382 void Umaxp(const ZRegister& zd, 7383 const PRegisterM& pg, 7384 const ZRegister& zn, 7385 const ZRegister& zm); 7386 void Uminp(const ZRegister& zd, 7387 const PRegisterM& pg, 7388 const ZRegister& zn, 7389 const ZRegister& zm); 7390 void Umlalb(const ZRegister& zd, 7391 const ZRegister& za, 7392 const ZRegister& zn, 7393 const ZRegister& zm, 7394 int index); 7395 void Umlalb(const ZRegister& zd, 7396 const ZRegister& za, 7397 const ZRegister& zn, 7398 const ZRegister& zm); 7399 void Umlalt(const ZRegister& zd, 7400 const ZRegister& za, 7401 const ZRegister& zn, 7402 const ZRegister& zm, 7403 int index); 7404 void Umlalt(const ZRegister& zd, 7405 const ZRegister& za, 7406 const ZRegister& zn, 7407 const ZRegister& zm); 7408 void Umlslb(const ZRegister& zd, 7409 const ZRegister& za, 7410 const ZRegister& zn, 7411 const ZRegister& zm, 7412 int index); 7413 void Umlslb(const ZRegister& zd, 7414 const ZRegister& za, 7415 const ZRegister& zn, 7416 const ZRegister& zm); 7417 void Umlslt(const ZRegister& zd, 7418 const ZRegister& za, 7419 const ZRegister& zn, 7420 const ZRegister& zm, 7421 int index); 7422 void Umlslt(const ZRegister& zd, 7423 const ZRegister& za, 7424 const ZRegister& zn, 7425 const ZRegister& zm); 7426 void Umulh(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7427 VIXL_ASSERT(allow_macro_instructions_); 7428 SingleEmissionCheckScope guard(this); 7429 umulh(zd, zn, zm); 7430 } 7431 void Umullb(const ZRegister& zd, 7432 const ZRegister& zn, 7433 const ZRegister& zm, 7434 int index) { 7435 VIXL_ASSERT(allow_macro_instructions_); 7436 SingleEmissionCheckScope guard(this); 7437 umullb(zd, zn, zm, index); 7438 } 7439 void Umullb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7440 VIXL_ASSERT(allow_macro_instructions_); 7441 SingleEmissionCheckScope guard(this); 7442 umullb(zd, zn, zm); 7443 } 7444 void Umullt(const ZRegister& zd, 7445 const ZRegister& zn, 7446 const ZRegister& zm, 7447 int index) { 7448 VIXL_ASSERT(allow_macro_instructions_); 7449 SingleEmissionCheckScope guard(this); 7450 umullt(zd, zn, zm, index); 7451 } 7452 void Umullt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7453 VIXL_ASSERT(allow_macro_instructions_); 7454 SingleEmissionCheckScope guard(this); 7455 umullt(zd, zn, zm); 7456 } 7457 void Uqrshl(const ZRegister& zd, 7458 const PRegisterM& pg, 7459 const ZRegister& zn, 7460 const ZRegister& zm); 7461 void Uqrshrnb(const ZRegister& zd, const ZRegister& zn, int shift) { 7462 VIXL_ASSERT(allow_macro_instructions_); 7463 SingleEmissionCheckScope guard(this); 7464 uqrshrnb(zd, zn, shift); 7465 } 7466 void Uqrshrnt(const ZRegister& zd, const ZRegister& zn, int shift) { 7467 VIXL_ASSERT(allow_macro_instructions_); 7468 SingleEmissionCheckScope guard(this); 7469 uqrshrnt(zd, zn, shift); 7470 } 7471 void Uqshl(const ZRegister& zd, 7472 const PRegisterM& pg, 7473 const ZRegister& zn, 7474 int shift) { 7475 VIXL_ASSERT(allow_macro_instructions_); 7476 MovprfxHelperScope guard(this, zd, pg, zn); 7477 uqshl(zd, pg, zd, shift); 7478 } 7479 void Uqshl(const ZRegister& zd, 7480 const PRegisterM& pg, 7481 const ZRegister& zn, 7482 const ZRegister& zm); 7483 void Uqshrnb(const ZRegister& zd, const ZRegister& zn, int shift) { 7484 VIXL_ASSERT(allow_macro_instructions_); 7485 SingleEmissionCheckScope guard(this); 7486 uqshrnb(zd, zn, shift); 7487 } 7488 void Uqshrnt(const ZRegister& zd, const ZRegister& zn, int shift) { 7489 VIXL_ASSERT(allow_macro_instructions_); 7490 SingleEmissionCheckScope guard(this); 7491 uqshrnt(zd, zn, shift); 7492 } 7493 void Uqsub(const ZRegister& zd, 7494 const PRegisterM& pg, 7495 const ZRegister& zn, 7496 const ZRegister& zm); 7497 void Uqxtnb(const ZRegister& zd, const ZRegister& zn) { 7498 VIXL_ASSERT(allow_macro_instructions_); 7499 SingleEmissionCheckScope guard(this); 7500 uqxtnb(zd, zn); 7501 } 7502 void Uqxtnt(const ZRegister& zd, const ZRegister& zn) { 7503 VIXL_ASSERT(allow_macro_instructions_); 7504 SingleEmissionCheckScope guard(this); 7505 uqxtnt(zd, zn); 7506 } 7507 void Urecpe(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) { 7508 VIXL_ASSERT(allow_macro_instructions_); 7509 MovprfxHelperScope guard(this, zd, pg, zd); 7510 urecpe(zd, pg.Merging(), zn); 7511 } 7512 void Urshl(const ZRegister& zd, 7513 const PRegisterM& pg, 7514 const ZRegister& zn, 7515 const ZRegister& zm); 7516 void Urshr(const ZRegister& zd, 7517 const PRegisterM& pg, 7518 const ZRegister& zn, 7519 int shift) { 7520 VIXL_ASSERT(allow_macro_instructions_); 7521 MovprfxHelperScope guard(this, zd, pg, zn); 7522 urshr(zd, pg, zd, shift); 7523 } 7524 void Ursqrte(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) { 7525 VIXL_ASSERT(allow_macro_instructions_); 7526 MovprfxHelperScope guard(this, zd, pg, zd); 7527 ursqrte(zd, pg.Merging(), zn); 7528 } 7529 void Ursra(const ZRegister& zd, 7530 const ZRegister& za, 7531 const ZRegister& zn, 7532 int shift); 7533 void Ushllb(const ZRegister& zd, const ZRegister& zn, int shift) { 7534 VIXL_ASSERT(allow_macro_instructions_); 7535 SingleEmissionCheckScope guard(this); 7536 ushllb(zd, zn, shift); 7537 } 7538 void Ushllt(const ZRegister& zd, const ZRegister& zn, int shift) { 7539 VIXL_ASSERT(allow_macro_instructions_); 7540 SingleEmissionCheckScope guard(this); 7541 ushllt(zd, zn, shift); 7542 } 7543 void Usqadd(const ZRegister& zd, 7544 const PRegisterM& pg, 7545 const ZRegister& zn, 7546 const ZRegister& zm); 7547 void Usra(const ZRegister& zd, 7548 const ZRegister& za, 7549 const ZRegister& zn, 7550 int shift); 7551 void Usublb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7552 VIXL_ASSERT(allow_macro_instructions_); 7553 SingleEmissionCheckScope guard(this); 7554 usublb(zd, zn, zm); 7555 } 7556 void Usublt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7557 VIXL_ASSERT(allow_macro_instructions_); 7558 SingleEmissionCheckScope guard(this); 7559 usublt(zd, zn, zm); 7560 } 7561 void Usubwb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7562 VIXL_ASSERT(allow_macro_instructions_); 7563 SingleEmissionCheckScope guard(this); 7564 usubwb(zd, zn, zm); 7565 } 7566 void Usubwt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) { 7567 VIXL_ASSERT(allow_macro_instructions_); 7568 SingleEmissionCheckScope guard(this); 7569 usubwt(zd, zn, zm); 7570 } 7571 void Whilege(const PRegisterWithLaneSize& pd, 7572 const Register& rn, 7573 const Register& rm) { 7574 VIXL_ASSERT(allow_macro_instructions_); 7575 SingleEmissionCheckScope guard(this); 7576 whilege(pd, rn, rm); 7577 } 7578 void Whilegt(const PRegisterWithLaneSize& pd, 7579 const Register& rn, 7580 const Register& rm) { 7581 VIXL_ASSERT(allow_macro_instructions_); 7582 SingleEmissionCheckScope guard(this); 7583 whilegt(pd, rn, rm); 7584 } 7585 void Whilehi(const PRegisterWithLaneSize& pd, 7586 const Register& rn, 7587 const Register& rm) { 7588 VIXL_ASSERT(allow_macro_instructions_); 7589 SingleEmissionCheckScope guard(this); 7590 whilehi(pd, rn, rm); 7591 } 7592 void Whilehs(const PRegisterWithLaneSize& pd, 7593 const Register& rn, 7594 const Register& rm) { 7595 VIXL_ASSERT(allow_macro_instructions_); 7596 SingleEmissionCheckScope guard(this); 7597 whilehs(pd, rn, rm); 7598 } 7599 void Whilerw(const PRegisterWithLaneSize& pd, 7600 const Register& rn, 7601 const Register& rm) { 7602 VIXL_ASSERT(allow_macro_instructions_); 7603 SingleEmissionCheckScope guard(this); 7604 whilerw(pd, rn, rm); 7605 } 7606 void Whilewr(const PRegisterWithLaneSize& pd, 7607 const Register& rn, 7608 const Register& rm) { 7609 VIXL_ASSERT(allow_macro_instructions_); 7610 SingleEmissionCheckScope guard(this); 7611 whilewr(pd, rn, rm); 7612 } 7613 void Xar(const ZRegister& zd, 7614 const ZRegister& zn, 7615 const ZRegister& zm, 7616 int shift) { 7617 VIXL_ASSERT(allow_macro_instructions_); 7618 if (zd.Aliases(zm)) { 7619 SingleEmissionCheckScope guard(this); 7620 xar(zd, zm, zn, shift); 7621 } else { 7622 MovprfxHelperScope guard(this, zd, zn); 7623 xar(zd, zd, zm, shift); 7624 } 7625 } 7626 void Fmmla(const ZRegister& zd, 7627 const ZRegister& za, 7628 const ZRegister& zn, 7629 const ZRegister& zm); 7630 void Smmla(const ZRegister& zd, 7631 const ZRegister& za, 7632 const ZRegister& zn, 7633 const ZRegister& zm); 7634 void Ummla(const ZRegister& zd, 7635 const ZRegister& za, 7636 const ZRegister& zn, 7637 const ZRegister& zm); 7638 void Usmmla(const ZRegister& zd, 7639 const ZRegister& za, 7640 const ZRegister& zn, 7641 const ZRegister& zm); 7642 void Usdot(const ZRegister& zd, 7643 const ZRegister& za, 7644 const ZRegister& zn, 7645 const ZRegister& zm); 7646 void Usdot(const ZRegister& zd, 7647 const ZRegister& za, 7648 const ZRegister& zn, 7649 const ZRegister& zm, 7650 int index); 7651 void Sudot(const ZRegister& zd, 7652 const ZRegister& za, 7653 const ZRegister& zn, 7654 const ZRegister& zm, 7655 int index); 7656 7657 // MTE 7658 void St2g(const Register& rt, const MemOperand& addr); 7659 void Stg(const Register& rt, const MemOperand& addr); 7660 void Stgp(const Register& rt1, const Register& rt2, const MemOperand& addr); 7661 void Stz2g(const Register& rt, const MemOperand& addr); 7662 void Stzg(const Register& rt, const MemOperand& addr); 7663 void Ldg(const Register& rt, const MemOperand& addr); 7664 7665 void Cpye(const Register& rd, const Register& rs, const Register& rn) { 7666 VIXL_ASSERT(allow_macro_instructions_); 7667 SingleEmissionCheckScope guard(this); 7668 cpye(rd, rs, rn); 7669 } 7670 7671 void Cpyen(const Register& rd, const Register& rs, const Register& rn) { 7672 VIXL_ASSERT(allow_macro_instructions_); 7673 SingleEmissionCheckScope guard(this); 7674 cpyen(rd, rs, rn); 7675 } 7676 7677 void Cpyern(const Register& rd, const Register& rs, const Register& rn) { 7678 VIXL_ASSERT(allow_macro_instructions_); 7679 SingleEmissionCheckScope guard(this); 7680 cpyern(rd, rs, rn); 7681 } 7682 7683 void Cpyewn(const Register& rd, const Register& rs, const Register& rn) { 7684 VIXL_ASSERT(allow_macro_instructions_); 7685 SingleEmissionCheckScope guard(this); 7686 cpyewn(rd, rs, rn); 7687 } 7688 7689 void Cpyfe(const Register& rd, const Register& rs, const Register& rn) { 7690 VIXL_ASSERT(allow_macro_instructions_); 7691 SingleEmissionCheckScope guard(this); 7692 cpyfe(rd, rs, rn); 7693 } 7694 7695 void Cpyfen(const Register& rd, const Register& rs, const Register& rn) { 7696 VIXL_ASSERT(allow_macro_instructions_); 7697 SingleEmissionCheckScope guard(this); 7698 cpyfen(rd, rs, rn); 7699 } 7700 7701 void Cpyfern(const Register& rd, const Register& rs, const Register& rn) { 7702 VIXL_ASSERT(allow_macro_instructions_); 7703 SingleEmissionCheckScope guard(this); 7704 cpyfern(rd, rs, rn); 7705 } 7706 7707 void Cpyfewn(const Register& rd, const Register& rs, const Register& rn) { 7708 VIXL_ASSERT(allow_macro_instructions_); 7709 SingleEmissionCheckScope guard(this); 7710 cpyfewn(rd, rs, rn); 7711 } 7712 7713 void Cpyfm(const Register& rd, const Register& rs, const Register& rn) { 7714 VIXL_ASSERT(allow_macro_instructions_); 7715 SingleEmissionCheckScope guard(this); 7716 cpyfm(rd, rs, rn); 7717 } 7718 7719 void Cpyfmn(const Register& rd, const Register& rs, const Register& rn) { 7720 VIXL_ASSERT(allow_macro_instructions_); 7721 SingleEmissionCheckScope guard(this); 7722 cpyfmn(rd, rs, rn); 7723 } 7724 7725 void Cpyfmrn(const Register& rd, const Register& rs, const Register& rn) { 7726 VIXL_ASSERT(allow_macro_instructions_); 7727 SingleEmissionCheckScope guard(this); 7728 cpyfmrn(rd, rs, rn); 7729 } 7730 7731 void Cpyfmwn(const Register& rd, const Register& rs, const Register& rn) { 7732 VIXL_ASSERT(allow_macro_instructions_); 7733 SingleEmissionCheckScope guard(this); 7734 cpyfmwn(rd, rs, rn); 7735 } 7736 7737 void Cpyfp(const Register& rd, const Register& rs, const Register& rn) { 7738 VIXL_ASSERT(allow_macro_instructions_); 7739 SingleEmissionCheckScope guard(this); 7740 cpyfp(rd, rs, rn); 7741 } 7742 7743 void Cpyfpn(const Register& rd, const Register& rs, const Register& rn) { 7744 VIXL_ASSERT(allow_macro_instructions_); 7745 SingleEmissionCheckScope guard(this); 7746 cpyfpn(rd, rs, rn); 7747 } 7748 7749 void Cpyfprn(const Register& rd, const Register& rs, const Register& rn) { 7750 VIXL_ASSERT(allow_macro_instructions_); 7751 SingleEmissionCheckScope guard(this); 7752 cpyfprn(rd, rs, rn); 7753 } 7754 7755 void Cpyfpwn(const Register& rd, const Register& rs, const Register& rn) { 7756 VIXL_ASSERT(allow_macro_instructions_); 7757 SingleEmissionCheckScope guard(this); 7758 cpyfpwn(rd, rs, rn); 7759 } 7760 7761 void Cpym(const Register& rd, const Register& rs, const Register& rn) { 7762 VIXL_ASSERT(allow_macro_instructions_); 7763 SingleEmissionCheckScope guard(this); 7764 cpym(rd, rs, rn); 7765 } 7766 7767 void Cpymn(const Register& rd, const Register& rs, const Register& rn) { 7768 VIXL_ASSERT(allow_macro_instructions_); 7769 SingleEmissionCheckScope guard(this); 7770 cpymn(rd, rs, rn); 7771 } 7772 7773 void Cpymrn(const Register& rd, const Register& rs, const Register& rn) { 7774 VIXL_ASSERT(allow_macro_instructions_); 7775 SingleEmissionCheckScope guard(this); 7776 cpymrn(rd, rs, rn); 7777 } 7778 7779 void Cpymwn(const Register& rd, const Register& rs, const Register& rn) { 7780 VIXL_ASSERT(allow_macro_instructions_); 7781 SingleEmissionCheckScope guard(this); 7782 cpymwn(rd, rs, rn); 7783 } 7784 7785 void Cpyp(const Register& rd, const Register& rs, const Register& rn) { 7786 VIXL_ASSERT(allow_macro_instructions_); 7787 SingleEmissionCheckScope guard(this); 7788 cpyp(rd, rs, rn); 7789 } 7790 7791 void Cpypn(const Register& rd, const Register& rs, const Register& rn) { 7792 VIXL_ASSERT(allow_macro_instructions_); 7793 SingleEmissionCheckScope guard(this); 7794 cpypn(rd, rs, rn); 7795 } 7796 7797 void Cpyprn(const Register& rd, const Register& rs, const Register& rn) { 7798 VIXL_ASSERT(allow_macro_instructions_); 7799 SingleEmissionCheckScope guard(this); 7800 cpyprn(rd, rs, rn); 7801 } 7802 7803 void Cpypwn(const Register& rd, const Register& rs, const Register& rn) { 7804 VIXL_ASSERT(allow_macro_instructions_); 7805 SingleEmissionCheckScope guard(this); 7806 cpypwn(rd, rs, rn); 7807 } 7808 7809 void Sete(const Register& rd, const Register& rn, const Register& rs) { 7810 VIXL_ASSERT(allow_macro_instructions_); 7811 SingleEmissionCheckScope guard(this); 7812 sete(rd, rn, rs); 7813 } 7814 7815 void Seten(const Register& rd, const Register& rn, const Register& rs) { 7816 VIXL_ASSERT(allow_macro_instructions_); 7817 SingleEmissionCheckScope guard(this); 7818 seten(rd, rn, rs); 7819 } 7820 7821 void Setge(const Register& rd, const Register& rn, const Register& rs) { 7822 VIXL_ASSERT(allow_macro_instructions_); 7823 SingleEmissionCheckScope guard(this); 7824 setge(rd, rn, rs); 7825 } 7826 7827 void Setgen(const Register& rd, const Register& rn, const Register& rs) { 7828 VIXL_ASSERT(allow_macro_instructions_); 7829 SingleEmissionCheckScope guard(this); 7830 setgen(rd, rn, rs); 7831 } 7832 7833 void Setgm(const Register& rd, const Register& rn, const Register& rs) { 7834 VIXL_ASSERT(allow_macro_instructions_); 7835 SingleEmissionCheckScope guard(this); 7836 setgm(rd, rn, rs); 7837 } 7838 7839 void Setgmn(const Register& rd, const Register& rn, const Register& rs) { 7840 VIXL_ASSERT(allow_macro_instructions_); 7841 SingleEmissionCheckScope guard(this); 7842 setgmn(rd, rn, rs); 7843 } 7844 7845 void Setgp(const Register& rd, const Register& rn, const Register& rs) { 7846 VIXL_ASSERT(allow_macro_instructions_); 7847 SingleEmissionCheckScope guard(this); 7848 setgp(rd, rn, rs); 7849 } 7850 7851 void Setgpn(const Register& rd, const Register& rn, const Register& rs) { 7852 VIXL_ASSERT(allow_macro_instructions_); 7853 SingleEmissionCheckScope guard(this); 7854 setgpn(rd, rn, rs); 7855 } 7856 7857 void Setm(const Register& rd, const Register& rn, const Register& rs) { 7858 VIXL_ASSERT(allow_macro_instructions_); 7859 SingleEmissionCheckScope guard(this); 7860 setm(rd, rn, rs); 7861 } 7862 7863 void Setmn(const Register& rd, const Register& rn, const Register& rs) { 7864 VIXL_ASSERT(allow_macro_instructions_); 7865 SingleEmissionCheckScope guard(this); 7866 setmn(rd, rn, rs); 7867 } 7868 7869 void Setp(const Register& rd, const Register& rn, const Register& rs) { 7870 VIXL_ASSERT(allow_macro_instructions_); 7871 SingleEmissionCheckScope guard(this); 7872 setp(rd, rn, rs); 7873 } 7874 7875 void Setpn(const Register& rd, const Register& rn, const Register& rs) { 7876 VIXL_ASSERT(allow_macro_instructions_); 7877 SingleEmissionCheckScope guard(this); 7878 setpn(rd, rn, rs); 7879 } 7880 7881// Macro assembler wrappers that package the MOPS instructions into a single 7882// call. 7883#define MOPS_LIST(V) \ 7884 V(Set, set, ) \ 7885 V(Setn, set, n) \ 7886 V(Setg, setg, ) \ 7887 V(Setgn, setg, n) \ 7888 V(Cpy, cpy, ) \ 7889 V(Cpyn, cpy, n) \ 7890 V(Cpyrn, cpy, rn) \ 7891 V(Cpywn, cpy, wn) \ 7892 V(Cpyf, cpyf, ) \ 7893 V(Cpyfn, cpyf, n) \ 7894 V(Cpyfrn, cpyf, rn) \ 7895 V(Cpyfwn, cpyf, wn) 7896 7897#define DEFINE_MACRO_ASM_FUNC(MASM, ASMPREFIX, ASMSUFFIX) \ 7898 void MASM(const Register& ra, const Register& rb, const Register& rc) { \ 7899 ExactAssemblyScope scope(this, 3 * kInstructionSize); \ 7900 ASMPREFIX##p##ASMSUFFIX(ra, rb, rc); \ 7901 ASMPREFIX##m##ASMSUFFIX(ra, rb, rc); \ 7902 ASMPREFIX##e##ASMSUFFIX(ra, rb, rc); \ 7903 } 7904 MOPS_LIST(DEFINE_MACRO_ASM_FUNC) 7905#undef DEFINE_MACRO_ASM_FUNC 7906 7907 void Abs(const Register& rd, const Register& rn) { 7908 VIXL_ASSERT(allow_macro_instructions_); 7909 SingleEmissionCheckScope guard(this); 7910 abs(rd, rn); 7911 } 7912 7913 void Cnt(const Register& rd, const Register& rn) { 7914 VIXL_ASSERT(allow_macro_instructions_); 7915 SingleEmissionCheckScope guard(this); 7916 cnt(rd, rn); 7917 } 7918 7919 void Ctz(const Register& rd, const Register& rn) { 7920 VIXL_ASSERT(allow_macro_instructions_); 7921 SingleEmissionCheckScope guard(this); 7922 ctz(rd, rn); 7923 } 7924 7925 void Smax(const Register& rd, const Register& rn, const Operand& op); 7926 void Smin(const Register& rd, const Register& rn, const Operand& op); 7927 void Umax(const Register& rd, const Register& rn, const Operand& op); 7928 void Umin(const Register& rd, const Register& rn, const Operand& op); 7929 7930 template <typename T> 7931 Literal<T>* CreateLiteralDestroyedWithPool(T value) { 7932#ifndef PANDA_BUILD 7933 return new Literal<T>(value, 7934 &literal_pool_, 7935 RawLiteral::kDeletedOnPoolDestruction); 7936#else 7937 return allocator_.New<Literal<T>>(value, 7938 &literal_pool_, 7939 RawLiteral::kDeletedOnPoolDestruction); 7940#endif 7941 } 7942 7943 template <typename T> 7944 Literal<T>* CreateLiteralDestroyedWithPool(T high64, T low64) { 7945#ifndef PANDA_BUILD 7946 return new Literal<T>(high64, 7947 low64, 7948 &literal_pool_, 7949 RawLiteral::kDeletedOnPoolDestruction); 7950#else 7951 return allocator_.New<Literal<T>>(high64, 7952 low64, 7953 &literal_pool_, 7954 RawLiteral::kDeletedOnPoolDestruction); 7955#endif 7956 } 7957 7958 // Push the system stack pointer (sp) down to allow the same to be done to 7959 // the current stack pointer (according to StackPointer()). This must be 7960 // called _before_ accessing the memory. 7961 // 7962 // This is necessary when pushing or otherwise adding things to the stack, to 7963 // satisfy the AAPCS64 constraint that the memory below the system stack 7964 // pointer is not accessed. 7965 // 7966 // This method asserts that StackPointer() is not sp, since the call does 7967 // not make sense in that context. 7968 // 7969 // TODO: This method can only accept values of 'space' that can be encoded in 7970 // one instruction. Refer to the implementation for details. 7971 void BumpSystemStackPointer(const Operand& space); 7972 7973 virtual bool AllowMacroInstructions() const VIXL_OVERRIDE { 7974 return allow_macro_instructions_; 7975 } 7976 7977 virtual bool ArePoolsBlocked() const VIXL_OVERRIDE { 7978 return IsLiteralPoolBlocked() && IsVeneerPoolBlocked(); 7979 } 7980 7981 void SetGenerateSimulatorCode(bool value) { 7982 generate_simulator_code_ = value; 7983 } 7984 7985 bool GenerateSimulatorCode() const { return generate_simulator_code_; } 7986 7987 size_t GetLiteralPoolSize() const { return literal_pool_.GetSize(); } 7988 VIXL_DEPRECATED("GetLiteralPoolSize", size_t LiteralPoolSize() const) { 7989 return GetLiteralPoolSize(); 7990 } 7991 7992 size_t GetLiteralPoolMaxSize() const { return literal_pool_.GetMaxSize(); } 7993 VIXL_DEPRECATED("GetLiteralPoolMaxSize", size_t LiteralPoolMaxSize() const) { 7994 return GetLiteralPoolMaxSize(); 7995 } 7996 7997 size_t GetVeneerPoolMaxSize() const { return veneer_pool_.GetMaxSize(); } 7998 VIXL_DEPRECATED("GetVeneerPoolMaxSize", size_t VeneerPoolMaxSize() const) { 7999 return GetVeneerPoolMaxSize(); 8000 } 8001 8002 // The number of unresolved branches that may require a veneer. 8003 int GetNumberOfPotentialVeneers() const { 8004 return veneer_pool_.GetNumberOfPotentialVeneers(); 8005 } 8006 VIXL_DEPRECATED("GetNumberOfPotentialVeneers", 8007 int NumberOfPotentialVeneers() const) { 8008 return GetNumberOfPotentialVeneers(); 8009 } 8010 8011 ptrdiff_t GetNextCheckPoint() const { 8012 ptrdiff_t next_checkpoint_for_pools = 8013 std::min(literal_pool_.GetCheckpoint(), veneer_pool_.GetCheckpoint()); 8014 return std::min(next_checkpoint_for_pools, 8015 static_cast<ptrdiff_t>(GetBuffer().GetCapacity())); 8016 } 8017 VIXL_DEPRECATED("GetNextCheckPoint", ptrdiff_t NextCheckPoint()) { 8018 return GetNextCheckPoint(); 8019 } 8020 8021 void EmitLiteralPool(LiteralPool::EmitOption option) { 8022 if (!literal_pool_.IsEmpty()) literal_pool_.Emit(option); 8023 8024 checkpoint_ = GetNextCheckPoint(); 8025 recommended_checkpoint_ = literal_pool_.GetNextRecommendedCheckpoint(); 8026 } 8027 8028 void CheckEmitFor(size_t amount); 8029 void EnsureEmitFor(size_t amount) { 8030 ptrdiff_t offset = amount; 8031 ptrdiff_t max_pools_size = 8032 literal_pool_.GetMaxSize() + veneer_pool_.GetMaxSize(); 8033 ptrdiff_t cursor = GetCursorOffset(); 8034 if ((cursor >= recommended_checkpoint_) || 8035 ((cursor + offset + max_pools_size) >= checkpoint_)) { 8036 CheckEmitFor(amount); 8037 } 8038 } 8039 8040 void CheckEmitPoolsFor(size_t amount); 8041 virtual void EnsureEmitPoolsFor(size_t amount) VIXL_OVERRIDE { 8042 ptrdiff_t offset = amount; 8043 ptrdiff_t max_pools_size = 8044 literal_pool_.GetMaxSize() + veneer_pool_.GetMaxSize(); 8045 ptrdiff_t cursor = GetCursorOffset(); 8046 if ((cursor >= recommended_checkpoint_) || 8047 ((cursor + offset + max_pools_size) >= checkpoint_)) { 8048 CheckEmitPoolsFor(amount); 8049 } 8050 } 8051 8052 // Set the current stack pointer, but don't generate any code. 8053 void SetStackPointer(const Register& stack_pointer) { 8054 VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(stack_pointer)); 8055 sp_ = stack_pointer; 8056 } 8057 8058 // Return the current stack pointer, as set by SetStackPointer. 8059 const Register& StackPointer() const { return sp_; } 8060 8061 CPURegList* GetScratchRegisterList() { return &tmp_list_; } 8062 VIXL_DEPRECATED("GetScratchRegisterList", CPURegList* TmpList()) { 8063 return GetScratchRegisterList(); 8064 } 8065 8066 CPURegList* GetScratchVRegisterList() { return &v_tmp_list_; } 8067 VIXL_DEPRECATED("GetScratchVRegisterList", CPURegList* FPTmpList()) { 8068 return GetScratchVRegisterList(); 8069 } 8070 8071 CPURegList* GetScratchPRegisterList() { return &p_tmp_list_; } 8072 8073 // Get or set the current (most-deeply-nested) UseScratchRegisterScope. 8074 void SetCurrentScratchRegisterScope(UseScratchRegisterScope* scope) { 8075 current_scratch_scope_ = scope; 8076 } 8077 UseScratchRegisterScope* GetCurrentScratchRegisterScope() { 8078 return current_scratch_scope_; 8079 } 8080 8081 // Like printf, but print at run-time from generated code. 8082 // 8083 // The caller must ensure that arguments for floating-point placeholders 8084 // (such as %e, %f or %g) are VRegisters in format 1S or 1D, and that 8085 // arguments for integer placeholders are Registers. 8086 // 8087 // At the moment it is only possible to print the value of sp if it is the 8088 // current stack pointer. Otherwise, the MacroAssembler will automatically 8089 // update sp on every push (using BumpSystemStackPointer), so determining its 8090 // value is difficult. 8091 // 8092 // Format placeholders that refer to more than one argument, or to a specific 8093 // argument, are not supported. This includes formats like "%1$d" or "%.*d". 8094 // 8095 // This function automatically preserves caller-saved registers so that 8096 // calling code can use Printf at any point without having to worry about 8097 // corruption. The preservation mechanism generates a lot of code. If this is 8098 // a problem, preserve the important registers manually and then call 8099 // PrintfNoPreserve. Callee-saved registers are not used by Printf, and are 8100 // implicitly preserved. 8101 void Printf(const char* format, 8102 CPURegister arg0 = NoCPUReg, 8103 CPURegister arg1 = NoCPUReg, 8104 CPURegister arg2 = NoCPUReg, 8105 CPURegister arg3 = NoCPUReg); 8106 8107 // Like Printf, but don't preserve any caller-saved registers, not even 'lr'. 8108 // 8109 // The return code from the system printf call will be returned in x0. 8110 void PrintfNoPreserve(const char* format, 8111 const CPURegister& arg0 = NoCPUReg, 8112 const CPURegister& arg1 = NoCPUReg, 8113 const CPURegister& arg2 = NoCPUReg, 8114 const CPURegister& arg3 = NoCPUReg); 8115 8116 // Trace control when running the debug simulator. 8117 // 8118 // For example: 8119 // 8120 // __ Trace(LOG_REGS, TRACE_ENABLE); 8121 // Will add registers to the trace if it wasn't already the case. 8122 // 8123 // __ Trace(LOG_DISASM, TRACE_DISABLE); 8124 // Will stop logging disassembly. It has no effect if the disassembly wasn't 8125 // already being logged. 8126 void Trace(TraceParameters parameters, TraceCommand command); 8127 8128 // Log the requested data independently of what is being traced. 8129 // 8130 // For example: 8131 // 8132 // __ Log(LOG_FLAGS) 8133 // Will output the flags. 8134 void Log(TraceParameters parameters); 8135 8136 // Enable or disable CPU features dynamically. This mechanism allows users to 8137 // strictly check the use of CPU features in different regions of code. 8138 void SetSimulatorCPUFeatures(const CPUFeatures& features); 8139 void EnableSimulatorCPUFeatures(const CPUFeatures& features); 8140 void DisableSimulatorCPUFeatures(const CPUFeatures& features); 8141 void SaveSimulatorCPUFeatures(); 8142 void RestoreSimulatorCPUFeatures(); 8143 8144 LiteralPool* GetLiteralPool() { return &literal_pool_; } 8145 8146// Support for simulated runtime calls. 8147 8148// `CallRuntime` requires variadic templating, that is only available from 8149// C++11. 8150#if __cplusplus >= 201103L 8151#define VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT 8152#endif // #if __cplusplus >= 201103L 8153 8154#ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT 8155 template <typename R, typename... P> 8156 void CallRuntimeHelper(R (*function)(P...), RuntimeCallType call_type); 8157 8158 template <typename R, typename... P> 8159 void CallRuntime(R (*function)(P...)) { 8160 CallRuntimeHelper(function, kCallRuntime); 8161 } 8162 8163 template <typename R, typename... P> 8164 void TailCallRuntime(R (*function)(P...)) { 8165 CallRuntimeHelper(function, kTailCallRuntime); 8166 } 8167#endif // #ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT 8168 8169 protected: 8170 void BlockLiteralPool() { literal_pool_.Block(); } 8171 void ReleaseLiteralPool() { literal_pool_.Release(); } 8172 bool IsLiteralPoolBlocked() const { return literal_pool_.IsBlocked(); } 8173 void BlockVeneerPool() { veneer_pool_.Block(); } 8174 void ReleaseVeneerPool() { veneer_pool_.Release(); } 8175 bool IsVeneerPoolBlocked() const { return veneer_pool_.IsBlocked(); } 8176 8177 virtual void BlockPools() VIXL_OVERRIDE { 8178 BlockLiteralPool(); 8179 BlockVeneerPool(); 8180 } 8181 8182 virtual void ReleasePools() VIXL_OVERRIDE { 8183 ReleaseLiteralPool(); 8184 ReleaseVeneerPool(); 8185 } 8186 8187 // The scopes below need to able to block and release a particular pool. 8188 // TODO: Consider removing those scopes or move them to 8189 // code-generation-scopes-vixl.h. 8190 friend class BlockPoolsScope; 8191 friend class BlockLiteralPoolScope; 8192 friend class BlockVeneerPoolScope; 8193 8194 virtual void SetAllowMacroInstructions(bool value) VIXL_OVERRIDE { 8195 allow_macro_instructions_ = value; 8196 } 8197 8198 // Helper used to query information about code generation and to generate 8199 // code for `csel`. 8200 // Here and for the related helpers below: 8201 // - Code is generated when `masm` is not `NULL`. 8202 // - On return and when set, `should_synthesise_left` and 8203 // `should_synthesise_right` will indicate whether `left` and `right` 8204 // should be synthesized in a temporary register. 8205 static void CselHelper(MacroAssembler* masm, 8206 const Register& rd, 8207 Operand left, 8208 Operand right, 8209 Condition cond, 8210 bool* should_synthesise_left = NULL, 8211 bool* should_synthesise_right = NULL); 8212 8213 // The helper returns `true` if it can handle the specified arguments. 8214 // Also see comments for `CselHelper()`. 8215 static bool CselSubHelperTwoImmediates(MacroAssembler* masm, 8216 const Register& rd, 8217 int64_t left, 8218 int64_t right, 8219 Condition cond, 8220 bool* should_synthesise_left, 8221 bool* should_synthesise_right); 8222 8223 // See comments for `CselHelper()`. 8224 static bool CselSubHelperTwoOrderedImmediates(MacroAssembler* masm, 8225 const Register& rd, 8226 int64_t left, 8227 int64_t right, 8228 Condition cond); 8229 8230 // See comments for `CselHelper()`. 8231 static void CselSubHelperRightSmallImmediate(MacroAssembler* masm, 8232 UseScratchRegisterScope* temps, 8233 const Register& rd, 8234 const Operand& left, 8235 const Operand& right, 8236 Condition cond, 8237 bool* should_synthesise_left); 8238 8239 // Generate code to calculate the address represented by `addr` and write it 8240 // into `xd`. This is used as a common fall-back for out-of-range load and 8241 // store operands. 8242 // 8243 // The vl_divisor_log2 argument is used to scale the VL, for use with 8244 // SVE_MUL_VL. 8245 void CalculateSVEAddress(const Register& xd, 8246 const SVEMemOperand& addr, 8247 int vl_divisor_log2 = 0); 8248 8249 void CalculateSVEAddress(const Register& xd, 8250 const SVEMemOperand& addr, 8251 const CPURegister& rt) { 8252 VIXL_ASSERT(rt.IsPRegister() || rt.IsZRegister()); 8253 int vl_divisor_log2 = rt.IsPRegister() ? kZRegBitsPerPRegBitLog2 : 0; 8254 CalculateSVEAddress(xd, addr, vl_divisor_log2); 8255 } 8256 8257 void SetFPNaNPropagationOption(FPMacroNaNPropagationOption nan_option) { 8258 fp_nan_propagation_ = nan_option; 8259 } 8260 8261 void ResolveFPNaNPropagationOption(FPMacroNaNPropagationOption* nan_option) { 8262 // The input option has priority over the option that has set. 8263 if (*nan_option == NoFPMacroNaNPropagationSelected) { 8264 *nan_option = fp_nan_propagation_; 8265 } 8266 VIXL_ASSERT(*nan_option != NoFPMacroNaNPropagationSelected); 8267 } 8268 8269 private: 8270 // The actual Push and Pop implementations. These don't generate any code 8271 // other than that required for the push or pop. This allows 8272 // (Push|Pop)CPURegList to bundle together setup code for a large block of 8273 // registers. 8274 // 8275 // Note that size is per register, and is specified in bytes. 8276 void PushHelper(int count, 8277 int size, 8278 const CPURegister& src0, 8279 const CPURegister& src1, 8280 const CPURegister& src2, 8281 const CPURegister& src3); 8282 void PopHelper(int count, 8283 int size, 8284 const CPURegister& dst0, 8285 const CPURegister& dst1, 8286 const CPURegister& dst2, 8287 const CPURegister& dst3); 8288 8289 void Movi16bitHelper(const VRegister& vd, uint64_t imm); 8290 void Movi32bitHelper(const VRegister& vd, uint64_t imm); 8291 void Movi64bitHelper(const VRegister& vd, uint64_t imm); 8292 8293 // Perform necessary maintenance operations before a push or pop. 8294 // 8295 // Note that size is per register, and is specified in bytes. 8296 void PrepareForPush(int count, int size); 8297 void PrepareForPop(int count, int size); 8298 8299 // The actual implementation of load and store operations for CPURegList. 8300 enum LoadStoreCPURegListAction { kLoad, kStore }; 8301 void LoadStoreCPURegListHelper(LoadStoreCPURegListAction operation, 8302 CPURegList registers, 8303 const MemOperand& mem); 8304 // Returns a MemOperand suitable for loading or storing a CPURegList at `dst`. 8305 // This helper may allocate registers from `scratch_scope` and generate code 8306 // to compute an intermediate address. The resulting MemOperand is only valid 8307 // as long as `scratch_scope` remains valid. 8308 MemOperand BaseMemOperandForLoadStoreCPURegList( 8309 const CPURegList& registers, 8310 const MemOperand& mem, 8311 UseScratchRegisterScope* scratch_scope); 8312 8313 bool LabelIsOutOfRange(Label* label, ImmBranchType branch_type) { 8314 return !Instruction::IsValidImmPCOffset(branch_type, 8315 label->GetLocation() - 8316 GetCursorOffset()); 8317 } 8318 8319 void ConfigureSimulatorCPUFeaturesHelper(const CPUFeatures& features, 8320 DebugHltOpcode action); 8321 8322 void CompareHelper(Condition cond, 8323 const PRegisterWithLaneSize& pd, 8324 const PRegisterZ& pg, 8325 const ZRegister& zn, 8326 IntegerOperand imm); 8327 8328 // E.g. Ld1rb. 8329 typedef void (Assembler::*SVELoadBroadcastFn)(const ZRegister& zt, 8330 const PRegisterZ& pg, 8331 const SVEMemOperand& addr); 8332 8333 void SVELoadBroadcastImmHelper(const ZRegister& zt, 8334 const PRegisterZ& pg, 8335 const SVEMemOperand& addr, 8336 SVELoadBroadcastFn fn, 8337 int divisor); 8338 8339 // E.g. ldr/str 8340 typedef void (Assembler::*SVELoadStoreFn)(const CPURegister& rt, 8341 const SVEMemOperand& addr); 8342 8343 void SVELoadStoreScalarImmHelper(const CPURegister& rt, 8344 const SVEMemOperand& addr, 8345 SVELoadStoreFn fn); 8346 8347 typedef void (Assembler::*SVELoad1Fn)(const ZRegister& zt, 8348 const PRegisterZ& pg, 8349 const SVEMemOperand& addr); 8350 typedef void (Assembler::*SVEStore1Fn)(const ZRegister& zt, 8351 const PRegister& pg, 8352 const SVEMemOperand& addr); 8353 8354 // Helper for predicated Z register loads with addressing modes not directly 8355 // encodable in the instruction. The supported_modifier parameter indicates 8356 // which offset modifier the calling instruction encoder supports (eg. 8357 // SVE_MUL_VL). The ratio log2 of VL to memory access size is passed as 8358 // vl_divisor_log2; pass -1 to indicate no dependency. 8359 template <typename Tg, typename Tf> 8360 void SVELoadStoreNTBroadcastQOHelper( 8361 const ZRegister& zt, 8362 const Tg& pg, 8363 const SVEMemOperand& addr, 8364 Tf fn, 8365 int imm_bits, 8366 int shift_amount, 8367 SVEOffsetModifier supported_modifier = NO_SVE_OFFSET_MODIFIER, 8368 int vl_divisor_log2 = 0); 8369 8370 template <typename Tg, typename Tf> 8371 void SVELoadStore1Helper(int msize_in_bytes_log2, 8372 const ZRegister& zt, 8373 const Tg& pg, 8374 const SVEMemOperand& addr, 8375 Tf fn); 8376 8377 template <typename Tf> 8378 void SVELoadFFHelper(int msize_in_bytes_log2, 8379 const ZRegister& zt, 8380 const PRegisterZ& pg, 8381 const SVEMemOperand& addr, 8382 Tf fn); 8383 8384 typedef void (MacroAssembler::*IntWideImmMacroFn)(const ZRegister& zd, 8385 const ZRegister& zn, 8386 IntegerOperand imm); 8387 8388 typedef void (Assembler::*IntWideImmShiftFn)(const ZRegister& zd, 8389 const ZRegister& zn, 8390 int imm, 8391 int shift); 8392 8393 typedef void (Assembler::*Int3ArithFn)(const ZRegister& zd, 8394 const ZRegister& zn, 8395 const ZRegister& zm); 8396 8397 typedef void (Assembler::*Int4ArithFn)(const ZRegister& zd, 8398 const ZRegister& za, 8399 const ZRegister& zn, 8400 const ZRegister& zm); 8401 8402 typedef void (Assembler::*IntArithImmFn)(const ZRegister& zd, 8403 const ZRegister& zn, 8404 int imm); 8405 8406 typedef void (Assembler::*ZZZImmFn)(const ZRegister& zd, 8407 const ZRegister& zn, 8408 const ZRegister& zm, 8409 int imm); 8410 8411 typedef void (MacroAssembler::*SVEArithPredicatedFn)(const ZRegister& zd, 8412 const PRegisterM& pg, 8413 const ZRegister& zn, 8414 const ZRegister& zm); 8415 8416 void IntWideImmHelper(IntArithImmFn imm_fn, 8417 SVEArithPredicatedFn reg_fn, 8418 const ZRegister& zd, 8419 const ZRegister& zn, 8420 IntegerOperand imm, 8421 bool is_signed_imm); 8422 8423 enum AddSubHelperOption { kAddImmediate, kSubImmediate }; 8424 8425 void AddSubHelper(AddSubHelperOption option, 8426 const ZRegister& zd, 8427 const ZRegister& zn, 8428 IntegerOperand imm); 8429 8430 // Try to emit an add- or sub-like instruction (imm_fn) with `imm`, or the 8431 // corresponding sub- or add-like instruction (n_imm_fn) with a negated `imm`. 8432 // A `movprfx` is automatically generated if one is required. If successful, 8433 // return true. Otherwise, return false. 8434 // 8435 // This helper uses two's complement equivalences, for example treating 0xffff 8436 // as -1 for H-sized lanes. 8437 bool TrySingleAddSub(AddSubHelperOption option, 8438 const ZRegister& zd, 8439 const ZRegister& zn, 8440 IntegerOperand imm); 8441 8442 void AbsoluteDifferenceAccumulate(Int3ArithFn fn, 8443 const ZRegister& zd, 8444 const ZRegister& za, 8445 const ZRegister& zn, 8446 const ZRegister& zm); 8447 8448 void FourRegDestructiveHelper(Int3ArithFn fn, 8449 const ZRegister& zd, 8450 const ZRegister& za, 8451 const ZRegister& zn, 8452 const ZRegister& zm); 8453 8454 void FourRegDestructiveHelper(Int4ArithFn fn, 8455 const ZRegister& zd, 8456 const ZRegister& za, 8457 const ZRegister& zn, 8458 const ZRegister& zm); 8459 8460 void SVEDotIndexHelper(ZZZImmFn fn, 8461 const ZRegister& zd, 8462 const ZRegister& za, 8463 const ZRegister& zn, 8464 const ZRegister& zm, 8465 int index); 8466 8467 // For noncommutative arithmetic operations. 8468 void NoncommutativeArithmeticHelper(const ZRegister& zd, 8469 const PRegisterM& pg, 8470 const ZRegister& zn, 8471 const ZRegister& zm, 8472 SVEArithPredicatedFn fn, 8473 SVEArithPredicatedFn rev_fn); 8474 8475 void FPCommutativeArithmeticHelper(const ZRegister& zd, 8476 const PRegisterM& pg, 8477 const ZRegister& zn, 8478 const ZRegister& zm, 8479 SVEArithPredicatedFn fn, 8480 FPMacroNaNPropagationOption nan_option); 8481 8482 // Floating-point fused multiply-add vectors (predicated), writing addend. 8483 typedef void (Assembler::*SVEMulAddPredicatedZdaFn)(const ZRegister& zda, 8484 const PRegisterM& pg, 8485 const ZRegister& zn, 8486 const ZRegister& zm); 8487 8488 // Floating-point fused multiply-add vectors (predicated), writing 8489 // multiplicand. 8490 typedef void (Assembler::*SVEMulAddPredicatedZdnFn)(const ZRegister& zdn, 8491 const PRegisterM& pg, 8492 const ZRegister& zn, 8493 const ZRegister& zm); 8494 8495 void FPMulAddHelper(const ZRegister& zd, 8496 const PRegisterM& pg, 8497 const ZRegister& za, 8498 const ZRegister& zn, 8499 const ZRegister& zm, 8500 SVEMulAddPredicatedZdaFn fn_zda, 8501 SVEMulAddPredicatedZdnFn fn_zdn, 8502 FPMacroNaNPropagationOption nan_option); 8503 8504 typedef void (Assembler::*SVEMulAddIndexFn)(const ZRegister& zda, 8505 const ZRegister& zn, 8506 const ZRegister& zm, 8507 int index); 8508 8509 void FourRegOneImmDestructiveHelper(ZZZImmFn fn, 8510 const ZRegister& zd, 8511 const ZRegister& za, 8512 const ZRegister& zn, 8513 const ZRegister& zm, 8514 int imm); 8515 8516 void ShiftRightAccumulate(IntArithImmFn fn, 8517 const ZRegister& zd, 8518 const ZRegister& za, 8519 const ZRegister& zn, 8520 int imm); 8521 8522 void ComplexAddition(ZZZImmFn fn, 8523 const ZRegister& zd, 8524 const ZRegister& zn, 8525 const ZRegister& zm, 8526 int rot); 8527 8528 // Tell whether any of the macro instruction can be used. When false the 8529 // MacroAssembler will assert if a method which can emit a variable number 8530 // of instructions is called. 8531 bool allow_macro_instructions_; 8532 8533 // Indicates whether we should generate simulator or native code. 8534 bool generate_simulator_code_; 8535 8536 // The register to use as a stack pointer for stack operations. 8537 Register sp_; 8538 8539 // Scratch registers available for use by the MacroAssembler. 8540 CPURegList tmp_list_; 8541 CPURegList v_tmp_list_; 8542 CPURegList p_tmp_list_; 8543 8544 UseScratchRegisterScope* current_scratch_scope_; 8545 8546 LiteralPool literal_pool_; 8547 VeneerPool veneer_pool_; 8548 8549 ptrdiff_t checkpoint_; 8550 ptrdiff_t recommended_checkpoint_; 8551 8552 FPMacroNaNPropagationOption fp_nan_propagation_; 8553 8554#ifdef PANDA_BUILD 8555 AllocatorWrapper allocator_; 8556#endif 8557 friend class Pool; 8558 friend class LiteralPool; 8559}; 8560 8561 8562inline size_t VeneerPool::GetOtherPoolsMaxSize() const { 8563 return masm_->GetLiteralPoolMaxSize(); 8564} 8565 8566 8567inline size_t LiteralPool::GetOtherPoolsMaxSize() const { 8568 return masm_->GetVeneerPoolMaxSize(); 8569} 8570 8571 8572inline void LiteralPool::SetNextRecommendedCheckpoint(ptrdiff_t offset) { 8573 masm_->recommended_checkpoint_ = 8574 std::min(masm_->recommended_checkpoint_, offset); 8575 recommended_checkpoint_ = offset; 8576} 8577 8578class InstructionAccurateScope : public ExactAssemblyScope { 8579 public: 8580 VIXL_DEPRECATED("ExactAssemblyScope", 8581 InstructionAccurateScope(MacroAssembler* masm, 8582 int64_t count, 8583 SizePolicy size_policy = kExactSize)) 8584 : ExactAssemblyScope(masm, count * kInstructionSize, size_policy) {} 8585}; 8586 8587class BlockLiteralPoolScope { 8588 public: 8589 explicit BlockLiteralPoolScope(MacroAssembler* masm) : masm_(masm) { 8590 masm_->BlockLiteralPool(); 8591 } 8592 8593 ~BlockLiteralPoolScope() { masm_->ReleaseLiteralPool(); } 8594 8595 private: 8596 MacroAssembler* masm_; 8597}; 8598 8599 8600class BlockVeneerPoolScope { 8601 public: 8602 explicit BlockVeneerPoolScope(MacroAssembler* masm) : masm_(masm) { 8603 masm_->BlockVeneerPool(); 8604 } 8605 8606 ~BlockVeneerPoolScope() { masm_->ReleaseVeneerPool(); } 8607 8608 private: 8609 MacroAssembler* masm_; 8610}; 8611 8612 8613class BlockPoolsScope { 8614 public: 8615 explicit BlockPoolsScope(MacroAssembler* masm) : masm_(masm) { 8616 masm_->BlockPools(); 8617 } 8618 8619 ~BlockPoolsScope() { masm_->ReleasePools(); } 8620 8621 private: 8622 MacroAssembler* masm_; 8623}; 8624 8625MovprfxHelperScope::MovprfxHelperScope(MacroAssembler* masm, 8626 const ZRegister& dst, 8627 const ZRegister& src) 8628 : ExactAssemblyScope(masm, 8629 ShouldGenerateMovprfx(dst, src) 8630 ? (2 * kInstructionSize) 8631 : kInstructionSize) { 8632 if (ShouldGenerateMovprfx(dst, src)) { 8633 masm->movprfx(dst, src); 8634 } 8635} 8636 8637MovprfxHelperScope::MovprfxHelperScope(MacroAssembler* masm, 8638 const ZRegister& dst, 8639 const PRegister& pg, 8640 const ZRegister& src) 8641 : ExactAssemblyScope(masm, 8642 ShouldGenerateMovprfx(dst, pg, src) 8643 ? (2 * kInstructionSize) 8644 : kInstructionSize) { 8645 if (ShouldGenerateMovprfx(dst, pg, src)) { 8646 masm->movprfx(dst, pg, src); 8647 } 8648} 8649 8650// This scope utility allows scratch registers to be managed safely. The 8651// MacroAssembler's GetScratch*RegisterList() are used as a pool of scratch 8652// registers. These registers can be allocated on demand, and will be returned 8653// at the end of the scope. 8654// 8655// When the scope ends, the MacroAssembler's lists will be restored to their 8656// original state, even if the lists were modified by some other means. 8657class UseScratchRegisterScope { 8658 public: 8659 // This constructor implicitly calls `Open` to initialise the scope (`masm` 8660 // must not be `NULL`), so it is ready to use immediately after it has been 8661 // constructed. 8662 explicit UseScratchRegisterScope(MacroAssembler* masm) 8663 : masm_(NULL), 8664 parent_(NULL), 8665 old_available_(0), 8666 old_available_v_(0), 8667 old_available_p_(0) { 8668 Open(masm); 8669 } 8670 // This constructor does not implicitly initialise the scope. Instead, the 8671 // user is required to explicitly call the `Open` function before using the 8672 // scope. 8673 UseScratchRegisterScope() 8674 : masm_(NULL), 8675 parent_(NULL), 8676 old_available_(0), 8677 old_available_v_(0), 8678 old_available_p_(0) {} 8679 8680 // This function performs the actual initialisation work. 8681 void Open(MacroAssembler* masm); 8682 8683 // The destructor always implicitly calls the `Close` function. 8684 ~UseScratchRegisterScope() { Close(); } 8685 8686 // This function performs the cleaning-up work. It must succeed even if the 8687 // scope has not been opened. It is safe to call multiple times. 8688 void Close(); 8689 8690 8691 bool IsAvailable(const CPURegister& reg) const; 8692 8693 // Take a register from the appropriate temps list. It will be returned 8694 // automatically when the scope ends. 8695 Register AcquireW() { 8696 return AcquireFrom(masm_->GetScratchRegisterList()).W(); 8697 } 8698 Register AcquireX() { 8699 return AcquireFrom(masm_->GetScratchRegisterList()).X(); 8700 } 8701 VRegister AcquireH() { 8702 return AcquireFrom(masm_->GetScratchVRegisterList()).H(); 8703 } 8704 VRegister AcquireS() { 8705 return AcquireFrom(masm_->GetScratchVRegisterList()).S(); 8706 } 8707 VRegister AcquireD() { 8708 return AcquireFrom(masm_->GetScratchVRegisterList()).D(); 8709 } 8710 ZRegister AcquireZ() { 8711 return AcquireFrom(masm_->GetScratchVRegisterList()).Z(); 8712 } 8713 PRegister AcquireP() { 8714 // Prefer to allocate p8-p15 if we can, to leave p0-p7 available for use as 8715 // governing predicates. 8716 CPURegList* available = masm_->GetScratchPRegisterList(); 8717 RegList preferred = ~kGoverningPRegisterMask; 8718 if ((available->GetList() & preferred) != 0) { 8719 return AcquireFrom(available, preferred).P(); 8720 } 8721 return AcquireFrom(available).P(); 8722 } 8723 // Acquire a P register suitable for use as a governing predicate in 8724 // instructions which only accept p0-p7 for that purpose. 8725 PRegister AcquireGoverningP() { 8726 CPURegList* available = masm_->GetScratchPRegisterList(); 8727 return AcquireFrom(available, kGoverningPRegisterMask).P(); 8728 } 8729 8730 Register AcquireRegisterOfSize(int size_in_bits); 8731 Register AcquireSameSizeAs(const Register& reg) { 8732 return AcquireRegisterOfSize(reg.GetSizeInBits()); 8733 } 8734 VRegister AcquireVRegisterOfSize(int size_in_bits); 8735 VRegister AcquireSameSizeAs(const VRegister& reg) { 8736 return AcquireVRegisterOfSize(reg.GetSizeInBits()); 8737 } 8738 CPURegister AcquireCPURegisterOfSize(int size_in_bits) { 8739 return masm_->GetScratchRegisterList()->IsEmpty() 8740 ? CPURegister(AcquireVRegisterOfSize(size_in_bits)) 8741 : CPURegister(AcquireRegisterOfSize(size_in_bits)); 8742 } 8743 8744 // Acquire a register big enough to represent one lane of `vector`. 8745 Register AcquireRegisterToHoldLane(const CPURegister& vector) { 8746 VIXL_ASSERT(vector.GetLaneSizeInBits() <= kXRegSize); 8747 return (vector.GetLaneSizeInBits() > kWRegSize) ? AcquireX() : AcquireW(); 8748 } 8749 8750 8751 // Explicitly release an acquired (or excluded) register, putting it back in 8752 // the appropriate temps list. 8753 void Release(const CPURegister& reg); 8754 8755 8756 // Make the specified registers available as scratch registers for the 8757 // duration of this scope. 8758 void Include(const CPURegList& list); 8759 void Include(const Register& reg1, 8760 const Register& reg2 = NoReg, 8761 const Register& reg3 = NoReg, 8762 const Register& reg4 = NoReg); 8763 void Include(const VRegister& reg1, 8764 const VRegister& reg2 = NoVReg, 8765 const VRegister& reg3 = NoVReg, 8766 const VRegister& reg4 = NoVReg); 8767 void Include(const CPURegister& reg1, 8768 const CPURegister& reg2 = NoCPUReg, 8769 const CPURegister& reg3 = NoCPUReg, 8770 const CPURegister& reg4 = NoCPUReg); 8771 8772 8773 // Make sure that the specified registers are not available in this scope. 8774 // This can be used to prevent helper functions from using sensitive 8775 // registers, for example. 8776 void Exclude(const CPURegList& list); 8777 void Exclude(const Register& reg1, 8778 const Register& reg2 = NoReg, 8779 const Register& reg3 = NoReg, 8780 const Register& reg4 = NoReg); 8781 void Exclude(const VRegister& reg1, 8782 const VRegister& reg2 = NoVReg, 8783 const VRegister& reg3 = NoVReg, 8784 const VRegister& reg4 = NoVReg); 8785 void Exclude(const CPURegister& reg1, 8786 const CPURegister& reg2 = NoCPUReg, 8787 const CPURegister& reg3 = NoCPUReg, 8788 const CPURegister& reg4 = NoCPUReg); 8789 8790 // Convenience for excluding registers that are part of Operands. This is 8791 // useful for sequences like this: 8792 // 8793 // // Use 'rd' as a scratch, but only if it's not aliased by an input. 8794 // temps.Include(rd); 8795 // temps.Exclude(rn); 8796 // temps.Exclude(operand); 8797 // 8798 // Otherwise, a conditional check is needed on the last 'Exclude'. 8799 void Exclude(const Operand& operand) { 8800 if (operand.IsShiftedRegister() || operand.IsExtendedRegister()) { 8801 Exclude(operand.GetRegister()); 8802 } else { 8803 VIXL_ASSERT(operand.IsImmediate()); 8804 } 8805 } 8806 8807 // Prevent any scratch registers from being used in this scope. 8808 void ExcludeAll(); 8809 8810 private: 8811 static CPURegister AcquireFrom(CPURegList* available, 8812 RegList mask = ~static_cast<RegList>(0)); 8813 8814 static void ReleaseByCode(CPURegList* available, int code); 8815 static void ReleaseByRegList(CPURegList* available, RegList regs); 8816 static void IncludeByRegList(CPURegList* available, RegList exclude); 8817 static void ExcludeByRegList(CPURegList* available, RegList exclude); 8818 8819 CPURegList* GetAvailableListFor(CPURegister::RegisterBank bank); 8820 8821 static const RegList kGoverningPRegisterMask = 8822 (static_cast<RegList>(1) << kNumberOfGoverningPRegisters) - 1; 8823 8824 // The MacroAssembler maintains a list of available scratch registers, and 8825 // also keeps track of the most recently-opened scope so that on destruction 8826 // we can check that scopes do not outlive their parents. 8827 MacroAssembler* masm_; 8828 UseScratchRegisterScope* parent_; 8829 8830 // The state of the available lists at the start of this scope. 8831 RegList old_available_; // kRegister 8832 RegList old_available_v_; // kVRegister / kZRegister 8833 RegList old_available_p_; // kPRegister 8834 8835 // Disallow copy constructor and operator=. 8836 VIXL_NO_RETURN_IN_DEBUG_MODE UseScratchRegisterScope( 8837 const UseScratchRegisterScope&) { 8838 VIXL_UNREACHABLE(); 8839 } 8840 VIXL_NO_RETURN_IN_DEBUG_MODE void operator=(const UseScratchRegisterScope&) { 8841 VIXL_UNREACHABLE(); 8842 } 8843}; 8844 8845 8846// Like CPUFeaturesScope, but also generate Simulation pseudo-instructions to 8847// control a Simulator's CPUFeatures dynamically. 8848// 8849// One major difference from CPUFeaturesScope is that this scope cannot offer 8850// a writable "CPUFeatures* GetCPUFeatures()", because every write to the 8851// features needs a corresponding macro instruction. 8852class SimulationCPUFeaturesScope { 8853 public: 8854 template <typename... T> 8855 explicit SimulationCPUFeaturesScope(MacroAssembler* masm, T... features) 8856 : masm_(masm), cpu_features_scope_(masm, features...) { 8857 masm_->SaveSimulatorCPUFeatures(); 8858 masm_->EnableSimulatorCPUFeatures(CPUFeatures(features...)); 8859 } 8860 8861 ~SimulationCPUFeaturesScope() { masm_->RestoreSimulatorCPUFeatures(); } 8862 8863 const CPUFeatures* GetCPUFeatures() const { 8864 return cpu_features_scope_.GetCPUFeatures(); 8865 } 8866 8867 void SetCPUFeatures(const CPUFeatures& cpu_features) { 8868 cpu_features_scope_.SetCPUFeatures(cpu_features); 8869 masm_->SetSimulatorCPUFeatures(cpu_features); 8870 } 8871 8872 private: 8873 MacroAssembler* masm_; 8874 CPUFeaturesScope cpu_features_scope_; 8875}; 8876 8877 8878// Variadic templating is only available from C++11. 8879#ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT 8880 8881// `R` stands for 'return type', and `P` for 'parameter types'. 8882template <typename R, typename... P> 8883void MacroAssembler::CallRuntimeHelper(R (*function)(P...), 8884 RuntimeCallType call_type) { 8885 if (generate_simulator_code_) { 8886#ifdef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT 8887 uintptr_t runtime_call_wrapper_address = reinterpret_cast<uintptr_t>( 8888 &(Simulator::RuntimeCallStructHelper<R, P...>::Wrapper)); 8889 uintptr_t function_address = reinterpret_cast<uintptr_t>(function); 8890 8891 EmissionCheckScope guard(this, 8892 kRuntimeCallLength, 8893 CodeBufferCheckScope::kExactSize); 8894#ifndef PANDA_BUILD 8895 Label start; 8896#else 8897 Label start(allocator_); 8898#endif 8899 bind(&start); 8900 { 8901 ExactAssemblyScope scope(this, kInstructionSize); 8902 hlt(kRuntimeCallOpcode); 8903 } 8904 VIXL_ASSERT(GetSizeOfCodeGeneratedSince(&start) == 8905 kRuntimeCallWrapperOffset); 8906 dc(runtime_call_wrapper_address); 8907 VIXL_ASSERT(GetSizeOfCodeGeneratedSince(&start) == 8908 kRuntimeCallFunctionOffset); 8909 dc(function_address); 8910 VIXL_ASSERT(GetSizeOfCodeGeneratedSince(&start) == kRuntimeCallTypeOffset); 8911 dc32(call_type); 8912 VIXL_ASSERT(GetSizeOfCodeGeneratedSince(&start) == kRuntimeCallLength); 8913#else 8914 VIXL_UNREACHABLE(); 8915#endif // #ifdef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT 8916 } else { 8917 UseScratchRegisterScope temps(this); 8918 Register temp = temps.AcquireX(); 8919 Mov(temp, reinterpret_cast<uint64_t>(function)); 8920 if (call_type == kTailCallRuntime) { 8921 Br(temp); 8922 } else { 8923 VIXL_ASSERT(call_type == kCallRuntime); 8924 Blr(temp); 8925 } 8926 } 8927} 8928 8929#endif // #ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT 8930 8931} // namespace aarch64 8932 8933// Required InvalSet template specialisations. 8934// TODO: These template specialisations should not live in this file. Move 8935// VeneerPool out of the aarch64 namespace in order to share its implementation 8936// later. 8937template <> 8938inline ptrdiff_t InvalSet<aarch64::VeneerPool::BranchInfo, 8939 aarch64::VeneerPool::kNPreallocatedInfos, 8940 ptrdiff_t, 8941 aarch64::VeneerPool::kInvalidOffset, 8942 aarch64::VeneerPool::kReclaimFrom, 8943 aarch64::VeneerPool::kReclaimFactor>:: 8944 GetKey(const aarch64::VeneerPool::BranchInfo& branch_info) { 8945 return branch_info.first_unreacheable_pc_; 8946} 8947template <> 8948inline void InvalSet<aarch64::VeneerPool::BranchInfo, 8949 aarch64::VeneerPool::kNPreallocatedInfos, 8950 ptrdiff_t, 8951 aarch64::VeneerPool::kInvalidOffset, 8952 aarch64::VeneerPool::kReclaimFrom, 8953 aarch64::VeneerPool::kReclaimFactor>:: 8954 SetKey(aarch64::VeneerPool::BranchInfo* branch_info, ptrdiff_t key) { 8955 branch_info->first_unreacheable_pc_ = key; 8956} 8957 8958} // namespace vixl 8959 8960#endif // VIXL_AARCH64_MACRO_ASSEMBLER_AARCH64_H_ 8961