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