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