• 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 
Addg(const Register & xd,const Register & xn,int offset,int tag_offset)2683   void Addg(const Register& xd,
2684             const Register& xn,
2685             int offset,
2686             int tag_offset) {
2687     VIXL_ASSERT(allow_macro_instructions_);
2688     SingleEmissionCheckScope guard(this);
2689     addg(xd, xn, offset, tag_offset);
2690   }
Gmi(const Register & xd,const Register & xn,const Register & xm)2691   void Gmi(const Register& xd, const Register& xn, const Register& xm) {
2692     VIXL_ASSERT(allow_macro_instructions_);
2693     SingleEmissionCheckScope guard(this);
2694     gmi(xd, xn, xm);
2695   }
2696   void Irg(const Register& xd, const Register& xn, const Register& xm = xzr) {
2697     VIXL_ASSERT(allow_macro_instructions_);
2698     SingleEmissionCheckScope guard(this);
2699     irg(xd, xn, xm);
2700   }
Subg(const Register & xd,const Register & xn,int offset,int tag_offset)2701   void Subg(const Register& xd,
2702             const Register& xn,
2703             int offset,
2704             int tag_offset) {
2705     VIXL_ASSERT(allow_macro_instructions_);
2706     SingleEmissionCheckScope guard(this);
2707     subg(xd, xn, offset, tag_offset);
2708   }
Subp(const Register & xd,const Register & xn,const Register & xm)2709   void Subp(const Register& xd, const Register& xn, const Register& xm) {
2710     VIXL_ASSERT(allow_macro_instructions_);
2711     SingleEmissionCheckScope guard(this);
2712     subp(xd, xn, xm);
2713   }
Subps(const Register & xd,const Register & xn,const Register & xm)2714   void Subps(const Register& xd, const Register& xn, const Register& xm) {
2715     VIXL_ASSERT(allow_macro_instructions_);
2716     SingleEmissionCheckScope guard(this);
2717     subps(xd, xn, xm);
2718   }
Cmpp(const Register & xn,const Register & xm)2719   void Cmpp(const Register& xn, const Register& xm) { Subps(xzr, xn, xm); }
2720   void Chkfeat(const Register& xdn);
Gcspushm(const Register & rt)2721   void Gcspushm(const Register& rt) {
2722     VIXL_ASSERT(allow_macro_instructions_);
2723     SingleEmissionCheckScope guard(this);
2724     gcspushm(rt);
2725   }
2726   void Gcspopm(const Register& rt = xzr) {
2727     VIXL_ASSERT(allow_macro_instructions_);
2728     SingleEmissionCheckScope guard(this);
2729     gcspopm(rt);
2730   }
Gcsss1(const Register & rt)2731   void Gcsss1(const Register& rt) {
2732     VIXL_ASSERT(allow_macro_instructions_);
2733     SingleEmissionCheckScope guard(this);
2734     gcsss1(rt);
2735   }
Gcsss2(const Register & rt)2736   void Gcsss2(const Register& rt) {
2737     VIXL_ASSERT(allow_macro_instructions_);
2738     SingleEmissionCheckScope guard(this);
2739     gcsss2(rt);
2740   }
2741 
2742 // NEON 3 vector register instructions.
2743 #define NEON_3VREG_MACRO_LIST(V) \
2744   V(add, Add)                    \
2745   V(addhn, Addhn)                \
2746   V(addhn2, Addhn2)              \
2747   V(addp, Addp)                  \
2748   V(and_, And)                   \
2749   V(bic, Bic)                    \
2750   V(bif, Bif)                    \
2751   V(bit, Bit)                    \
2752   V(bsl, Bsl)                    \
2753   V(cmeq, Cmeq)                  \
2754   V(cmge, Cmge)                  \
2755   V(cmgt, Cmgt)                  \
2756   V(cmhi, Cmhi)                  \
2757   V(cmhs, Cmhs)                  \
2758   V(cmtst, Cmtst)                \
2759   V(eor, Eor)                    \
2760   V(fabd, Fabd)                  \
2761   V(facge, Facge)                \
2762   V(facgt, Facgt)                \
2763   V(faddp, Faddp)                \
2764   V(fcmeq, Fcmeq)                \
2765   V(fcmge, Fcmge)                \
2766   V(fcmgt, Fcmgt)                \
2767   V(fmaxnmp, Fmaxnmp)            \
2768   V(fmaxp, Fmaxp)                \
2769   V(fminnmp, Fminnmp)            \
2770   V(fminp, Fminp)                \
2771   V(fmla, Fmla)                  \
2772   V(fmlal, Fmlal)                \
2773   V(fmlal2, Fmlal2)              \
2774   V(fmls, Fmls)                  \
2775   V(fmlsl, Fmlsl)                \
2776   V(fmlsl2, Fmlsl2)              \
2777   V(fmulx, Fmulx)                \
2778   V(frecps, Frecps)              \
2779   V(frsqrts, Frsqrts)            \
2780   V(mla, Mla)                    \
2781   V(mls, Mls)                    \
2782   V(mul, Mul)                    \
2783   V(orn, Orn)                    \
2784   V(orr, Orr)                    \
2785   V(pmul, Pmul)                  \
2786   V(pmull, Pmull)                \
2787   V(pmull2, Pmull2)              \
2788   V(raddhn, Raddhn)              \
2789   V(raddhn2, Raddhn2)            \
2790   V(rax1, Rax1)                  \
2791   V(rsubhn, Rsubhn)              \
2792   V(rsubhn2, Rsubhn2)            \
2793   V(saba, Saba)                  \
2794   V(sabal, Sabal)                \
2795   V(sabal2, Sabal2)              \
2796   V(sabd, Sabd)                  \
2797   V(sabdl, Sabdl)                \
2798   V(sabdl2, Sabdl2)              \
2799   V(saddl, Saddl)                \
2800   V(saddl2, Saddl2)              \
2801   V(saddw, Saddw)                \
2802   V(saddw2, Saddw2)              \
2803   V(sha1c, Sha1c)                \
2804   V(sha1m, Sha1m)                \
2805   V(sha1p, Sha1p)                \
2806   V(sha1su0, Sha1su0)            \
2807   V(sha256h, Sha256h)            \
2808   V(sha256h2, Sha256h2)          \
2809   V(sha256su1, Sha256su1)        \
2810   V(sha512h, Sha512h)            \
2811   V(sha512h2, Sha512h2)          \
2812   V(sha512su1, Sha512su1)        \
2813   V(shadd, Shadd)                \
2814   V(shsub, Shsub)                \
2815   V(sm3partw1, Sm3partw1)        \
2816   V(sm3partw2, Sm3partw2)        \
2817   V(sm4ekey, Sm4ekey)            \
2818   V(smax, Smax)                  \
2819   V(smaxp, Smaxp)                \
2820   V(smin, Smin)                  \
2821   V(sminp, Sminp)                \
2822   V(smlal, Smlal)                \
2823   V(smlal2, Smlal2)              \
2824   V(smlsl, Smlsl)                \
2825   V(smlsl2, Smlsl2)              \
2826   V(smull, Smull)                \
2827   V(smull2, Smull2)              \
2828   V(sqadd, Sqadd)                \
2829   V(sqdmlal, Sqdmlal)            \
2830   V(sqdmlal2, Sqdmlal2)          \
2831   V(sqdmlsl, Sqdmlsl)            \
2832   V(sqdmlsl2, Sqdmlsl2)          \
2833   V(sqdmulh, Sqdmulh)            \
2834   V(sqdmull, Sqdmull)            \
2835   V(sqdmull2, Sqdmull2)          \
2836   V(sqrdmulh, Sqrdmulh)          \
2837   V(sdot, Sdot)                  \
2838   V(sqrdmlah, Sqrdmlah)          \
2839   V(udot, Udot)                  \
2840   V(sqrdmlsh, Sqrdmlsh)          \
2841   V(sqrshl, Sqrshl)              \
2842   V(sqshl, Sqshl)                \
2843   V(sqsub, Sqsub)                \
2844   V(srhadd, Srhadd)              \
2845   V(srshl, Srshl)                \
2846   V(sshl, Sshl)                  \
2847   V(ssubl, Ssubl)                \
2848   V(ssubl2, Ssubl2)              \
2849   V(ssubw, Ssubw)                \
2850   V(ssubw2, Ssubw2)              \
2851   V(sub, Sub)                    \
2852   V(subhn, Subhn)                \
2853   V(subhn2, Subhn2)              \
2854   V(trn1, Trn1)                  \
2855   V(trn2, Trn2)                  \
2856   V(uaba, Uaba)                  \
2857   V(uabal, Uabal)                \
2858   V(uabal2, Uabal2)              \
2859   V(uabd, Uabd)                  \
2860   V(uabdl, Uabdl)                \
2861   V(uabdl2, Uabdl2)              \
2862   V(uaddl, Uaddl)                \
2863   V(uaddl2, Uaddl2)              \
2864   V(uaddw, Uaddw)                \
2865   V(uaddw2, Uaddw2)              \
2866   V(uhadd, Uhadd)                \
2867   V(uhsub, Uhsub)                \
2868   V(umax, Umax)                  \
2869   V(umaxp, Umaxp)                \
2870   V(umin, Umin)                  \
2871   V(uminp, Uminp)                \
2872   V(umlal, Umlal)                \
2873   V(umlal2, Umlal2)              \
2874   V(umlsl, Umlsl)                \
2875   V(umlsl2, Umlsl2)              \
2876   V(umull, Umull)                \
2877   V(umull2, Umull2)              \
2878   V(uqadd, Uqadd)                \
2879   V(uqrshl, Uqrshl)              \
2880   V(uqshl, Uqshl)                \
2881   V(uqsub, Uqsub)                \
2882   V(urhadd, Urhadd)              \
2883   V(urshl, Urshl)                \
2884   V(ushl, Ushl)                  \
2885   V(usubl, Usubl)                \
2886   V(usubl2, Usubl2)              \
2887   V(usubw, Usubw)                \
2888   V(usubw2, Usubw2)              \
2889   V(uzp1, Uzp1)                  \
2890   V(uzp2, Uzp2)                  \
2891   V(zip1, Zip1)                  \
2892   V(zip2, Zip2)                  \
2893   V(smmla, Smmla)                \
2894   V(ummla, Ummla)                \
2895   V(usmmla, Usmmla)              \
2896   V(usdot, Usdot)
2897 
2898 #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)                                     \
2899   void MASM(const VRegister& vd, const VRegister& vn, const VRegister& vm) { \
2900     VIXL_ASSERT(allow_macro_instructions_);                                  \
2901     SingleEmissionCheckScope guard(this);                                    \
2902     ASM(vd, vn, vm);                                                         \
2903   }
2904   NEON_3VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
2905 #undef DEFINE_MACRO_ASM_FUNC
2906 
2907 // NEON 2 vector register instructions.
2908 #define NEON_2VREG_MACRO_LIST(V) \
2909   V(abs, Abs)                    \
2910   V(addp, Addp)                  \
2911   V(addv, Addv)                  \
2912   V(aesd, Aesd)                  \
2913   V(aese, Aese)                  \
2914   V(aesimc, Aesimc)              \
2915   V(aesmc, Aesmc)                \
2916   V(cls, Cls)                    \
2917   V(clz, Clz)                    \
2918   V(cnt, Cnt)                    \
2919   V(fabs, Fabs)                  \
2920   V(faddp, Faddp)                \
2921   V(fcvtas, Fcvtas)              \
2922   V(fcvtau, Fcvtau)              \
2923   V(fcvtms, Fcvtms)              \
2924   V(fcvtmu, Fcvtmu)              \
2925   V(fcvtns, Fcvtns)              \
2926   V(fcvtnu, Fcvtnu)              \
2927   V(fcvtps, Fcvtps)              \
2928   V(fcvtpu, Fcvtpu)              \
2929   V(fmaxnmp, Fmaxnmp)            \
2930   V(fmaxnmv, Fmaxnmv)            \
2931   V(fmaxp, Fmaxp)                \
2932   V(fmaxv, Fmaxv)                \
2933   V(fminnmp, Fminnmp)            \
2934   V(fminnmv, Fminnmv)            \
2935   V(fminp, Fminp)                \
2936   V(fminv, Fminv)                \
2937   V(fneg, Fneg)                  \
2938   V(frecpe, Frecpe)              \
2939   V(frecpx, Frecpx)              \
2940   V(frint32x, Frint32x)          \
2941   V(frint32z, Frint32z)          \
2942   V(frint64x, Frint64x)          \
2943   V(frint64z, Frint64z)          \
2944   V(frinta, Frinta)              \
2945   V(frinti, Frinti)              \
2946   V(frintm, Frintm)              \
2947   V(frintn, Frintn)              \
2948   V(frintp, Frintp)              \
2949   V(frintx, Frintx)              \
2950   V(frintz, Frintz)              \
2951   V(frsqrte, Frsqrte)            \
2952   V(fsqrt, Fsqrt)                \
2953   V(mov, Mov)                    \
2954   V(mvn, Mvn)                    \
2955   V(neg, Neg)                    \
2956   V(not_, Not)                   \
2957   V(rbit, Rbit)                  \
2958   V(rev16, Rev16)                \
2959   V(rev32, Rev32)                \
2960   V(rev64, Rev64)                \
2961   V(sadalp, Sadalp)              \
2962   V(saddlp, Saddlp)              \
2963   V(saddlv, Saddlv)              \
2964   V(sha1h, Sha1h)                \
2965   V(sha1su1, Sha1su1)            \
2966   V(sha256su0, Sha256su0)        \
2967   V(sha512su0, Sha512su0)        \
2968   V(sm4e, Sm4e)                  \
2969   V(smaxv, Smaxv)                \
2970   V(sminv, Sminv)                \
2971   V(sqabs, Sqabs)                \
2972   V(sqneg, Sqneg)                \
2973   V(sqxtn, Sqxtn)                \
2974   V(sqxtn2, Sqxtn2)              \
2975   V(sqxtun, Sqxtun)              \
2976   V(sqxtun2, Sqxtun2)            \
2977   V(suqadd, Suqadd)              \
2978   V(sxtl, Sxtl)                  \
2979   V(sxtl2, Sxtl2)                \
2980   V(uadalp, Uadalp)              \
2981   V(uaddlp, Uaddlp)              \
2982   V(uaddlv, Uaddlv)              \
2983   V(umaxv, Umaxv)                \
2984   V(uminv, Uminv)                \
2985   V(uqxtn, Uqxtn)                \
2986   V(uqxtn2, Uqxtn2)              \
2987   V(urecpe, Urecpe)              \
2988   V(ursqrte, Ursqrte)            \
2989   V(usqadd, Usqadd)              \
2990   V(uxtl, Uxtl)                  \
2991   V(uxtl2, Uxtl2)                \
2992   V(xtn, Xtn)                    \
2993   V(xtn2, Xtn2)
2994 
2995 #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)                \
2996   void MASM(const VRegister& vd, const VRegister& vn) { \
2997     VIXL_ASSERT(allow_macro_instructions_);             \
2998     SingleEmissionCheckScope guard(this);               \
2999     ASM(vd, vn);                                        \
3000   }
NEON_2VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)3001   NEON_2VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
3002 #undef DEFINE_MACRO_ASM_FUNC
3003 
3004 // NEON 2 vector register with immediate instructions.
3005 #define NEON_2VREG_FPIMM_MACRO_LIST(V) \
3006   V(fcmeq, Fcmeq)                      \
3007   V(fcmge, Fcmge)                      \
3008   V(fcmgt, Fcmgt)                      \
3009   V(fcmle, Fcmle)                      \
3010   V(fcmlt, Fcmlt)
3011 
3012 #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)                            \
3013   void MASM(const VRegister& vd, const VRegister& vn, double imm) { \
3014     VIXL_ASSERT(allow_macro_instructions_);                         \
3015     SingleEmissionCheckScope guard(this);                           \
3016     ASM(vd, vn, imm);                                               \
3017   }
3018   NEON_2VREG_FPIMM_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
3019 #undef DEFINE_MACRO_ASM_FUNC
3020 
3021 // NEON by element instructions.
3022 #define NEON_BYELEMENT_MACRO_LIST(V) \
3023   V(fmul, Fmul)                      \
3024   V(fmla, Fmla)                      \
3025   V(fmlal, Fmlal)                    \
3026   V(fmlal2, Fmlal2)                  \
3027   V(fmls, Fmls)                      \
3028   V(fmlsl, Fmlsl)                    \
3029   V(fmlsl2, Fmlsl2)                  \
3030   V(fmulx, Fmulx)                    \
3031   V(mul, Mul)                        \
3032   V(mla, Mla)                        \
3033   V(mls, Mls)                        \
3034   V(sqdmulh, Sqdmulh)                \
3035   V(sqrdmulh, Sqrdmulh)              \
3036   V(sdot, Sdot)                      \
3037   V(sqrdmlah, Sqrdmlah)              \
3038   V(udot, Udot)                      \
3039   V(sqrdmlsh, Sqrdmlsh)              \
3040   V(sqdmull, Sqdmull)                \
3041   V(sqdmull2, Sqdmull2)              \
3042   V(sqdmlal, Sqdmlal)                \
3043   V(sqdmlal2, Sqdmlal2)              \
3044   V(sqdmlsl, Sqdmlsl)                \
3045   V(sqdmlsl2, Sqdmlsl2)              \
3046   V(smull, Smull)                    \
3047   V(smull2, Smull2)                  \
3048   V(smlal, Smlal)                    \
3049   V(smlal2, Smlal2)                  \
3050   V(smlsl, Smlsl)                    \
3051   V(smlsl2, Smlsl2)                  \
3052   V(umull, Umull)                    \
3053   V(umull2, Umull2)                  \
3054   V(umlal, Umlal)                    \
3055   V(umlal2, Umlal2)                  \
3056   V(umlsl, Umlsl)                    \
3057   V(umlsl2, Umlsl2)                  \
3058   V(sudot, Sudot)                    \
3059   V(usdot, Usdot)                    \
3060   V(sm3tt1a, Sm3tt1a)                \
3061   V(sm3tt1b, Sm3tt1b)                \
3062   V(sm3tt2a, Sm3tt2a)                \
3063   V(sm3tt2b, Sm3tt2b)
3064 
3065 
3066 #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)    \
3067   void MASM(const VRegister& vd,            \
3068             const VRegister& vn,            \
3069             const VRegister& vm,            \
3070             int vm_index) {                 \
3071     VIXL_ASSERT(allow_macro_instructions_); \
3072     SingleEmissionCheckScope guard(this);   \
3073     ASM(vd, vn, vm, vm_index);              \
3074   }
3075   NEON_BYELEMENT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
3076 #undef DEFINE_MACRO_ASM_FUNC
3077 
3078 #define NEON_2VREG_SHIFT_MACRO_LIST(V) \
3079   V(rshrn, Rshrn)                      \
3080   V(rshrn2, Rshrn2)                    \
3081   V(shl, Shl)                          \
3082   V(shll, Shll)                        \
3083   V(shll2, Shll2)                      \
3084   V(shrn, Shrn)                        \
3085   V(shrn2, Shrn2)                      \
3086   V(sli, Sli)                          \
3087   V(sqrshrn, Sqrshrn)                  \
3088   V(sqrshrn2, Sqrshrn2)                \
3089   V(sqrshrun, Sqrshrun)                \
3090   V(sqrshrun2, Sqrshrun2)              \
3091   V(sqshl, Sqshl)                      \
3092   V(sqshlu, Sqshlu)                    \
3093   V(sqshrn, Sqshrn)                    \
3094   V(sqshrn2, Sqshrn2)                  \
3095   V(sqshrun, Sqshrun)                  \
3096   V(sqshrun2, Sqshrun2)                \
3097   V(sri, Sri)                          \
3098   V(srshr, Srshr)                      \
3099   V(srsra, Srsra)                      \
3100   V(sshr, Sshr)                        \
3101   V(ssra, Ssra)                        \
3102   V(uqrshrn, Uqrshrn)                  \
3103   V(uqrshrn2, Uqrshrn2)                \
3104   V(uqshl, Uqshl)                      \
3105   V(uqshrn, Uqshrn)                    \
3106   V(uqshrn2, Uqshrn2)                  \
3107   V(urshr, Urshr)                      \
3108   V(ursra, Ursra)                      \
3109   V(ushr, Ushr)                        \
3110   V(usra, Usra)
3111 
3112 #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)                           \
3113   void MASM(const VRegister& vd, const VRegister& vn, int shift) { \
3114     VIXL_ASSERT(allow_macro_instructions_);                        \
3115     SingleEmissionCheckScope guard(this);                          \
3116     ASM(vd, vn, shift);                                            \
3117   }
3118   NEON_2VREG_SHIFT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
3119 #undef DEFINE_MACRO_ASM_FUNC
3120 
3121 #define NEON_2VREG_SHIFT_LONG_MACRO_LIST(V) \
3122   V(shll, sshll, Sshll)                     \
3123   V(shll, ushll, Ushll)                     \
3124   V(shll2, sshll2, Sshll2)                  \
3125   V(shll2, ushll2, Ushll2)
3126 
3127 #define DEFINE_MACRO_ASM_FUNC(ASM1, ASM2, MASM)                    \
3128   void MASM(const VRegister& vd, const VRegister& vn, int shift) { \
3129     VIXL_ASSERT(allow_macro_instructions_);                        \
3130     SingleEmissionCheckScope guard(this);                          \
3131     if (vn.GetLaneSizeInBits() == static_cast<unsigned>(shift)) {  \
3132       ASM1(vd, vn, shift);                                         \
3133     } else {                                                       \
3134       ASM2(vd, vn, shift);                                         \
3135     }                                                              \
3136   }
3137   NEON_2VREG_SHIFT_LONG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
3138 #undef DEFINE_MACRO_ASM_FUNC
3139 
3140 // SVE 3 vector register instructions.
3141 #define SVE_3VREG_COMMUTATIVE_MACRO_LIST(V) \
3142   V(add, Add)                               \
3143   V(and_, And)                              \
3144   V(eor, Eor)                               \
3145   V(mul, Mul)                               \
3146   V(orr, Orr)                               \
3147   V(sabd, Sabd)                             \
3148   V(shadd, Shadd)                           \
3149   V(smax, Smax)                             \
3150   V(smin, Smin)                             \
3151   V(smulh, Smulh)                           \
3152   V(sqadd, Sqadd)                           \
3153   V(srhadd, Srhadd)                         \
3154   V(uabd, Uabd)                             \
3155   V(uhadd, Uhadd)                           \
3156   V(umax, Umax)                             \
3157   V(umin, Umin)                             \
3158   V(umulh, Umulh)                           \
3159   V(uqadd, Uqadd)                           \
3160   V(urhadd, Urhadd)
3161 
3162 #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)          \
3163   void MASM(const ZRegister& zd,                  \
3164             const PRegisterM& pg,                 \
3165             const ZRegister& zn,                  \
3166             const ZRegister& zm) {                \
3167     VIXL_ASSERT(allow_macro_instructions_);       \
3168     if (zd.Aliases(zn)) {                         \
3169       SingleEmissionCheckScope guard(this);       \
3170       ASM(zd, pg, zd, zm);                        \
3171     } else if (zd.Aliases(zm)) {                  \
3172       SingleEmissionCheckScope guard(this);       \
3173       ASM(zd, pg, zd, zn);                        \
3174     } else {                                      \
3175       MovprfxHelperScope guard(this, zd, pg, zn); \
3176       ASM(zd, pg, zd, zm);                        \
3177     }                                             \
3178   }
3179   SVE_3VREG_COMMUTATIVE_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
3180 #undef DEFINE_MACRO_ASM_FUNC
3181 
3182   void Bcax(const VRegister& vd,
3183             const VRegister& vn,
3184             const VRegister& vm,
3185             const VRegister& va) {
3186     VIXL_ASSERT(allow_macro_instructions_);
3187     SingleEmissionCheckScope guard(this);
3188     bcax(vd, vn, vm, va);
3189   }
3190   void Bic(const VRegister& vd, const int imm8, const int left_shift = 0) {
3191     VIXL_ASSERT(allow_macro_instructions_);
3192     SingleEmissionCheckScope guard(this);
3193     bic(vd, imm8, left_shift);
3194   }
Cmeq(const VRegister & vd,const VRegister & vn,int imm)3195   void Cmeq(const VRegister& vd, const VRegister& vn, int imm) {
3196     VIXL_ASSERT(allow_macro_instructions_);
3197     SingleEmissionCheckScope guard(this);
3198     cmeq(vd, vn, imm);
3199   }
Cmge(const VRegister & vd,const VRegister & vn,int imm)3200   void Cmge(const VRegister& vd, const VRegister& vn, int imm) {
3201     VIXL_ASSERT(allow_macro_instructions_);
3202     SingleEmissionCheckScope guard(this);
3203     cmge(vd, vn, imm);
3204   }
Cmgt(const VRegister & vd,const VRegister & vn,int imm)3205   void Cmgt(const VRegister& vd, const VRegister& vn, int imm) {
3206     VIXL_ASSERT(allow_macro_instructions_);
3207     SingleEmissionCheckScope guard(this);
3208     cmgt(vd, vn, imm);
3209   }
Cmle(const VRegister & vd,const VRegister & vn,int imm)3210   void Cmle(const VRegister& vd, const VRegister& vn, int imm) {
3211     VIXL_ASSERT(allow_macro_instructions_);
3212     SingleEmissionCheckScope guard(this);
3213     cmle(vd, vn, imm);
3214   }
Cmlt(const VRegister & vd,const VRegister & vn,int imm)3215   void Cmlt(const VRegister& vd, const VRegister& vn, int imm) {
3216     VIXL_ASSERT(allow_macro_instructions_);
3217     SingleEmissionCheckScope guard(this);
3218     cmlt(vd, vn, imm);
3219   }
Dup(const VRegister & vd,const VRegister & vn,int index)3220   void Dup(const VRegister& vd, const VRegister& vn, int index) {
3221     VIXL_ASSERT(allow_macro_instructions_);
3222     SingleEmissionCheckScope guard(this);
3223     dup(vd, vn, index);
3224   }
Dup(const VRegister & vd,const Register & rn)3225   void Dup(const VRegister& vd, const Register& rn) {
3226     VIXL_ASSERT(allow_macro_instructions_);
3227     SingleEmissionCheckScope guard(this);
3228     dup(vd, rn);
3229   }
Eor3(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)3230   void Eor3(const VRegister& vd,
3231             const VRegister& vn,
3232             const VRegister& vm,
3233             const VRegister& va) {
3234     VIXL_ASSERT(allow_macro_instructions_);
3235     SingleEmissionCheckScope guard(this);
3236     eor3(vd, vn, vm, va);
3237   }
Ext(const VRegister & vd,const VRegister & vn,const VRegister & vm,int index)3238   void Ext(const VRegister& vd,
3239            const VRegister& vn,
3240            const VRegister& vm,
3241            int index) {
3242     VIXL_ASSERT(allow_macro_instructions_);
3243     SingleEmissionCheckScope guard(this);
3244     ext(vd, vn, vm, index);
3245   }
Fcadd(const VRegister & vd,const VRegister & vn,const VRegister & vm,int rot)3246   void Fcadd(const VRegister& vd,
3247              const VRegister& vn,
3248              const VRegister& vm,
3249              int rot) {
3250     VIXL_ASSERT(allow_macro_instructions_);
3251     SingleEmissionCheckScope guard(this);
3252     fcadd(vd, vn, vm, rot);
3253   }
Fcmla(const VRegister & vd,const VRegister & vn,const VRegister & vm,int vm_index,int rot)3254   void Fcmla(const VRegister& vd,
3255              const VRegister& vn,
3256              const VRegister& vm,
3257              int vm_index,
3258              int rot) {
3259     VIXL_ASSERT(allow_macro_instructions_);
3260     SingleEmissionCheckScope guard(this);
3261     fcmla(vd, vn, vm, vm_index, rot);
3262   }
Fcmla(const VRegister & vd,const VRegister & vn,const VRegister & vm,int rot)3263   void Fcmla(const VRegister& vd,
3264              const VRegister& vn,
3265              const VRegister& vm,
3266              int rot) {
3267     VIXL_ASSERT(allow_macro_instructions_);
3268     SingleEmissionCheckScope guard(this);
3269     fcmla(vd, vn, vm, rot);
3270   }
Ins(const VRegister & vd,int vd_index,const VRegister & vn,int vn_index)3271   void Ins(const VRegister& vd,
3272            int vd_index,
3273            const VRegister& vn,
3274            int vn_index) {
3275     VIXL_ASSERT(allow_macro_instructions_);
3276     SingleEmissionCheckScope guard(this);
3277     ins(vd, vd_index, vn, vn_index);
3278   }
Ins(const VRegister & vd,int vd_index,const Register & rn)3279   void Ins(const VRegister& vd, int vd_index, const Register& rn) {
3280     VIXL_ASSERT(allow_macro_instructions_);
3281     SingleEmissionCheckScope guard(this);
3282     ins(vd, vd_index, rn);
3283   }
Ld1(const VRegister & vt,const MemOperand & src)3284   void Ld1(const VRegister& vt, const MemOperand& src) {
3285     VIXL_ASSERT(allow_macro_instructions_);
3286     SingleEmissionCheckScope guard(this);
3287     ld1(vt, src);
3288   }
Ld1(const VRegister & vt,const VRegister & vt2,const MemOperand & src)3289   void Ld1(const VRegister& vt, const VRegister& vt2, const MemOperand& src) {
3290     VIXL_ASSERT(allow_macro_instructions_);
3291     SingleEmissionCheckScope guard(this);
3292     ld1(vt, vt2, src);
3293   }
Ld1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & src)3294   void Ld1(const VRegister& vt,
3295            const VRegister& vt2,
3296            const VRegister& vt3,
3297            const MemOperand& src) {
3298     VIXL_ASSERT(allow_macro_instructions_);
3299     SingleEmissionCheckScope guard(this);
3300     ld1(vt, vt2, vt3, src);
3301   }
Ld1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & src)3302   void Ld1(const VRegister& vt,
3303            const VRegister& vt2,
3304            const VRegister& vt3,
3305            const VRegister& vt4,
3306            const MemOperand& src) {
3307     VIXL_ASSERT(allow_macro_instructions_);
3308     SingleEmissionCheckScope guard(this);
3309     ld1(vt, vt2, vt3, vt4, src);
3310   }
Ld1(const VRegister & vt,int lane,const MemOperand & src)3311   void Ld1(const VRegister& vt, int lane, const MemOperand& src) {
3312     VIXL_ASSERT(allow_macro_instructions_);
3313     SingleEmissionCheckScope guard(this);
3314     ld1(vt, lane, src);
3315   }
Ld1r(const VRegister & vt,const MemOperand & src)3316   void Ld1r(const VRegister& vt, const MemOperand& src) {
3317     VIXL_ASSERT(allow_macro_instructions_);
3318     SingleEmissionCheckScope guard(this);
3319     ld1r(vt, src);
3320   }
Ld2(const VRegister & vt,const VRegister & vt2,const MemOperand & src)3321   void Ld2(const VRegister& vt, const VRegister& vt2, const MemOperand& src) {
3322     VIXL_ASSERT(allow_macro_instructions_);
3323     SingleEmissionCheckScope guard(this);
3324     ld2(vt, vt2, src);
3325   }
Ld2(const VRegister & vt,const VRegister & vt2,int lane,const MemOperand & src)3326   void Ld2(const VRegister& vt,
3327            const VRegister& vt2,
3328            int lane,
3329            const MemOperand& src) {
3330     VIXL_ASSERT(allow_macro_instructions_);
3331     SingleEmissionCheckScope guard(this);
3332     ld2(vt, vt2, lane, src);
3333   }
Ld2r(const VRegister & vt,const VRegister & vt2,const MemOperand & src)3334   void Ld2r(const VRegister& vt, const VRegister& vt2, const MemOperand& src) {
3335     VIXL_ASSERT(allow_macro_instructions_);
3336     SingleEmissionCheckScope guard(this);
3337     ld2r(vt, vt2, src);
3338   }
Ld3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & src)3339   void Ld3(const VRegister& vt,
3340            const VRegister& vt2,
3341            const VRegister& vt3,
3342            const MemOperand& src) {
3343     VIXL_ASSERT(allow_macro_instructions_);
3344     SingleEmissionCheckScope guard(this);
3345     ld3(vt, vt2, vt3, src);
3346   }
Ld3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,int lane,const MemOperand & src)3347   void Ld3(const VRegister& vt,
3348            const VRegister& vt2,
3349            const VRegister& vt3,
3350            int lane,
3351            const MemOperand& src) {
3352     VIXL_ASSERT(allow_macro_instructions_);
3353     SingleEmissionCheckScope guard(this);
3354     ld3(vt, vt2, vt3, lane, src);
3355   }
Ld3r(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & src)3356   void Ld3r(const VRegister& vt,
3357             const VRegister& vt2,
3358             const VRegister& vt3,
3359             const MemOperand& src) {
3360     VIXL_ASSERT(allow_macro_instructions_);
3361     SingleEmissionCheckScope guard(this);
3362     ld3r(vt, vt2, vt3, src);
3363   }
Ld4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & src)3364   void Ld4(const VRegister& vt,
3365            const VRegister& vt2,
3366            const VRegister& vt3,
3367            const VRegister& vt4,
3368            const MemOperand& src) {
3369     VIXL_ASSERT(allow_macro_instructions_);
3370     SingleEmissionCheckScope guard(this);
3371     ld4(vt, vt2, vt3, vt4, src);
3372   }
Ld4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,int lane,const MemOperand & src)3373   void Ld4(const VRegister& vt,
3374            const VRegister& vt2,
3375            const VRegister& vt3,
3376            const VRegister& vt4,
3377            int lane,
3378            const MemOperand& src) {
3379     VIXL_ASSERT(allow_macro_instructions_);
3380     SingleEmissionCheckScope guard(this);
3381     ld4(vt, vt2, vt3, vt4, lane, src);
3382   }
Ld4r(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & src)3383   void Ld4r(const VRegister& vt,
3384             const VRegister& vt2,
3385             const VRegister& vt3,
3386             const VRegister& vt4,
3387             const MemOperand& src) {
3388     VIXL_ASSERT(allow_macro_instructions_);
3389     SingleEmissionCheckScope guard(this);
3390     ld4r(vt, vt2, vt3, vt4, src);
3391   }
Mov(const VRegister & vd,int vd_index,const VRegister & vn,int vn_index)3392   void Mov(const VRegister& vd,
3393            int vd_index,
3394            const VRegister& vn,
3395            int vn_index) {
3396     VIXL_ASSERT(allow_macro_instructions_);
3397     SingleEmissionCheckScope guard(this);
3398     mov(vd, vd_index, vn, vn_index);
3399   }
Mov(const VRegister & vd,const VRegister & vn,int index)3400   void Mov(const VRegister& vd, const VRegister& vn, int index) {
3401     VIXL_ASSERT(allow_macro_instructions_);
3402     SingleEmissionCheckScope guard(this);
3403     mov(vd, vn, index);
3404   }
Mov(const VRegister & vd,int vd_index,const Register & rn)3405   void Mov(const VRegister& vd, int vd_index, const Register& rn) {
3406     VIXL_ASSERT(allow_macro_instructions_);
3407     SingleEmissionCheckScope guard(this);
3408     mov(vd, vd_index, rn);
3409   }
Mov(const Register & rd,const VRegister & vn,int vn_index)3410   void Mov(const Register& rd, const VRegister& vn, int vn_index) {
3411     VIXL_ASSERT(allow_macro_instructions_);
3412     SingleEmissionCheckScope guard(this);
3413     mov(rd, vn, vn_index);
3414   }
3415   void Movi(const VRegister& vd,
3416             uint64_t imm,
3417             Shift shift = LSL,
3418             int shift_amount = 0);
3419   void Movi(const VRegister& vd, uint64_t hi, uint64_t lo);
3420   void Mvni(const VRegister& vd,
3421             const int imm8,
3422             Shift shift = LSL,
3423             const int shift_amount = 0) {
3424     VIXL_ASSERT(allow_macro_instructions_);
3425     SingleEmissionCheckScope guard(this);
3426     mvni(vd, imm8, shift, shift_amount);
3427   }
3428   void Orr(const VRegister& vd, const int imm8, const int left_shift = 0) {
3429     VIXL_ASSERT(allow_macro_instructions_);
3430     SingleEmissionCheckScope guard(this);
3431     orr(vd, imm8, left_shift);
3432   }
3433   void Scvtf(const VRegister& vd, const VRegister& vn, int fbits = 0) {
3434     VIXL_ASSERT(allow_macro_instructions_);
3435     SingleEmissionCheckScope guard(this);
3436     scvtf(vd, vn, fbits);
3437   }
3438   void Ucvtf(const VRegister& vd, const VRegister& vn, int fbits = 0) {
3439     VIXL_ASSERT(allow_macro_instructions_);
3440     SingleEmissionCheckScope guard(this);
3441     ucvtf(vd, vn, fbits);
3442   }
3443   void Fcvtzs(const VRegister& vd, const VRegister& vn, int fbits = 0) {
3444     VIXL_ASSERT(allow_macro_instructions_);
3445     SingleEmissionCheckScope guard(this);
3446     fcvtzs(vd, vn, fbits);
3447   }
3448   void Fcvtzu(const VRegister& vd, const VRegister& vn, int fbits = 0) {
3449     VIXL_ASSERT(allow_macro_instructions_);
3450     SingleEmissionCheckScope guard(this);
3451     fcvtzu(vd, vn, fbits);
3452   }
St1(const VRegister & vt,const MemOperand & dst)3453   void St1(const VRegister& vt, const MemOperand& dst) {
3454     VIXL_ASSERT(allow_macro_instructions_);
3455     SingleEmissionCheckScope guard(this);
3456     st1(vt, dst);
3457   }
St1(const VRegister & vt,const VRegister & vt2,const MemOperand & dst)3458   void St1(const VRegister& vt, const VRegister& vt2, const MemOperand& dst) {
3459     VIXL_ASSERT(allow_macro_instructions_);
3460     SingleEmissionCheckScope guard(this);
3461     st1(vt, vt2, dst);
3462   }
St1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & dst)3463   void St1(const VRegister& vt,
3464            const VRegister& vt2,
3465            const VRegister& vt3,
3466            const MemOperand& dst) {
3467     VIXL_ASSERT(allow_macro_instructions_);
3468     SingleEmissionCheckScope guard(this);
3469     st1(vt, vt2, vt3, dst);
3470   }
St1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & dst)3471   void St1(const VRegister& vt,
3472            const VRegister& vt2,
3473            const VRegister& vt3,
3474            const VRegister& vt4,
3475            const MemOperand& dst) {
3476     VIXL_ASSERT(allow_macro_instructions_);
3477     SingleEmissionCheckScope guard(this);
3478     st1(vt, vt2, vt3, vt4, dst);
3479   }
St1(const VRegister & vt,int lane,const MemOperand & dst)3480   void St1(const VRegister& vt, int lane, const MemOperand& dst) {
3481     VIXL_ASSERT(allow_macro_instructions_);
3482     SingleEmissionCheckScope guard(this);
3483     st1(vt, lane, dst);
3484   }
St2(const VRegister & vt,const VRegister & vt2,const MemOperand & dst)3485   void St2(const VRegister& vt, const VRegister& vt2, const MemOperand& dst) {
3486     VIXL_ASSERT(allow_macro_instructions_);
3487     SingleEmissionCheckScope guard(this);
3488     st2(vt, vt2, dst);
3489   }
St3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & dst)3490   void St3(const VRegister& vt,
3491            const VRegister& vt2,
3492            const VRegister& vt3,
3493            const MemOperand& dst) {
3494     VIXL_ASSERT(allow_macro_instructions_);
3495     SingleEmissionCheckScope guard(this);
3496     st3(vt, vt2, vt3, dst);
3497   }
St4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & dst)3498   void St4(const VRegister& vt,
3499            const VRegister& vt2,
3500            const VRegister& vt3,
3501            const VRegister& vt4,
3502            const MemOperand& dst) {
3503     VIXL_ASSERT(allow_macro_instructions_);
3504     SingleEmissionCheckScope guard(this);
3505     st4(vt, vt2, vt3, vt4, dst);
3506   }
St2(const VRegister & vt,const VRegister & vt2,int lane,const MemOperand & dst)3507   void St2(const VRegister& vt,
3508            const VRegister& vt2,
3509            int lane,
3510            const MemOperand& dst) {
3511     VIXL_ASSERT(allow_macro_instructions_);
3512     SingleEmissionCheckScope guard(this);
3513     st2(vt, vt2, lane, dst);
3514   }
St3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,int lane,const MemOperand & dst)3515   void St3(const VRegister& vt,
3516            const VRegister& vt2,
3517            const VRegister& vt3,
3518            int lane,
3519            const MemOperand& dst) {
3520     VIXL_ASSERT(allow_macro_instructions_);
3521     SingleEmissionCheckScope guard(this);
3522     st3(vt, vt2, vt3, lane, dst);
3523   }
St4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,int lane,const MemOperand & dst)3524   void St4(const VRegister& vt,
3525            const VRegister& vt2,
3526            const VRegister& vt3,
3527            const VRegister& vt4,
3528            int lane,
3529            const MemOperand& dst) {
3530     VIXL_ASSERT(allow_macro_instructions_);
3531     SingleEmissionCheckScope guard(this);
3532     st4(vt, vt2, vt3, vt4, lane, dst);
3533   }
Sm3ss1(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)3534   void Sm3ss1(const VRegister& vd,
3535               const VRegister& vn,
3536               const VRegister& vm,
3537               const VRegister& va) {
3538     VIXL_ASSERT(allow_macro_instructions_);
3539     SingleEmissionCheckScope guard(this);
3540     sm3ss1(vd, vn, vm, va);
3541   }
Smov(const Register & rd,const VRegister & vn,int vn_index)3542   void Smov(const Register& rd, const VRegister& vn, int vn_index) {
3543     VIXL_ASSERT(allow_macro_instructions_);
3544     SingleEmissionCheckScope guard(this);
3545     smov(rd, vn, vn_index);
3546   }
Umov(const Register & rd,const VRegister & vn,int vn_index)3547   void Umov(const Register& rd, const VRegister& vn, int vn_index) {
3548     VIXL_ASSERT(allow_macro_instructions_);
3549     SingleEmissionCheckScope guard(this);
3550     umov(rd, vn, vn_index);
3551   }
Xar(const VRegister & vd,const VRegister & vn,const VRegister & vm,int rotate)3552   void Xar(const VRegister& vd,
3553            const VRegister& vn,
3554            const VRegister& vm,
3555            int rotate) {
3556     VIXL_ASSERT(allow_macro_instructions_);
3557     SingleEmissionCheckScope guard(this);
3558     xar(vd, vn, vm, rotate);
3559   }
Crc32b(const Register & rd,const Register & rn,const Register & rm)3560   void Crc32b(const Register& rd, const Register& rn, const Register& rm) {
3561     VIXL_ASSERT(allow_macro_instructions_);
3562     SingleEmissionCheckScope guard(this);
3563     crc32b(rd, rn, rm);
3564   }
Crc32h(const Register & rd,const Register & rn,const Register & rm)3565   void Crc32h(const Register& rd, const Register& rn, const Register& rm) {
3566     VIXL_ASSERT(allow_macro_instructions_);
3567     SingleEmissionCheckScope guard(this);
3568     crc32h(rd, rn, rm);
3569   }
Crc32w(const Register & rd,const Register & rn,const Register & rm)3570   void Crc32w(const Register& rd, const Register& rn, const Register& rm) {
3571     VIXL_ASSERT(allow_macro_instructions_);
3572     SingleEmissionCheckScope guard(this);
3573     crc32w(rd, rn, rm);
3574   }
Crc32x(const Register & rd,const Register & rn,const Register & rm)3575   void Crc32x(const Register& rd, const Register& rn, const Register& rm) {
3576     VIXL_ASSERT(allow_macro_instructions_);
3577     SingleEmissionCheckScope guard(this);
3578     crc32x(rd, rn, rm);
3579   }
Crc32cb(const Register & rd,const Register & rn,const Register & rm)3580   void Crc32cb(const Register& rd, const Register& rn, const Register& rm) {
3581     VIXL_ASSERT(allow_macro_instructions_);
3582     SingleEmissionCheckScope guard(this);
3583     crc32cb(rd, rn, rm);
3584   }
Crc32ch(const Register & rd,const Register & rn,const Register & rm)3585   void Crc32ch(const Register& rd, const Register& rn, const Register& rm) {
3586     VIXL_ASSERT(allow_macro_instructions_);
3587     SingleEmissionCheckScope guard(this);
3588     crc32ch(rd, rn, rm);
3589   }
Crc32cw(const Register & rd,const Register & rn,const Register & rm)3590   void Crc32cw(const Register& rd, const Register& rn, const Register& rm) {
3591     VIXL_ASSERT(allow_macro_instructions_);
3592     SingleEmissionCheckScope guard(this);
3593     crc32cw(rd, rn, rm);
3594   }
Crc32cx(const Register & rd,const Register & rn,const Register & rm)3595   void Crc32cx(const Register& rd, const Register& rn, const Register& rm) {
3596     VIXL_ASSERT(allow_macro_instructions_);
3597     SingleEmissionCheckScope guard(this);
3598     crc32cx(rd, rn, rm);
3599   }
3600 
3601   // Scalable Vector Extensions.
Abs(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3602   void Abs(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
3603     VIXL_ASSERT(allow_macro_instructions_);
3604     SingleEmissionCheckScope guard(this);
3605     abs(zd, pg, zn);
3606   }
Add(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)3607   void Add(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
3608     VIXL_ASSERT(allow_macro_instructions_);
3609     SingleEmissionCheckScope guard(this);
3610     add(zd, zn, zm);
3611   }
Add(const ZRegister & zd,const ZRegister & zn,IntegerOperand imm)3612   void Add(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm) {
3613     VIXL_ASSERT(allow_macro_instructions_);
3614     AddSubHelper(kAddImmediate, zd, zn, imm);
3615   }
3616   void Addpl(const Register& xd, const Register& xn, int64_t multiplier);
3617   void Addvl(const Register& xd, const Register& xn, int64_t multiplier);
3618   // Note that unlike the core ISA, SVE's `adr` is not PC-relative.
Adr(const ZRegister & zd,const SVEMemOperand & addr)3619   void Adr(const ZRegister& zd, const SVEMemOperand& addr) {
3620     VIXL_ASSERT(allow_macro_instructions_);
3621     SingleEmissionCheckScope guard(this);
3622     adr(zd, addr);
3623   }
And(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)3624   void And(const PRegisterWithLaneSize& pd,
3625            const PRegisterZ& pg,
3626            const PRegisterWithLaneSize& pn,
3627            const PRegisterWithLaneSize& pm) {
3628     VIXL_ASSERT(allow_macro_instructions_);
3629     SingleEmissionCheckScope guard(this);
3630     and_(pd, pg, pn, pm);
3631   }
And(const ZRegister & zd,const ZRegister & zn,uint64_t imm)3632   void And(const ZRegister& zd, const ZRegister& zn, uint64_t imm) {
3633     VIXL_ASSERT(allow_macro_instructions_);
3634     SingleEmissionCheckScope guard(this);
3635     if (IsImmLogical(imm, zd.GetLaneSizeInBits())) {
3636       and_(zd, zn, imm);
3637     } else {
3638       // TODO: Synthesise the immediate once 'Mov' is implemented.
3639       VIXL_UNIMPLEMENTED();
3640     }
3641   }
And(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)3642   void And(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
3643     VIXL_ASSERT(allow_macro_instructions_);
3644     VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
3645     SingleEmissionCheckScope guard(this);
3646     and_(zd.VnD(), zn.VnD(), zm.VnD());
3647   }
Ands(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)3648   void Ands(const PRegisterWithLaneSize& pd,
3649             const PRegisterZ& pg,
3650             const PRegisterWithLaneSize& pn,
3651             const PRegisterWithLaneSize& pm) {
3652     VIXL_ASSERT(allow_macro_instructions_);
3653     SingleEmissionCheckScope guard(this);
3654     ands(pd, pg, pn, pm);
3655   }
Andv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)3656   void Andv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
3657     VIXL_ASSERT(allow_macro_instructions_);
3658     SingleEmissionCheckScope guard(this);
3659     andv(vd, pg, zn);
3660   }
Asr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)3661   void Asr(const ZRegister& zd,
3662            const PRegisterM& pg,
3663            const ZRegister& zn,
3664            int shift) {
3665     VIXL_ASSERT(allow_macro_instructions_);
3666     MovprfxHelperScope guard(this, zd, pg, zn);
3667     asr(zd, pg, zd, shift);
3668   }
3669   void Asr(const ZRegister& zd,
3670            const PRegisterM& pg,
3671            const ZRegister& zn,
3672            const ZRegister& zm);
Asr(const ZRegister & zd,const ZRegister & zn,int shift)3673   void Asr(const ZRegister& zd, const ZRegister& zn, int shift) {
3674     VIXL_ASSERT(allow_macro_instructions_);
3675     SingleEmissionCheckScope guard(this);
3676     asr(zd, zn, shift);
3677   }
Asr(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)3678   void Asr(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
3679     VIXL_ASSERT(allow_macro_instructions_);
3680     SingleEmissionCheckScope guard(this);
3681     asr(zd, zn, zm);
3682   }
Asrd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)3683   void Asrd(const ZRegister& zd,
3684             const PRegisterM& pg,
3685             const ZRegister& zn,
3686             int shift) {
3687     VIXL_ASSERT(allow_macro_instructions_);
3688     MovprfxHelperScope guard(this, zd, pg, zn);
3689     asrd(zd, pg, zd, shift);
3690   }
3691   void Bic(const ZRegister& zd,
3692            const PRegisterM& pg,
3693            const ZRegister& zn,
3694            const ZRegister& zm);
Bic(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)3695   void Bic(const PRegisterWithLaneSize& pd,
3696            const PRegisterZ& pg,
3697            const PRegisterWithLaneSize& pn,
3698            const PRegisterWithLaneSize& pm) {
3699     VIXL_ASSERT(allow_macro_instructions_);
3700     SingleEmissionCheckScope guard(this);
3701     bic(pd, pg, pn, pm);
3702   }
Bic(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)3703   void Bic(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
3704     VIXL_ASSERT(allow_macro_instructions_);
3705     VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
3706     SingleEmissionCheckScope guard(this);
3707     bic(zd.VnD(), zn.VnD(), zm.VnD());
3708   }
Bic(const ZRegister & zd,const ZRegister & zn,uint64_t imm)3709   void Bic(const ZRegister& zd, const ZRegister& zn, uint64_t imm) {
3710     VIXL_ASSERT(allow_macro_instructions_);
3711     SingleEmissionCheckScope guard(this);
3712     if (IsImmLogical(imm, zd.GetLaneSizeInBits())) {
3713       bic(zd, zn, imm);
3714     } else {
3715       // TODO: Synthesise the immediate once 'Mov' is implemented.
3716       VIXL_UNIMPLEMENTED();
3717     }
3718   }
Bics(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)3719   void Bics(const PRegisterWithLaneSize& pd,
3720             const PRegisterZ& pg,
3721             const PRegisterWithLaneSize& pn,
3722             const PRegisterWithLaneSize& pm) {
3723     VIXL_ASSERT(allow_macro_instructions_);
3724     SingleEmissionCheckScope guard(this);
3725     bics(pd, pg, pn, pm);
3726   }
Brka(const PRegisterWithLaneSize & pd,const PRegister & pg,const PRegisterWithLaneSize & pn)3727   void Brka(const PRegisterWithLaneSize& pd,
3728             const PRegister& pg,
3729             const PRegisterWithLaneSize& pn) {
3730     VIXL_ASSERT(allow_macro_instructions_);
3731     SingleEmissionCheckScope guard(this);
3732     brka(pd, pg, pn);
3733   }
Brkas(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn)3734   void Brkas(const PRegisterWithLaneSize& pd,
3735              const PRegisterZ& pg,
3736              const PRegisterWithLaneSize& pn) {
3737     VIXL_ASSERT(allow_macro_instructions_);
3738     SingleEmissionCheckScope guard(this);
3739     brkas(pd, pg, pn);
3740   }
Brkb(const PRegisterWithLaneSize & pd,const PRegister & pg,const PRegisterWithLaneSize & pn)3741   void Brkb(const PRegisterWithLaneSize& pd,
3742             const PRegister& pg,
3743             const PRegisterWithLaneSize& pn) {
3744     VIXL_ASSERT(allow_macro_instructions_);
3745     SingleEmissionCheckScope guard(this);
3746     brkb(pd, pg, pn);
3747   }
Brkbs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn)3748   void Brkbs(const PRegisterWithLaneSize& pd,
3749              const PRegisterZ& pg,
3750              const PRegisterWithLaneSize& pn) {
3751     VIXL_ASSERT(allow_macro_instructions_);
3752     SingleEmissionCheckScope guard(this);
3753     brkbs(pd, pg, pn);
3754   }
Brkn(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)3755   void Brkn(const PRegisterWithLaneSize& pd,
3756             const PRegisterZ& pg,
3757             const PRegisterWithLaneSize& pn,
3758             const PRegisterWithLaneSize& pm) {
3759     VIXL_ASSERT(allow_macro_instructions_);
3760     if (!pd.Aliases(pm)) {
3761       Mov(pd, pm);
3762     }
3763     SingleEmissionCheckScope guard(this);
3764     brkn(pd, pg, pn, pd);
3765   }
Brkns(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)3766   void Brkns(const PRegisterWithLaneSize& pd,
3767              const PRegisterZ& pg,
3768              const PRegisterWithLaneSize& pn,
3769              const PRegisterWithLaneSize& pm) {
3770     VIXL_ASSERT(allow_macro_instructions_);
3771     if (!pd.Aliases(pm)) {
3772       Mov(pd, pm);
3773     }
3774     SingleEmissionCheckScope guard(this);
3775     brkns(pd, pg, pn, pd);
3776   }
Brkpa(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)3777   void Brkpa(const PRegisterWithLaneSize& pd,
3778              const PRegisterZ& pg,
3779              const PRegisterWithLaneSize& pn,
3780              const PRegisterWithLaneSize& pm) {
3781     VIXL_ASSERT(allow_macro_instructions_);
3782     SingleEmissionCheckScope guard(this);
3783     brkpa(pd, pg, pn, pm);
3784   }
Brkpas(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)3785   void Brkpas(const PRegisterWithLaneSize& pd,
3786               const PRegisterZ& pg,
3787               const PRegisterWithLaneSize& pn,
3788               const PRegisterWithLaneSize& pm) {
3789     VIXL_ASSERT(allow_macro_instructions_);
3790     SingleEmissionCheckScope guard(this);
3791     brkpas(pd, pg, pn, pm);
3792   }
Brkpb(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)3793   void Brkpb(const PRegisterWithLaneSize& pd,
3794              const PRegisterZ& pg,
3795              const PRegisterWithLaneSize& pn,
3796              const PRegisterWithLaneSize& pm) {
3797     VIXL_ASSERT(allow_macro_instructions_);
3798     SingleEmissionCheckScope guard(this);
3799     brkpb(pd, pg, pn, pm);
3800   }
Brkpbs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)3801   void Brkpbs(const PRegisterWithLaneSize& pd,
3802               const PRegisterZ& pg,
3803               const PRegisterWithLaneSize& pn,
3804               const PRegisterWithLaneSize& pm) {
3805     VIXL_ASSERT(allow_macro_instructions_);
3806     SingleEmissionCheckScope guard(this);
3807     brkpbs(pd, pg, pn, pm);
3808   }
Clasta(const Register & rd,const PRegister & pg,const Register & rn,const ZRegister & zm)3809   void Clasta(const Register& rd,
3810               const PRegister& pg,
3811               const Register& rn,
3812               const ZRegister& zm) {
3813     VIXL_ASSERT(allow_macro_instructions_);
3814     SingleEmissionCheckScope guard(this);
3815     clasta(rd, pg, rn, zm);
3816   }
Clasta(const VRegister & vd,const PRegister & pg,const VRegister & vn,const ZRegister & zm)3817   void Clasta(const VRegister& vd,
3818               const PRegister& pg,
3819               const VRegister& vn,
3820               const ZRegister& zm) {
3821     VIXL_ASSERT(allow_macro_instructions_);
3822     SingleEmissionCheckScope guard(this);
3823     clasta(vd, pg, vn, zm);
3824   }
3825   void Clasta(const ZRegister& zd,
3826               const PRegister& pg,
3827               const ZRegister& zn,
3828               const ZRegister& zm);
Clastb(const Register & rd,const PRegister & pg,const Register & rn,const ZRegister & zm)3829   void Clastb(const Register& rd,
3830               const PRegister& pg,
3831               const Register& rn,
3832               const ZRegister& zm) {
3833     VIXL_ASSERT(allow_macro_instructions_);
3834     SingleEmissionCheckScope guard(this);
3835     clastb(rd, pg, rn, zm);
3836   }
Clastb(const VRegister & vd,const PRegister & pg,const VRegister & vn,const ZRegister & zm)3837   void Clastb(const VRegister& vd,
3838               const PRegister& pg,
3839               const VRegister& vn,
3840               const ZRegister& zm) {
3841     VIXL_ASSERT(allow_macro_instructions_);
3842     SingleEmissionCheckScope guard(this);
3843     clastb(vd, pg, vn, zm);
3844   }
3845   void Clastb(const ZRegister& zd,
3846               const PRegister& pg,
3847               const ZRegister& zn,
3848               const ZRegister& zm);
Cls(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3849   void Cls(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
3850     VIXL_ASSERT(allow_macro_instructions_);
3851     SingleEmissionCheckScope guard(this);
3852     cls(zd, pg, zn);
3853   }
Clz(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)3854   void Clz(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
3855     VIXL_ASSERT(allow_macro_instructions_);
3856     SingleEmissionCheckScope guard(this);
3857     clz(zd, pg, zn);
3858   }
Cmpeq(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3859   void Cmpeq(const PRegisterWithLaneSize& pd,
3860              const PRegisterZ& pg,
3861              const ZRegister& zn,
3862              const ZRegister& zm) {
3863     VIXL_ASSERT(allow_macro_instructions_);
3864     SingleEmissionCheckScope guard(this);
3865     cmpeq(pd, pg, zn, zm);
3866   }
Cmpeq(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,IntegerOperand imm)3867   void Cmpeq(const PRegisterWithLaneSize& pd,
3868              const PRegisterZ& pg,
3869              const ZRegister& zn,
3870              IntegerOperand imm) {
3871     VIXL_ASSERT(allow_macro_instructions_);
3872     int imm5;
3873     if (imm.TryEncodeAsIntNForLane<5>(zn, &imm5)) {
3874       SingleEmissionCheckScope guard(this);
3875       cmpeq(pd, pg, zn, imm5);
3876     } else {
3877       CompareHelper(eq, pd, pg, zn, imm);
3878     }
3879   }
Cmpge(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3880   void Cmpge(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     cmpge(pd, pg, zn, zm);
3887   }
Cmpge(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,IntegerOperand imm)3888   void Cmpge(const PRegisterWithLaneSize& pd,
3889              const PRegisterZ& pg,
3890              const ZRegister& zn,
3891              IntegerOperand imm) {
3892     VIXL_ASSERT(allow_macro_instructions_);
3893     int imm5;
3894     if (imm.TryEncodeAsIntNForLane<5>(zn, &imm5)) {
3895       SingleEmissionCheckScope guard(this);
3896       cmpge(pd, pg, zn, imm5);
3897     } else {
3898       CompareHelper(ge, pd, pg, zn, imm);
3899     }
3900   }
Cmpgt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3901   void Cmpgt(const PRegisterWithLaneSize& pd,
3902              const PRegisterZ& pg,
3903              const ZRegister& zn,
3904              const ZRegister& zm) {
3905     VIXL_ASSERT(allow_macro_instructions_);
3906     SingleEmissionCheckScope guard(this);
3907     cmpgt(pd, pg, zn, zm);
3908   }
Cmpgt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,IntegerOperand imm)3909   void Cmpgt(const PRegisterWithLaneSize& pd,
3910              const PRegisterZ& pg,
3911              const ZRegister& zn,
3912              IntegerOperand imm) {
3913     VIXL_ASSERT(allow_macro_instructions_);
3914     int imm5;
3915     if (imm.TryEncodeAsIntNForLane<5>(zn, &imm5)) {
3916       SingleEmissionCheckScope guard(this);
3917       cmpgt(pd, pg, zn, imm5);
3918     } else {
3919       CompareHelper(gt, pd, pg, zn, imm);
3920     }
3921   }
Cmphi(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3922   void Cmphi(const PRegisterWithLaneSize& pd,
3923              const PRegisterZ& pg,
3924              const ZRegister& zn,
3925              const ZRegister& zm) {
3926     VIXL_ASSERT(allow_macro_instructions_);
3927     SingleEmissionCheckScope guard(this);
3928     cmphi(pd, pg, zn, zm);
3929   }
Cmphi(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,IntegerOperand imm)3930   void Cmphi(const PRegisterWithLaneSize& pd,
3931              const PRegisterZ& pg,
3932              const ZRegister& zn,
3933              IntegerOperand imm) {
3934     VIXL_ASSERT(allow_macro_instructions_);
3935     if (imm.IsUintN(7)) {
3936       SingleEmissionCheckScope guard(this);
3937       cmphi(pd, pg, zn, static_cast<unsigned>(imm.AsUintN(7)));
3938     } else {
3939       CompareHelper(hi, pd, pg, zn, imm);
3940     }
3941   }
Cmphs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3942   void Cmphs(const PRegisterWithLaneSize& pd,
3943              const PRegisterZ& pg,
3944              const ZRegister& zn,
3945              const ZRegister& zm) {
3946     VIXL_ASSERT(allow_macro_instructions_);
3947     SingleEmissionCheckScope guard(this);
3948     cmphs(pd, pg, zn, zm);
3949   }
Cmphs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,IntegerOperand imm)3950   void Cmphs(const PRegisterWithLaneSize& pd,
3951              const PRegisterZ& pg,
3952              const ZRegister& zn,
3953              IntegerOperand imm) {
3954     if (imm.IsUintN(7)) {
3955       SingleEmissionCheckScope guard(this);
3956       cmphs(pd, pg, zn, static_cast<unsigned>(imm.AsUintN(7)));
3957     } else {
3958       CompareHelper(hs, pd, pg, zn, imm);
3959     }
3960   }
Cmple(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3961   void Cmple(const PRegisterWithLaneSize& pd,
3962              const PRegisterZ& pg,
3963              const ZRegister& zn,
3964              const ZRegister& zm) {
3965     VIXL_ASSERT(allow_macro_instructions_);
3966     SingleEmissionCheckScope guard(this);
3967     cmple(pd, pg, zn, zm);
3968   }
Cmple(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,IntegerOperand imm)3969   void Cmple(const PRegisterWithLaneSize& pd,
3970              const PRegisterZ& pg,
3971              const ZRegister& zn,
3972              IntegerOperand imm) {
3973     VIXL_ASSERT(allow_macro_instructions_);
3974     int imm5;
3975     if (imm.TryEncodeAsIntNForLane<5>(zn, &imm5)) {
3976       SingleEmissionCheckScope guard(this);
3977       cmple(pd, pg, zn, imm5);
3978     } else {
3979       CompareHelper(le, pd, pg, zn, imm);
3980     }
3981   }
Cmplo(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)3982   void Cmplo(const PRegisterWithLaneSize& pd,
3983              const PRegisterZ& pg,
3984              const ZRegister& zn,
3985              const ZRegister& zm) {
3986     VIXL_ASSERT(allow_macro_instructions_);
3987     SingleEmissionCheckScope guard(this);
3988     cmplo(pd, pg, zn, zm);
3989   }
Cmplo(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,IntegerOperand imm)3990   void Cmplo(const PRegisterWithLaneSize& pd,
3991              const PRegisterZ& pg,
3992              const ZRegister& zn,
3993              IntegerOperand imm) {
3994     if (imm.IsUintN(7)) {
3995       SingleEmissionCheckScope guard(this);
3996       cmplo(pd, pg, zn, static_cast<unsigned>(imm.AsUintN(7)));
3997     } else {
3998       CompareHelper(lo, pd, pg, zn, imm);
3999     }
4000   }
Cmpls(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4001   void Cmpls(const PRegisterWithLaneSize& pd,
4002              const PRegisterZ& pg,
4003              const ZRegister& zn,
4004              const ZRegister& zm) {
4005     VIXL_ASSERT(allow_macro_instructions_);
4006     SingleEmissionCheckScope guard(this);
4007     cmpls(pd, pg, zn, zm);
4008   }
Cmpls(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,IntegerOperand imm)4009   void Cmpls(const PRegisterWithLaneSize& pd,
4010              const PRegisterZ& pg,
4011              const ZRegister& zn,
4012              IntegerOperand imm) {
4013     if (imm.IsUintN(7)) {
4014       SingleEmissionCheckScope guard(this);
4015       cmpls(pd, pg, zn, static_cast<unsigned>(imm.AsUintN(7)));
4016     } else {
4017       CompareHelper(ls, pd, pg, zn, imm);
4018     }
4019   }
Cmplt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4020   void Cmplt(const PRegisterWithLaneSize& pd,
4021              const PRegisterZ& pg,
4022              const ZRegister& zn,
4023              const ZRegister& zm) {
4024     VIXL_ASSERT(allow_macro_instructions_);
4025     SingleEmissionCheckScope guard(this);
4026     cmplt(pd, pg, zn, zm);
4027   }
Cmplt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,IntegerOperand imm)4028   void Cmplt(const PRegisterWithLaneSize& pd,
4029              const PRegisterZ& pg,
4030              const ZRegister& zn,
4031              IntegerOperand imm) {
4032     VIXL_ASSERT(allow_macro_instructions_);
4033     int imm5;
4034     if (imm.TryEncodeAsIntNForLane<5>(zn, &imm5)) {
4035       SingleEmissionCheckScope guard(this);
4036       cmplt(pd, pg, zn, imm5);
4037     } else {
4038       CompareHelper(lt, pd, pg, zn, imm);
4039     }
4040   }
Cmpne(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4041   void Cmpne(const PRegisterWithLaneSize& pd,
4042              const PRegisterZ& pg,
4043              const ZRegister& zn,
4044              const ZRegister& zm) {
4045     VIXL_ASSERT(allow_macro_instructions_);
4046     SingleEmissionCheckScope guard(this);
4047     cmpne(pd, pg, zn, zm);
4048   }
Cmpne(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,IntegerOperand imm)4049   void Cmpne(const PRegisterWithLaneSize& pd,
4050              const PRegisterZ& pg,
4051              const ZRegister& zn,
4052              IntegerOperand imm) {
4053     VIXL_ASSERT(allow_macro_instructions_);
4054     int imm5;
4055     if (imm.TryEncodeAsIntNForLane<5>(zn, &imm5)) {
4056       SingleEmissionCheckScope guard(this);
4057       cmpne(pd, pg, zn, imm5);
4058     } else {
4059       CompareHelper(ne, pd, pg, zn, imm);
4060     }
4061   }
Cnot(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4062   void Cnot(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4063     VIXL_ASSERT(allow_macro_instructions_);
4064     SingleEmissionCheckScope guard(this);
4065     cnot(zd, pg, zn);
4066   }
Cnt(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4067   void Cnt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4068     VIXL_ASSERT(allow_macro_instructions_);
4069     SingleEmissionCheckScope guard(this);
4070     cnt(zd, pg, zn);
4071   }
4072   void Cntb(const Register& rd, int pattern = SVE_ALL, int multiplier = 1) {
4073     VIXL_ASSERT(allow_macro_instructions_);
4074     SingleEmissionCheckScope guard(this);
4075     cntb(rd, pattern, multiplier);
4076   }
4077   void Cntd(const Register& rd, int pattern = SVE_ALL, int multiplier = 1) {
4078     VIXL_ASSERT(allow_macro_instructions_);
4079     SingleEmissionCheckScope guard(this);
4080     cntd(rd, pattern, multiplier);
4081   }
4082   void Cnth(const Register& rd, int pattern = SVE_ALL, int multiplier = 1) {
4083     VIXL_ASSERT(allow_macro_instructions_);
4084     SingleEmissionCheckScope guard(this);
4085     cnth(rd, pattern, multiplier);
4086   }
Cntp(const Register & rd,const PRegister & pg,const PRegisterWithLaneSize & pn)4087   void Cntp(const Register& rd,
4088             const PRegister& pg,
4089             const PRegisterWithLaneSize& pn) {
4090     VIXL_ASSERT(allow_macro_instructions_);
4091     SingleEmissionCheckScope guard(this);
4092     // The `cntp` instruction architecturally takes an X register, but the
4093     // result will always be in the range [0, kPRegMaxSize] (and therefore
4094     // always fits in a W register), so we can accept a W-sized rd here.
4095     cntp(rd.X(), pg, pn);
4096   }
4097   void Cntw(const Register& rd, int pattern = SVE_ALL, int multiplier = 1) {
4098     VIXL_ASSERT(allow_macro_instructions_);
4099     SingleEmissionCheckScope guard(this);
4100     cntw(rd, pattern, multiplier);
4101   }
Compact(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)4102   void Compact(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) {
4103     VIXL_ASSERT(allow_macro_instructions_);
4104     SingleEmissionCheckScope guard(this);
4105     compact(zd, pg, zn);
4106   }
4107   void Cpy(const ZRegister& zd, const PRegister& pg, IntegerOperand imm);
Cpy(const ZRegister & zd,const PRegisterM & pg,const Register & rn)4108   void Cpy(const ZRegister& zd, const PRegisterM& pg, const Register& rn) {
4109     VIXL_ASSERT(allow_macro_instructions_);
4110     SingleEmissionCheckScope guard(this);
4111     cpy(zd, pg, rn);
4112   }
Cpy(const ZRegister & zd,const PRegisterM & pg,const VRegister & vn)4113   void Cpy(const ZRegister& zd, const PRegisterM& pg, const VRegister& vn) {
4114     VIXL_ASSERT(allow_macro_instructions_);
4115     SingleEmissionCheckScope guard(this);
4116     cpy(zd, pg, vn);
4117   }
Ctermeq(const Register & rn,const Register & rm)4118   void Ctermeq(const Register& rn, const Register& rm) {
4119     VIXL_ASSERT(allow_macro_instructions_);
4120     SingleEmissionCheckScope guard(this);
4121     ctermeq(rn, rm);
4122   }
Ctermne(const Register & rn,const Register & rm)4123   void Ctermne(const Register& rn, const Register& rm) {
4124     VIXL_ASSERT(allow_macro_instructions_);
4125     SingleEmissionCheckScope guard(this);
4126     ctermne(rn, rm);
4127   }
4128   void Decb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
4129     VIXL_ASSERT(allow_macro_instructions_);
4130     SingleEmissionCheckScope guard(this);
4131     decb(rdn, pattern, multiplier);
4132   }
4133   void Decd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
4134     VIXL_ASSERT(allow_macro_instructions_);
4135     SingleEmissionCheckScope guard(this);
4136     decd(rdn, pattern, multiplier);
4137   }
4138   void Decd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
4139     VIXL_ASSERT(allow_macro_instructions_);
4140     SingleEmissionCheckScope guard(this);
4141     decd(zdn, pattern, multiplier);
4142   }
4143   void Dech(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
4144     VIXL_ASSERT(allow_macro_instructions_);
4145     SingleEmissionCheckScope guard(this);
4146     dech(rdn, pattern, multiplier);
4147   }
4148   void Dech(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
4149     VIXL_ASSERT(allow_macro_instructions_);
4150     SingleEmissionCheckScope guard(this);
4151     dech(zdn, pattern, multiplier);
4152   }
Decp(const Register & rdn,const PRegisterWithLaneSize & pg)4153   void Decp(const Register& rdn, const PRegisterWithLaneSize& pg) {
4154     VIXL_ASSERT(allow_macro_instructions_);
4155     SingleEmissionCheckScope guard(this);
4156     decp(rdn, pg);
4157   }
Decp(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)4158   void Decp(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) {
4159     VIXL_ASSERT(allow_macro_instructions_);
4160     VIXL_ASSERT(AreSameFormat(zd, zn));
4161     // `decp` writes every lane, so use an unpredicated movprfx.
4162     MovprfxHelperScope guard(this, zd, zn);
4163     decp(zd, pg);
4164   }
Decp(const ZRegister & zdn,const PRegister & pg)4165   void Decp(const ZRegister& zdn, const PRegister& pg) { Decp(zdn, pg, zdn); }
4166   void Decw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
4167     VIXL_ASSERT(allow_macro_instructions_);
4168     SingleEmissionCheckScope guard(this);
4169     decw(rdn, pattern, multiplier);
4170   }
4171   void Decw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
4172     VIXL_ASSERT(allow_macro_instructions_);
4173     SingleEmissionCheckScope guard(this);
4174     decw(zdn, pattern, multiplier);
4175   }
Dup(const ZRegister & zd,const Register & xn)4176   void Dup(const ZRegister& zd, const Register& xn) {
4177     VIXL_ASSERT(allow_macro_instructions_);
4178     SingleEmissionCheckScope guard(this);
4179     dup(zd, xn);
4180   }
Dup(const ZRegister & zd,const ZRegister & zn,int index)4181   void Dup(const ZRegister& zd, const ZRegister& zn, int index) {
4182     VIXL_ASSERT(allow_macro_instructions_);
4183     SingleEmissionCheckScope guard(this);
4184     dup(zd, zn, index);
4185   }
4186   void Dup(const ZRegister& zd, IntegerOperand imm);
Eon(const ZRegister & zd,const ZRegister & zn,uint64_t imm)4187   void Eon(const ZRegister& zd, const ZRegister& zn, uint64_t imm) {
4188     VIXL_ASSERT(allow_macro_instructions_);
4189     SingleEmissionCheckScope guard(this);
4190     if (IsImmLogical(imm, zd.GetLaneSizeInBits())) {
4191       eon(zd, zn, imm);
4192     } else {
4193       // TODO: Synthesise the immediate once 'Mov' is implemented.
4194       VIXL_UNIMPLEMENTED();
4195     }
4196   }
Eor(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)4197   void Eor(const PRegisterWithLaneSize& pd,
4198            const PRegisterZ& pg,
4199            const PRegisterWithLaneSize& pn,
4200            const PRegisterWithLaneSize& pm) {
4201     VIXL_ASSERT(allow_macro_instructions_);
4202     SingleEmissionCheckScope guard(this);
4203     eor(pd, pg, pn, pm);
4204   }
Eor(const ZRegister & zd,const ZRegister & zn,uint64_t imm)4205   void Eor(const ZRegister& zd, const ZRegister& zn, uint64_t imm) {
4206     VIXL_ASSERT(allow_macro_instructions_);
4207     SingleEmissionCheckScope guard(this);
4208     if (IsImmLogical(imm, zd.GetLaneSizeInBits())) {
4209       eor(zd, zn, imm);
4210     } else {
4211       // TODO: Synthesise the immediate once 'Mov' is implemented.
4212       VIXL_UNIMPLEMENTED();
4213     }
4214   }
Eor(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)4215   void Eor(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
4216     VIXL_ASSERT(allow_macro_instructions_);
4217     VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
4218     SingleEmissionCheckScope guard(this);
4219     eor(zd.VnD(), zn.VnD(), zm.VnD());
4220   }
Eors(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)4221   void Eors(const PRegisterWithLaneSize& pd,
4222             const PRegisterZ& pg,
4223             const PRegisterWithLaneSize& pn,
4224             const PRegisterWithLaneSize& pm) {
4225     VIXL_ASSERT(allow_macro_instructions_);
4226     SingleEmissionCheckScope guard(this);
4227     eors(pd, pg, pn, pm);
4228   }
Eorv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)4229   void Eorv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
4230     VIXL_ASSERT(allow_macro_instructions_);
4231     SingleEmissionCheckScope guard(this);
4232     eorv(vd, pg, zn);
4233   }
Ext(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,unsigned offset)4234   void Ext(const ZRegister& zd,
4235            const ZRegister& zn,
4236            const ZRegister& zm,
4237            unsigned offset) {
4238     VIXL_ASSERT(allow_macro_instructions_);
4239     SingleEmissionCheckScope guard(this);
4240     ext(zd, zn, zm, offset);
4241   }
4242   void Fabd(const ZRegister& zd,
4243             const PRegisterM& pg,
4244             const ZRegister& zn,
4245             const ZRegister& zm,
4246             FPMacroNaNPropagationOption nan_option);
Fabs(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4247   void Fabs(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4248     VIXL_ASSERT(allow_macro_instructions_);
4249     SingleEmissionCheckScope guard(this);
4250     fabs(zd, pg, zn);
4251   }
Facge(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4252   void Facge(const PRegisterWithLaneSize& pd,
4253              const PRegisterZ& pg,
4254              const ZRegister& zn,
4255              const ZRegister& zm) {
4256     VIXL_ASSERT(allow_macro_instructions_);
4257     SingleEmissionCheckScope guard(this);
4258     facge(pd, pg, zn, zm);
4259   }
Facgt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4260   void Facgt(const PRegisterWithLaneSize& pd,
4261              const PRegisterZ& pg,
4262              const ZRegister& zn,
4263              const ZRegister& zm) {
4264     VIXL_ASSERT(allow_macro_instructions_);
4265     SingleEmissionCheckScope guard(this);
4266     facgt(pd, pg, zn, zm);
4267   }
Facle(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4268   void Facle(const PRegisterWithLaneSize& pd,
4269              const PRegisterZ& pg,
4270              const ZRegister& zn,
4271              const ZRegister& zm) {
4272     VIXL_ASSERT(allow_macro_instructions_);
4273     SingleEmissionCheckScope guard(this);
4274     facge(pd, pg, zm, zn);
4275   }
Faclt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4276   void Faclt(const PRegisterWithLaneSize& pd,
4277              const PRegisterZ& pg,
4278              const ZRegister& zn,
4279              const ZRegister& zm) {
4280     VIXL_ASSERT(allow_macro_instructions_);
4281     SingleEmissionCheckScope guard(this);
4282     facgt(pd, pg, zm, zn);
4283   }
Fadd(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)4284   void Fadd(const ZRegister& zd,
4285             const PRegisterM& pg,
4286             const ZRegister& zn,
4287             double imm) {
4288     VIXL_ASSERT(allow_macro_instructions_);
4289     MovprfxHelperScope guard(this, zd, pg, zn);
4290     fadd(zd, pg, zd, imm);
4291   }
4292   void Fadd(const ZRegister& zd,
4293             const PRegisterM& pg,
4294             const ZRegister& zn,
4295             const ZRegister& zm,
4296             FPMacroNaNPropagationOption nan_option);
Fadd(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)4297   void Fadd(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
4298     VIXL_ASSERT(allow_macro_instructions_);
4299     SingleEmissionCheckScope guard(this);
4300     fadd(zd, zn, zm);
4301   }
Fadda(const VRegister & vd,const PRegister & pg,const VRegister & vn,const ZRegister & zm)4302   void Fadda(const VRegister& vd,
4303              const PRegister& pg,
4304              const VRegister& vn,
4305              const ZRegister& zm) {
4306     VIXL_ASSERT(allow_macro_instructions_);
4307     SingleEmissionCheckScope guard(this);
4308     fadda(vd, pg, vn, zm);
4309   }
Faddv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)4310   void Faddv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
4311     VIXL_ASSERT(allow_macro_instructions_);
4312     SingleEmissionCheckScope guard(this);
4313     faddv(vd, pg, zn);
4314   }
4315   void Fcadd(const ZRegister& zd,
4316              const PRegisterM& pg,
4317              const ZRegister& zn,
4318              const ZRegister& zm,
4319              int rot);
Fcmeq(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,double zero)4320   void Fcmeq(const PRegisterWithLaneSize& pd,
4321              const PRegisterZ& pg,
4322              const ZRegister& zn,
4323              double zero) {
4324     VIXL_ASSERT(allow_macro_instructions_);
4325     SingleEmissionCheckScope guard(this);
4326     if (zero == 0.0) {
4327       fcmeq(pd, pg, zn, zero);
4328     } else {
4329       // TODO: Synthesise other immediates.
4330       VIXL_UNIMPLEMENTED();
4331     }
4332   }
Fcmeq(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4333   void Fcmeq(const PRegisterWithLaneSize& pd,
4334              const PRegisterZ& pg,
4335              const ZRegister& zn,
4336              const ZRegister& zm) {
4337     VIXL_ASSERT(allow_macro_instructions_);
4338     SingleEmissionCheckScope guard(this);
4339     fcmeq(pd, pg, zn, zm);
4340   }
Fcmge(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,double zero)4341   void Fcmge(const PRegisterWithLaneSize& pd,
4342              const PRegisterZ& pg,
4343              const ZRegister& zn,
4344              double zero) {
4345     VIXL_ASSERT(allow_macro_instructions_);
4346     SingleEmissionCheckScope guard(this);
4347     if (zero == 0.0) {
4348       fcmge(pd, pg, zn, zero);
4349     } else {
4350       // TODO: Synthesise other immediates.
4351       VIXL_UNIMPLEMENTED();
4352     }
4353   }
Fcmge(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4354   void Fcmge(const PRegisterWithLaneSize& pd,
4355              const PRegisterZ& pg,
4356              const ZRegister& zn,
4357              const ZRegister& zm) {
4358     VIXL_ASSERT(allow_macro_instructions_);
4359     SingleEmissionCheckScope guard(this);
4360     fcmge(pd, pg, zn, zm);
4361   }
Fcmgt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,double zero)4362   void Fcmgt(const PRegisterWithLaneSize& pd,
4363              const PRegisterZ& pg,
4364              const ZRegister& zn,
4365              double zero) {
4366     VIXL_ASSERT(allow_macro_instructions_);
4367     SingleEmissionCheckScope guard(this);
4368     if (zero == 0.0) {
4369       fcmgt(pd, pg, zn, zero);
4370     } else {
4371       // TODO: Synthesise other immediates.
4372       VIXL_UNIMPLEMENTED();
4373     }
4374   }
Fcmgt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4375   void Fcmgt(const PRegisterWithLaneSize& pd,
4376              const PRegisterZ& pg,
4377              const ZRegister& zn,
4378              const ZRegister& zm) {
4379     VIXL_ASSERT(allow_macro_instructions_);
4380     SingleEmissionCheckScope guard(this);
4381     fcmgt(pd, pg, zn, zm);
4382   }
4383   void Fcmla(const ZRegister& zd,
4384              const PRegisterM& pg,
4385              const ZRegister& za,
4386              const ZRegister& zn,
4387              const ZRegister& zm,
4388              int rot);
Fcmla(const ZRegister & zda,const ZRegister & zn,const ZRegister & zm,int index,int rot)4389   void Fcmla(const ZRegister& zda,
4390              const ZRegister& zn,
4391              const ZRegister& zm,
4392              int index,
4393              int rot) {
4394     VIXL_ASSERT(allow_macro_instructions_);
4395     SingleEmissionCheckScope guard(this);
4396     fcmla(zda, zn, zm, index, rot);
4397   }
Fcmle(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,double zero)4398   void Fcmle(const PRegisterWithLaneSize& pd,
4399              const PRegisterZ& pg,
4400              const ZRegister& zn,
4401              double zero) {
4402     VIXL_ASSERT(allow_macro_instructions_);
4403     SingleEmissionCheckScope guard(this);
4404     if (zero == 0.0) {
4405       fcmle(pd, pg, zn, zero);
4406     } else {
4407       // TODO: Synthesise other immediates.
4408       VIXL_UNIMPLEMENTED();
4409     }
4410   }
Fcmle(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4411   void Fcmle(const PRegisterWithLaneSize& pd,
4412              const PRegisterZ& pg,
4413              const ZRegister& zn,
4414              const ZRegister& zm) {
4415     VIXL_ASSERT(allow_macro_instructions_);
4416     SingleEmissionCheckScope guard(this);
4417     fcmge(pd, pg, zm, zn);
4418   }
Fcmlt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,double zero)4419   void Fcmlt(const PRegisterWithLaneSize& pd,
4420              const PRegisterZ& pg,
4421              const ZRegister& zn,
4422              double zero) {
4423     VIXL_ASSERT(allow_macro_instructions_);
4424     SingleEmissionCheckScope guard(this);
4425     if (zero == 0.0) {
4426       fcmlt(pd, pg, zn, zero);
4427     } else {
4428       // TODO: Synthesise other immediates.
4429       VIXL_UNIMPLEMENTED();
4430     }
4431   }
Fcmlt(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4432   void Fcmlt(const PRegisterWithLaneSize& pd,
4433              const PRegisterZ& pg,
4434              const ZRegister& zn,
4435              const ZRegister& zm) {
4436     VIXL_ASSERT(allow_macro_instructions_);
4437     SingleEmissionCheckScope guard(this);
4438     fcmgt(pd, pg, zm, zn);
4439   }
Fcmne(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,double zero)4440   void Fcmne(const PRegisterWithLaneSize& pd,
4441              const PRegisterZ& pg,
4442              const ZRegister& zn,
4443              double zero) {
4444     VIXL_ASSERT(allow_macro_instructions_);
4445     SingleEmissionCheckScope guard(this);
4446     if (zero == 0.0) {
4447       fcmne(pd, pg, zn, zero);
4448     } else {
4449       // TODO: Synthesise other immediates.
4450       VIXL_UNIMPLEMENTED();
4451     }
4452   }
Fcmne(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4453   void Fcmne(const PRegisterWithLaneSize& pd,
4454              const PRegisterZ& pg,
4455              const ZRegister& zn,
4456              const ZRegister& zm) {
4457     VIXL_ASSERT(allow_macro_instructions_);
4458     SingleEmissionCheckScope guard(this);
4459     fcmne(pd, pg, zn, zm);
4460   }
Fcmuo(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)4461   void Fcmuo(const PRegisterWithLaneSize& pd,
4462              const PRegisterZ& pg,
4463              const ZRegister& zn,
4464              const ZRegister& zm) {
4465     VIXL_ASSERT(allow_macro_instructions_);
4466     SingleEmissionCheckScope guard(this);
4467     fcmuo(pd, pg, zn, zm);
4468   }
4469   void Fcpy(const ZRegister& zd, const PRegisterM& pg, double imm);
4470   void Fcpy(const ZRegister& zd, const PRegisterM& pg, float imm);
4471   void Fcpy(const ZRegister& zd, const PRegisterM& pg, Float16 imm);
Fcvt(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4472   void Fcvt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4473     VIXL_ASSERT(allow_macro_instructions_);
4474     SingleEmissionCheckScope guard(this);
4475     fcvt(zd, pg, zn);
4476   }
Fcvt(const ZRegister & zd,const PRegisterZ & pg,const ZRegister & zn)4477   void Fcvt(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) {
4478     VIXL_ASSERT(allow_macro_instructions_);
4479     // The element type in this predicated movprfx is determined by the larger
4480     // type between the source and destination.
4481     int lane_size = std::max(zd.GetLaneSizeInBits(), zn.GetLaneSizeInBits());
4482     MovprfxHelperScope guard(this,
4483                              zd.WithLaneSize(lane_size),
4484                              pg,
4485                              zn.WithLaneSize(lane_size));
4486     fcvt(zd, pg.Merging(), zn);
4487   }
Fcvtzs(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4488   void Fcvtzs(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4489     VIXL_ASSERT(allow_macro_instructions_);
4490     SingleEmissionCheckScope guard(this);
4491     fcvtzs(zd, pg, zn);
4492   }
Fcvtzu(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4493   void Fcvtzu(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4494     VIXL_ASSERT(allow_macro_instructions_);
4495     SingleEmissionCheckScope guard(this);
4496     fcvtzu(zd, pg, zn);
4497   }
4498   void Fdiv(const ZRegister& zd,
4499             const PRegisterM& pg,
4500             const ZRegister& zn,
4501             const ZRegister& zm);
4502   void Fdup(const ZRegister& zd, double imm);
4503   void Fdup(const ZRegister& zd, float imm);
4504   void Fdup(const ZRegister& zd, Float16 imm);
Fexpa(const ZRegister & zd,const ZRegister & zn)4505   void Fexpa(const ZRegister& zd, const ZRegister& zn) {
4506     VIXL_ASSERT(allow_macro_instructions_);
4507     SingleEmissionCheckScope guard(this);
4508     fexpa(zd, zn);
4509   }
Fmad(const ZRegister & zdn,const PRegisterM & pg,const ZRegister & zm,const ZRegister & za)4510   void Fmad(const ZRegister& zdn,
4511             const PRegisterM& pg,
4512             const ZRegister& zm,
4513             const ZRegister& za) {
4514     VIXL_ASSERT(allow_macro_instructions_);
4515     SingleEmissionCheckScope guard(this);
4516     fmad(zdn, pg, zm, za);
4517   }
Fmax(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)4518   void Fmax(const ZRegister& zd,
4519             const PRegisterM& pg,
4520             const ZRegister& zn,
4521             double imm) {
4522     VIXL_ASSERT(allow_macro_instructions_);
4523     MovprfxHelperScope guard(this, zd, pg, zn);
4524     fmax(zd, pg, zd, imm);
4525   }
4526   void Fmax(
4527       const ZRegister& zd,
4528       const PRegisterM& pg,
4529       const ZRegister& zn,
4530       const ZRegister& zm,
4531       FPMacroNaNPropagationOption nan_option = NoFPMacroNaNPropagationSelected);
Fmaxnm(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)4532   void Fmaxnm(const ZRegister& zd,
4533               const PRegisterM& pg,
4534               const ZRegister& zn,
4535               double imm) {
4536     VIXL_ASSERT(allow_macro_instructions_);
4537     MovprfxHelperScope guard(this, zd, pg, zn);
4538     fmaxnm(zd, pg, zd, imm);
4539   }
4540   void Fmaxnm(const ZRegister& zd,
4541               const PRegisterM& pg,
4542               const ZRegister& zn,
4543               const ZRegister& zm,
4544               FPMacroNaNPropagationOption nan_option);
Fmaxnmv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)4545   void Fmaxnmv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
4546     VIXL_ASSERT(allow_macro_instructions_);
4547     SingleEmissionCheckScope guard(this);
4548     fmaxnmv(vd, pg, zn);
4549   }
Fmaxv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)4550   void Fmaxv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
4551     VIXL_ASSERT(allow_macro_instructions_);
4552     SingleEmissionCheckScope guard(this);
4553     fmaxv(vd, pg, zn);
4554   }
Fmin(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)4555   void Fmin(const ZRegister& zd,
4556             const PRegisterM& pg,
4557             const ZRegister& zn,
4558             double imm) {
4559     VIXL_ASSERT(allow_macro_instructions_);
4560     MovprfxHelperScope guard(this, zd, pg, zn);
4561     fmin(zd, pg, zd, imm);
4562   }
4563   void Fmin(
4564       const ZRegister& zd,
4565       const PRegisterM& pg,
4566       const ZRegister& zn,
4567       const ZRegister& zm,
4568       FPMacroNaNPropagationOption nan_option = NoFPMacroNaNPropagationSelected);
Fminnm(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)4569   void Fminnm(const ZRegister& zd,
4570               const PRegisterM& pg,
4571               const ZRegister& zn,
4572               double imm) {
4573     VIXL_ASSERT(allow_macro_instructions_);
4574     MovprfxHelperScope guard(this, zd, pg, zn);
4575     fminnm(zd, pg, zd, imm);
4576   }
4577   void Fminnm(const ZRegister& zd,
4578               const PRegisterM& pg,
4579               const ZRegister& zn,
4580               const ZRegister& zm,
4581               FPMacroNaNPropagationOption nan_option);
Fminnmv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)4582   void Fminnmv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
4583     VIXL_ASSERT(allow_macro_instructions_);
4584     SingleEmissionCheckScope guard(this);
4585     fminnmv(vd, pg, zn);
4586   }
Fminv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)4587   void Fminv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
4588     VIXL_ASSERT(allow_macro_instructions_);
4589     SingleEmissionCheckScope guard(this);
4590     fminv(vd, pg, zn);
4591   }
4592   // zd = za + (zn * zm)
4593   void Fmla(
4594       const ZRegister& zd,
4595       const PRegisterM& pg,
4596       const ZRegister& za,
4597       const ZRegister& zn,
4598       const ZRegister& zm,
4599       FPMacroNaNPropagationOption nan_option = NoFPMacroNaNPropagationSelected);
4600   void Fmla(const ZRegister& zd,
4601             const ZRegister& za,
4602             const ZRegister& zn,
4603             const ZRegister& zm,
4604             int index);
4605   // zd = za - (zn * zm)
4606   void Fmls(
4607       const ZRegister& zd,
4608       const PRegisterM& pg,
4609       const ZRegister& za,
4610       const ZRegister& zn,
4611       const ZRegister& zm,
4612       FPMacroNaNPropagationOption nan_option = NoFPMacroNaNPropagationSelected);
4613   void Fmls(const ZRegister& zd,
4614             const ZRegister& za,
4615             const ZRegister& zn,
4616             const ZRegister& zm,
4617             int index);
Fmov(const ZRegister & zd,double imm)4618   void Fmov(const ZRegister& zd, double imm) {
4619     VIXL_ASSERT(allow_macro_instructions_);
4620     Fdup(zd, imm);
4621   }
Fmov(const ZRegister & zd,float imm)4622   void Fmov(const ZRegister& zd, float imm) {
4623     VIXL_ASSERT(allow_macro_instructions_);
4624     Fdup(zd, imm);
4625   }
Fmov(const ZRegister & zd,Float16 imm)4626   void Fmov(const ZRegister& zd, Float16 imm) {
4627     VIXL_ASSERT(allow_macro_instructions_);
4628     Fdup(zd, imm);
4629   }
Fmov(const ZRegister & zd,const PRegisterM & pg,double imm)4630   void Fmov(const ZRegister& zd, const PRegisterM& pg, double imm) {
4631     VIXL_ASSERT(allow_macro_instructions_);
4632     Fcpy(zd, pg, imm);
4633   }
Fmov(const ZRegister & zd,const PRegisterM & pg,float imm)4634   void Fmov(const ZRegister& zd, const PRegisterM& pg, float imm) {
4635     VIXL_ASSERT(allow_macro_instructions_);
4636     Fcpy(zd, pg, imm);
4637   }
Fmov(const ZRegister & zd,const PRegisterM & pg,Float16 imm)4638   void Fmov(const ZRegister& zd, const PRegisterM& pg, Float16 imm) {
4639     VIXL_ASSERT(allow_macro_instructions_);
4640     Fcpy(zd, pg, imm);
4641   }
Fmsb(const ZRegister & zdn,const PRegisterM & pg,const ZRegister & zm,const ZRegister & za)4642   void Fmsb(const ZRegister& zdn,
4643             const PRegisterM& pg,
4644             const ZRegister& zm,
4645             const ZRegister& za) {
4646     VIXL_ASSERT(allow_macro_instructions_);
4647     SingleEmissionCheckScope guard(this);
4648     fmsb(zdn, pg, zm, za);
4649   }
Fmul(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)4650   void Fmul(const ZRegister& zd,
4651             const PRegisterM& pg,
4652             const ZRegister& zn,
4653             double imm) {
4654     VIXL_ASSERT(allow_macro_instructions_);
4655     MovprfxHelperScope guard(this, zd, pg, zn);
4656     fmul(zd, pg, zd, imm);
4657   }
4658   void Fmul(const ZRegister& zd,
4659             const PRegisterM& pg,
4660             const ZRegister& zn,
4661             const ZRegister& zm,
4662             FPMacroNaNPropagationOption nan_option);
Fmul(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,unsigned index)4663   void Fmul(const ZRegister& zd,
4664             const ZRegister& zn,
4665             const ZRegister& zm,
4666             unsigned index) {
4667     VIXL_ASSERT(allow_macro_instructions_);
4668     SingleEmissionCheckScope guard(this);
4669     fmul(zd, zn, zm, index);
4670   }
Fmul(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)4671   void Fmul(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
4672     VIXL_ASSERT(allow_macro_instructions_);
4673     SingleEmissionCheckScope guard(this);
4674     fmul(zd, zn, zm);
4675   }
4676   void Fmulx(const ZRegister& zd,
4677              const PRegisterM& pg,
4678              const ZRegister& zn,
4679              const ZRegister& zm,
4680              FPMacroNaNPropagationOption nan_option);
Fneg(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4681   void Fneg(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4682     VIXL_ASSERT(allow_macro_instructions_);
4683     SingleEmissionCheckScope guard(this);
4684     fneg(zd, pg, zn);
4685   }
4686   void Fnmla(
4687       const ZRegister& zda,
4688       const PRegisterM& pg,
4689       const ZRegister& za,
4690       const ZRegister& zn,
4691       const ZRegister& zm,
4692       FPMacroNaNPropagationOption nan_option = NoFPMacroNaNPropagationSelected);
4693   void Fnmls(
4694       const ZRegister& zd,
4695       const PRegisterM& pg,
4696       const ZRegister& za,
4697       const ZRegister& zn,
4698       const ZRegister& zm,
4699       FPMacroNaNPropagationOption nan_option = NoFPMacroNaNPropagationSelected);
Frecpe(const ZRegister & zd,const ZRegister & zn)4700   void Frecpe(const ZRegister& zd, const ZRegister& zn) {
4701     VIXL_ASSERT(allow_macro_instructions_);
4702     SingleEmissionCheckScope guard(this);
4703     frecpe(zd, zn);
4704   }
Frecps(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)4705   void Frecps(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
4706     VIXL_ASSERT(allow_macro_instructions_);
4707     SingleEmissionCheckScope guard(this);
4708     frecps(zd, zn, zm);
4709   }
Frecpx(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4710   void Frecpx(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4711     VIXL_ASSERT(allow_macro_instructions_);
4712     SingleEmissionCheckScope guard(this);
4713     frecpx(zd, pg, zn);
4714   }
Frecpx(const ZRegister & zd,const PRegisterZ & pg,const ZRegister & zn)4715   void Frecpx(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) {
4716     VIXL_ASSERT(allow_macro_instructions_);
4717     MovprfxHelperScope guard(this, zd, pg, zn);
4718     frecpx(zd, pg.Merging(), zn);
4719   }
Frinta(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4720   void Frinta(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4721     VIXL_ASSERT(allow_macro_instructions_);
4722     SingleEmissionCheckScope guard(this);
4723     frinta(zd, pg, zn);
4724   }
Frinta(const ZRegister & zd,const PRegisterZ & pg,const ZRegister & zn)4725   void Frinta(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) {
4726     VIXL_ASSERT(allow_macro_instructions_);
4727     MovprfxHelperScope guard(this, zd, pg, zn);
4728     frinta(zd, pg.Merging(), zn);
4729   }
Frinti(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4730   void Frinti(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4731     VIXL_ASSERT(allow_macro_instructions_);
4732     SingleEmissionCheckScope guard(this);
4733     frinti(zd, pg, zn);
4734   }
Frinti(const ZRegister & zd,const PRegisterZ & pg,const ZRegister & zn)4735   void Frinti(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) {
4736     VIXL_ASSERT(allow_macro_instructions_);
4737     MovprfxHelperScope guard(this, zd, pg, zn);
4738     frinti(zd, pg.Merging(), zn);
4739   }
Frintm(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4740   void Frintm(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4741     VIXL_ASSERT(allow_macro_instructions_);
4742     SingleEmissionCheckScope guard(this);
4743     frintm(zd, pg, zn);
4744   }
Frintm(const ZRegister & zd,const PRegisterZ & pg,const ZRegister & zn)4745   void Frintm(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) {
4746     VIXL_ASSERT(allow_macro_instructions_);
4747     MovprfxHelperScope guard(this, zd, pg, zn);
4748     frintm(zd, pg.Merging(), zn);
4749   }
Frintn(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4750   void Frintn(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4751     VIXL_ASSERT(allow_macro_instructions_);
4752     SingleEmissionCheckScope guard(this);
4753     frintn(zd, pg, zn);
4754   }
Frintn(const ZRegister & zd,const PRegisterZ & pg,const ZRegister & zn)4755   void Frintn(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) {
4756     VIXL_ASSERT(allow_macro_instructions_);
4757     MovprfxHelperScope guard(this, zd, pg, zn);
4758     frintn(zd, pg.Merging(), zn);
4759   }
Frintp(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4760   void Frintp(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4761     VIXL_ASSERT(allow_macro_instructions_);
4762     SingleEmissionCheckScope guard(this);
4763     frintp(zd, pg, zn);
4764   }
Frintp(const ZRegister & zd,const PRegisterZ & pg,const ZRegister & zn)4765   void Frintp(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) {
4766     VIXL_ASSERT(allow_macro_instructions_);
4767     MovprfxHelperScope guard(this, zd, pg, zn);
4768     frintp(zd, pg.Merging(), zn);
4769   }
Frintx(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4770   void Frintx(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4771     VIXL_ASSERT(allow_macro_instructions_);
4772     SingleEmissionCheckScope guard(this);
4773     frintx(zd, pg, zn);
4774   }
Frintx(const ZRegister & zd,const PRegisterZ & pg,const ZRegister & zn)4775   void Frintx(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) {
4776     VIXL_ASSERT(allow_macro_instructions_);
4777     MovprfxHelperScope guard(this, zd, pg, zn);
4778     frintx(zd, pg.Merging(), zn);
4779   }
Frintz(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4780   void Frintz(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4781     VIXL_ASSERT(allow_macro_instructions_);
4782     SingleEmissionCheckScope guard(this);
4783     frintz(zd, pg, zn);
4784   }
Frintz(const ZRegister & zd,const PRegisterZ & pg,const ZRegister & zn)4785   void Frintz(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) {
4786     VIXL_ASSERT(allow_macro_instructions_);
4787     MovprfxHelperScope guard(this, zd, pg, zn);
4788     frintz(zd, pg.Merging(), zn);
4789   }
Frsqrte(const ZRegister & zd,const ZRegister & zn)4790   void Frsqrte(const ZRegister& zd, const ZRegister& zn) {
4791     VIXL_ASSERT(allow_macro_instructions_);
4792     SingleEmissionCheckScope guard(this);
4793     frsqrte(zd, zn);
4794   }
Frsqrts(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)4795   void Frsqrts(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
4796     VIXL_ASSERT(allow_macro_instructions_);
4797     SingleEmissionCheckScope guard(this);
4798     frsqrts(zd, zn, zm);
4799   }
4800   void Fscale(const ZRegister& zd,
4801               const PRegisterM& pg,
4802               const ZRegister& zn,
4803               const ZRegister& zm);
Fsqrt(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)4804   void Fsqrt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
4805     VIXL_ASSERT(allow_macro_instructions_);
4806     SingleEmissionCheckScope guard(this);
4807     fsqrt(zd, pg, zn);
4808   }
Fsqrt(const ZRegister & zd,const PRegisterZ & pg,const ZRegister & zn)4809   void Fsqrt(const ZRegister& zd, const PRegisterZ& pg, const ZRegister& zn) {
4810     VIXL_ASSERT(allow_macro_instructions_);
4811     MovprfxHelperScope guard(this, zd, pg, zn);
4812     fsqrt(zd, pg.Merging(), zn);
4813   }
Fsub(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,double imm)4814   void Fsub(const ZRegister& zd,
4815             const PRegisterM& pg,
4816             const ZRegister& zn,
4817             double imm) {
4818     VIXL_ASSERT(allow_macro_instructions_);
4819     MovprfxHelperScope guard(this, zd, pg, zn);
4820     fsub(zd, pg, zd, imm);
4821   }
Fsub(const ZRegister & zd,const PRegisterM & pg,double imm,const ZRegister & zn)4822   void Fsub(const ZRegister& zd,
4823             const PRegisterM& pg,
4824             double imm,
4825             const ZRegister& zn) {
4826     VIXL_ASSERT(allow_macro_instructions_);
4827     MovprfxHelperScope guard(this, zd, pg, zn);
4828     fsubr(zd, pg, zd, imm);
4829   }
4830   void Fsub(const ZRegister& zd,
4831             const PRegisterM& pg,
4832             const ZRegister& zn,
4833             const ZRegister& zm);
Fsub(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)4834   void Fsub(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
4835     VIXL_ASSERT(allow_macro_instructions_);
4836     SingleEmissionCheckScope guard(this);
4837     fsub(zd, zn, zm);
4838   }
4839   void Ftmad(const ZRegister& zd,
4840              const ZRegister& zn,
4841              const ZRegister& zm,
4842              int imm3);
Ftsmul(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)4843   void Ftsmul(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
4844     VIXL_ASSERT(allow_macro_instructions_);
4845     SingleEmissionCheckScope guard(this);
4846     ftsmul(zd, zn, zm);
4847   }
Ftssel(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)4848   void Ftssel(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
4849     VIXL_ASSERT(allow_macro_instructions_);
4850     SingleEmissionCheckScope guard(this);
4851     ftssel(zd, zn, zm);
4852   }
4853   void Incb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
4854     VIXL_ASSERT(allow_macro_instructions_);
4855     SingleEmissionCheckScope guard(this);
4856     incb(rdn, pattern, multiplier);
4857   }
4858   void Incd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
4859     VIXL_ASSERT(allow_macro_instructions_);
4860     SingleEmissionCheckScope guard(this);
4861     incd(rdn, pattern, multiplier);
4862   }
4863   void Incd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
4864     VIXL_ASSERT(allow_macro_instructions_);
4865     SingleEmissionCheckScope guard(this);
4866     incd(zdn, pattern, multiplier);
4867   }
4868   void Inch(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
4869     VIXL_ASSERT(allow_macro_instructions_);
4870     SingleEmissionCheckScope guard(this);
4871     inch(rdn, pattern, multiplier);
4872   }
4873   void Inch(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
4874     VIXL_ASSERT(allow_macro_instructions_);
4875     SingleEmissionCheckScope guard(this);
4876     inch(zdn, pattern, multiplier);
4877   }
Incp(const Register & rdn,const PRegisterWithLaneSize & pg)4878   void Incp(const Register& rdn, const PRegisterWithLaneSize& pg) {
4879     VIXL_ASSERT(allow_macro_instructions_);
4880     SingleEmissionCheckScope guard(this);
4881     incp(rdn, pg);
4882   }
Incp(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)4883   void Incp(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) {
4884     VIXL_ASSERT(allow_macro_instructions_);
4885     VIXL_ASSERT(AreSameFormat(zd, zn));
4886     // `incp` writes every lane, so use an unpredicated movprfx.
4887     MovprfxHelperScope guard(this, zd, zn);
4888     incp(zd, pg);
4889   }
Incp(const ZRegister & zdn,const PRegister & pg)4890   void Incp(const ZRegister& zdn, const PRegister& pg) { Incp(zdn, pg, zdn); }
4891   void Incw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
4892     VIXL_ASSERT(allow_macro_instructions_);
4893     SingleEmissionCheckScope guard(this);
4894     incw(rdn, pattern, multiplier);
4895   }
4896   void Incw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
4897     VIXL_ASSERT(allow_macro_instructions_);
4898     SingleEmissionCheckScope guard(this);
4899     incw(zdn, pattern, multiplier);
4900   }
4901   void Index(const ZRegister& zd, const Operand& start, const Operand& step);
Insr(const ZRegister & zdn,const Register & rm)4902   void Insr(const ZRegister& zdn, const Register& rm) {
4903     VIXL_ASSERT(allow_macro_instructions_);
4904     SingleEmissionCheckScope guard(this);
4905     insr(zdn, rm);
4906   }
Insr(const ZRegister & zdn,const VRegister & vm)4907   void Insr(const ZRegister& zdn, const VRegister& vm) {
4908     VIXL_ASSERT(allow_macro_instructions_);
4909     SingleEmissionCheckScope guard(this);
4910     insr(zdn, vm);
4911   }
4912   void Insr(const ZRegister& zdn, IntegerOperand imm);
Lasta(const Register & rd,const PRegister & pg,const ZRegister & zn)4913   void Lasta(const Register& rd, const PRegister& pg, const ZRegister& zn) {
4914     VIXL_ASSERT(allow_macro_instructions_);
4915     SingleEmissionCheckScope guard(this);
4916     lasta(rd, pg, zn);
4917   }
Lasta(const VRegister & vd,const PRegister & pg,const ZRegister & zn)4918   void Lasta(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
4919     VIXL_ASSERT(allow_macro_instructions_);
4920     SingleEmissionCheckScope guard(this);
4921     lasta(vd, pg, zn);
4922   }
Lastb(const Register & rd,const PRegister & pg,const ZRegister & zn)4923   void Lastb(const Register& rd, const PRegister& pg, const ZRegister& zn) {
4924     VIXL_ASSERT(allow_macro_instructions_);
4925     SingleEmissionCheckScope guard(this);
4926     lastb(rd, pg, zn);
4927   }
Lastb(const VRegister & vd,const PRegister & pg,const ZRegister & zn)4928   void Lastb(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
4929     VIXL_ASSERT(allow_macro_instructions_);
4930     SingleEmissionCheckScope guard(this);
4931     lastb(vd, pg, zn);
4932   }
4933   void Ld1b(const ZRegister& zt,
4934             const PRegisterZ& pg,
4935             const SVEMemOperand& addr);
4936   void Ld1h(const ZRegister& zt,
4937             const PRegisterZ& pg,
4938             const SVEMemOperand& addr);
4939   void Ld1w(const ZRegister& zt,
4940             const PRegisterZ& pg,
4941             const SVEMemOperand& addr);
4942   void Ld1d(const ZRegister& zt,
4943             const PRegisterZ& pg,
4944             const SVEMemOperand& addr);
Ld1rb(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4945   void Ld1rb(const ZRegister& zt,
4946              const PRegisterZ& pg,
4947              const SVEMemOperand& addr) {
4948     VIXL_ASSERT(allow_macro_instructions_);
4949     SVELoadBroadcastImmHelper(zt,
4950                               pg,
4951                               addr,
4952                               &MacroAssembler::ld1rb,
4953                               kBRegSizeInBytes);
4954   }
Ld1rh(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4955   void Ld1rh(const ZRegister& zt,
4956              const PRegisterZ& pg,
4957              const SVEMemOperand& addr) {
4958     VIXL_ASSERT(allow_macro_instructions_);
4959     SVELoadBroadcastImmHelper(zt,
4960                               pg,
4961                               addr,
4962                               &MacroAssembler::ld1rh,
4963                               kHRegSizeInBytes);
4964   }
Ld1rw(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4965   void Ld1rw(const ZRegister& zt,
4966              const PRegisterZ& pg,
4967              const SVEMemOperand& addr) {
4968     VIXL_ASSERT(allow_macro_instructions_);
4969     SVELoadBroadcastImmHelper(zt,
4970                               pg,
4971                               addr,
4972                               &MacroAssembler::ld1rw,
4973                               kSRegSizeInBytes);
4974   }
Ld1rd(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)4975   void Ld1rd(const ZRegister& zt,
4976              const PRegisterZ& pg,
4977              const SVEMemOperand& addr) {
4978     VIXL_ASSERT(allow_macro_instructions_);
4979     SVELoadBroadcastImmHelper(zt,
4980                               pg,
4981                               addr,
4982                               &MacroAssembler::ld1rd,
4983                               kDRegSizeInBytes);
4984   }
4985   void Ld1rqb(const ZRegister& zt,
4986               const PRegisterZ& pg,
4987               const SVEMemOperand& addr);
4988   void Ld1rqd(const ZRegister& zt,
4989               const PRegisterZ& pg,
4990               const SVEMemOperand& addr);
4991   void Ld1rqh(const ZRegister& zt,
4992               const PRegisterZ& pg,
4993               const SVEMemOperand& addr);
4994   void Ld1rqw(const ZRegister& zt,
4995               const PRegisterZ& pg,
4996               const SVEMemOperand& addr);
4997   void Ld1rob(const ZRegister& zt,
4998               const PRegisterZ& pg,
4999               const SVEMemOperand& addr);
5000   void Ld1rod(const ZRegister& zt,
5001               const PRegisterZ& pg,
5002               const SVEMemOperand& addr);
5003   void Ld1roh(const ZRegister& zt,
5004               const PRegisterZ& pg,
5005               const SVEMemOperand& addr);
5006   void Ld1row(const ZRegister& zt,
5007               const PRegisterZ& pg,
5008               const SVEMemOperand& addr);
Ld1rsb(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5009   void Ld1rsb(const ZRegister& zt,
5010               const PRegisterZ& pg,
5011               const SVEMemOperand& addr) {
5012     VIXL_ASSERT(allow_macro_instructions_);
5013     SVELoadBroadcastImmHelper(zt,
5014                               pg,
5015                               addr,
5016                               &MacroAssembler::ld1rsb,
5017                               kBRegSizeInBytes);
5018   }
Ld1rsh(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5019   void Ld1rsh(const ZRegister& zt,
5020               const PRegisterZ& pg,
5021               const SVEMemOperand& addr) {
5022     VIXL_ASSERT(allow_macro_instructions_);
5023     SVELoadBroadcastImmHelper(zt,
5024                               pg,
5025                               addr,
5026                               &MacroAssembler::ld1rsh,
5027                               kHRegSizeInBytes);
5028   }
Ld1rsw(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5029   void Ld1rsw(const ZRegister& zt,
5030               const PRegisterZ& pg,
5031               const SVEMemOperand& addr) {
5032     VIXL_ASSERT(allow_macro_instructions_);
5033     SVELoadBroadcastImmHelper(zt,
5034                               pg,
5035                               addr,
5036                               &MacroAssembler::ld1rsw,
5037                               kSRegSizeInBytes);
5038   }
5039   void Ld1sb(const ZRegister& zt,
5040              const PRegisterZ& pg,
5041              const SVEMemOperand& addr);
5042   void Ld1sh(const ZRegister& zt,
5043              const PRegisterZ& pg,
5044              const SVEMemOperand& addr);
5045   void Ld1sw(const ZRegister& zt,
5046              const PRegisterZ& pg,
5047              const SVEMemOperand& addr);
Ld2b(const ZRegister & zt1,const ZRegister & zt2,const PRegisterZ & pg,const SVEMemOperand & addr)5048   void Ld2b(const ZRegister& zt1,
5049             const ZRegister& zt2,
5050             const PRegisterZ& pg,
5051             const SVEMemOperand& addr) {
5052     VIXL_ASSERT(allow_macro_instructions_);
5053     SingleEmissionCheckScope guard(this);
5054     ld2b(zt1, zt2, pg, addr);
5055   }
Ld2h(const ZRegister & zt1,const ZRegister & zt2,const PRegisterZ & pg,const SVEMemOperand & addr)5056   void Ld2h(const ZRegister& zt1,
5057             const ZRegister& zt2,
5058             const PRegisterZ& pg,
5059             const SVEMemOperand& addr) {
5060     VIXL_ASSERT(allow_macro_instructions_);
5061     SingleEmissionCheckScope guard(this);
5062     ld2h(zt1, zt2, pg, addr);
5063   }
Ld2w(const ZRegister & zt1,const ZRegister & zt2,const PRegisterZ & pg,const SVEMemOperand & addr)5064   void Ld2w(const ZRegister& zt1,
5065             const ZRegister& zt2,
5066             const PRegisterZ& pg,
5067             const SVEMemOperand& addr) {
5068     VIXL_ASSERT(allow_macro_instructions_);
5069     SingleEmissionCheckScope guard(this);
5070     ld2w(zt1, zt2, pg, addr);
5071   }
Ld2d(const ZRegister & zt1,const ZRegister & zt2,const PRegisterZ & pg,const SVEMemOperand & addr)5072   void Ld2d(const ZRegister& zt1,
5073             const ZRegister& zt2,
5074             const PRegisterZ& pg,
5075             const SVEMemOperand& addr) {
5076     VIXL_ASSERT(allow_macro_instructions_);
5077     SingleEmissionCheckScope guard(this);
5078     ld2d(zt1, zt2, pg, addr);
5079   }
Ld3b(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const PRegisterZ & pg,const SVEMemOperand & addr)5080   void Ld3b(const ZRegister& zt1,
5081             const ZRegister& zt2,
5082             const ZRegister& zt3,
5083             const PRegisterZ& pg,
5084             const SVEMemOperand& addr) {
5085     VIXL_ASSERT(allow_macro_instructions_);
5086     SingleEmissionCheckScope guard(this);
5087     ld3b(zt1, zt2, zt3, pg, addr);
5088   }
Ld3h(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const PRegisterZ & pg,const SVEMemOperand & addr)5089   void Ld3h(const ZRegister& zt1,
5090             const ZRegister& zt2,
5091             const ZRegister& zt3,
5092             const PRegisterZ& pg,
5093             const SVEMemOperand& addr) {
5094     VIXL_ASSERT(allow_macro_instructions_);
5095     SingleEmissionCheckScope guard(this);
5096     ld3h(zt1, zt2, zt3, pg, addr);
5097   }
Ld3w(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const PRegisterZ & pg,const SVEMemOperand & addr)5098   void Ld3w(const ZRegister& zt1,
5099             const ZRegister& zt2,
5100             const ZRegister& zt3,
5101             const PRegisterZ& pg,
5102             const SVEMemOperand& addr) {
5103     VIXL_ASSERT(allow_macro_instructions_);
5104     SingleEmissionCheckScope guard(this);
5105     ld3w(zt1, zt2, zt3, pg, addr);
5106   }
Ld3d(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const PRegisterZ & pg,const SVEMemOperand & addr)5107   void Ld3d(const ZRegister& zt1,
5108             const ZRegister& zt2,
5109             const ZRegister& zt3,
5110             const PRegisterZ& pg,
5111             const SVEMemOperand& addr) {
5112     VIXL_ASSERT(allow_macro_instructions_);
5113     SingleEmissionCheckScope guard(this);
5114     ld3d(zt1, zt2, zt3, pg, addr);
5115   }
Ld4b(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const ZRegister & zt4,const PRegisterZ & pg,const SVEMemOperand & addr)5116   void Ld4b(const ZRegister& zt1,
5117             const ZRegister& zt2,
5118             const ZRegister& zt3,
5119             const ZRegister& zt4,
5120             const PRegisterZ& pg,
5121             const SVEMemOperand& addr) {
5122     VIXL_ASSERT(allow_macro_instructions_);
5123     SingleEmissionCheckScope guard(this);
5124     ld4b(zt1, zt2, zt3, zt4, pg, addr);
5125   }
Ld4h(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const ZRegister & zt4,const PRegisterZ & pg,const SVEMemOperand & addr)5126   void Ld4h(const ZRegister& zt1,
5127             const ZRegister& zt2,
5128             const ZRegister& zt3,
5129             const ZRegister& zt4,
5130             const PRegisterZ& pg,
5131             const SVEMemOperand& addr) {
5132     VIXL_ASSERT(allow_macro_instructions_);
5133     SingleEmissionCheckScope guard(this);
5134     ld4h(zt1, zt2, zt3, zt4, pg, addr);
5135   }
Ld4w(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const ZRegister & zt4,const PRegisterZ & pg,const SVEMemOperand & addr)5136   void Ld4w(const ZRegister& zt1,
5137             const ZRegister& zt2,
5138             const ZRegister& zt3,
5139             const ZRegister& zt4,
5140             const PRegisterZ& pg,
5141             const SVEMemOperand& addr) {
5142     VIXL_ASSERT(allow_macro_instructions_);
5143     SingleEmissionCheckScope guard(this);
5144     ld4w(zt1, zt2, zt3, zt4, pg, addr);
5145   }
Ld4d(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const ZRegister & zt4,const PRegisterZ & pg,const SVEMemOperand & addr)5146   void Ld4d(const ZRegister& zt1,
5147             const ZRegister& zt2,
5148             const ZRegister& zt3,
5149             const ZRegister& zt4,
5150             const PRegisterZ& pg,
5151             const SVEMemOperand& addr) {
5152     VIXL_ASSERT(allow_macro_instructions_);
5153     SingleEmissionCheckScope guard(this);
5154     ld4d(zt1, zt2, zt3, zt4, pg, addr);
5155   }
5156   void Ldff1b(const ZRegister& zt,
5157               const PRegisterZ& pg,
5158               const SVEMemOperand& addr);
5159   void Ldff1h(const ZRegister& zt,
5160               const PRegisterZ& pg,
5161               const SVEMemOperand& addr);
5162   void Ldff1w(const ZRegister& zt,
5163               const PRegisterZ& pg,
5164               const SVEMemOperand& addr);
5165   void Ldff1d(const ZRegister& zt,
5166               const PRegisterZ& pg,
5167               const SVEMemOperand& addr);
5168   void Ldff1sb(const ZRegister& zt,
5169                const PRegisterZ& pg,
5170                const SVEMemOperand& addr);
5171   void Ldff1sh(const ZRegister& zt,
5172                const PRegisterZ& pg,
5173                const SVEMemOperand& addr);
5174   void Ldff1sw(const ZRegister& zt,
5175                const PRegisterZ& pg,
5176                const SVEMemOperand& addr);
Ldff1b(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)5177   void Ldff1b(const ZRegister& zt,
5178               const PRegisterZ& pg,
5179               const Register& xn,
5180               const ZRegister& zm) {
5181     VIXL_ASSERT(allow_macro_instructions_);
5182     SingleEmissionCheckScope guard(this);
5183     ldff1b(zt, pg, xn, zm);
5184   }
Ldff1b(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)5185   void Ldff1b(const ZRegister& zt,
5186               const PRegisterZ& pg,
5187               const ZRegister& zn,
5188               int imm5) {
5189     VIXL_ASSERT(allow_macro_instructions_);
5190     SingleEmissionCheckScope guard(this);
5191     ldff1b(zt, pg, zn, imm5);
5192   }
Ldff1d(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)5193   void Ldff1d(const ZRegister& zt,
5194               const PRegisterZ& pg,
5195               const Register& xn,
5196               const ZRegister& zm) {
5197     VIXL_ASSERT(allow_macro_instructions_);
5198     SingleEmissionCheckScope guard(this);
5199     ldff1d(zt, pg, xn, zm);
5200   }
Ldff1d(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)5201   void Ldff1d(const ZRegister& zt,
5202               const PRegisterZ& pg,
5203               const ZRegister& zn,
5204               int imm5) {
5205     VIXL_ASSERT(allow_macro_instructions_);
5206     SingleEmissionCheckScope guard(this);
5207     ldff1d(zt, pg, zn, imm5);
5208   }
Ldff1h(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)5209   void Ldff1h(const ZRegister& zt,
5210               const PRegisterZ& pg,
5211               const Register& xn,
5212               const ZRegister& zm) {
5213     VIXL_ASSERT(allow_macro_instructions_);
5214     SingleEmissionCheckScope guard(this);
5215     ldff1h(zt, pg, xn, zm);
5216   }
Ldff1h(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)5217   void Ldff1h(const ZRegister& zt,
5218               const PRegisterZ& pg,
5219               const ZRegister& zn,
5220               int imm5) {
5221     VIXL_ASSERT(allow_macro_instructions_);
5222     SingleEmissionCheckScope guard(this);
5223     ldff1h(zt, pg, zn, imm5);
5224   }
Ldff1sb(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)5225   void Ldff1sb(const ZRegister& zt,
5226                const PRegisterZ& pg,
5227                const Register& xn,
5228                const ZRegister& zm) {
5229     VIXL_ASSERT(allow_macro_instructions_);
5230     SingleEmissionCheckScope guard(this);
5231     ldff1sb(zt, pg, xn, zm);
5232   }
Ldff1sb(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)5233   void Ldff1sb(const ZRegister& zt,
5234                const PRegisterZ& pg,
5235                const ZRegister& zn,
5236                int imm5) {
5237     VIXL_ASSERT(allow_macro_instructions_);
5238     SingleEmissionCheckScope guard(this);
5239     ldff1sb(zt, pg, zn, imm5);
5240   }
Ldff1sh(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)5241   void Ldff1sh(const ZRegister& zt,
5242                const PRegisterZ& pg,
5243                const Register& xn,
5244                const ZRegister& zm) {
5245     VIXL_ASSERT(allow_macro_instructions_);
5246     SingleEmissionCheckScope guard(this);
5247     ldff1sh(zt, pg, xn, zm);
5248   }
Ldff1sh(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)5249   void Ldff1sh(const ZRegister& zt,
5250                const PRegisterZ& pg,
5251                const ZRegister& zn,
5252                int imm5) {
5253     VIXL_ASSERT(allow_macro_instructions_);
5254     SingleEmissionCheckScope guard(this);
5255     ldff1sh(zt, pg, zn, imm5);
5256   }
Ldff1sw(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)5257   void Ldff1sw(const ZRegister& zt,
5258                const PRegisterZ& pg,
5259                const Register& xn,
5260                const ZRegister& zm) {
5261     VIXL_ASSERT(allow_macro_instructions_);
5262     SingleEmissionCheckScope guard(this);
5263     ldff1sw(zt, pg, xn, zm);
5264   }
Ldff1sw(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)5265   void Ldff1sw(const ZRegister& zt,
5266                const PRegisterZ& pg,
5267                const ZRegister& zn,
5268                int imm5) {
5269     VIXL_ASSERT(allow_macro_instructions_);
5270     SingleEmissionCheckScope guard(this);
5271     ldff1sw(zt, pg, zn, imm5);
5272   }
Ldff1w(const ZRegister & zt,const PRegisterZ & pg,const Register & xn,const ZRegister & zm)5273   void Ldff1w(const ZRegister& zt,
5274               const PRegisterZ& pg,
5275               const Register& xn,
5276               const ZRegister& zm) {
5277     VIXL_ASSERT(allow_macro_instructions_);
5278     SingleEmissionCheckScope guard(this);
5279     ldff1w(zt, pg, xn, zm);
5280   }
Ldff1w(const ZRegister & zt,const PRegisterZ & pg,const ZRegister & zn,int imm5)5281   void Ldff1w(const ZRegister& zt,
5282               const PRegisterZ& pg,
5283               const ZRegister& zn,
5284               int imm5) {
5285     VIXL_ASSERT(allow_macro_instructions_);
5286     SingleEmissionCheckScope guard(this);
5287     ldff1w(zt, pg, zn, imm5);
5288   }
Ldnf1b(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5289   void Ldnf1b(const ZRegister& zt,
5290               const PRegisterZ& pg,
5291               const SVEMemOperand& addr) {
5292     VIXL_ASSERT(allow_macro_instructions_);
5293     SingleEmissionCheckScope guard(this);
5294     ldnf1b(zt, pg, addr);
5295   }
Ldnf1d(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5296   void Ldnf1d(const ZRegister& zt,
5297               const PRegisterZ& pg,
5298               const SVEMemOperand& addr) {
5299     VIXL_ASSERT(allow_macro_instructions_);
5300     SingleEmissionCheckScope guard(this);
5301     ldnf1d(zt, pg, addr);
5302   }
Ldnf1h(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5303   void Ldnf1h(const ZRegister& zt,
5304               const PRegisterZ& pg,
5305               const SVEMemOperand& addr) {
5306     VIXL_ASSERT(allow_macro_instructions_);
5307     SingleEmissionCheckScope guard(this);
5308     ldnf1h(zt, pg, addr);
5309   }
Ldnf1sb(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5310   void Ldnf1sb(const ZRegister& zt,
5311                const PRegisterZ& pg,
5312                const SVEMemOperand& addr) {
5313     VIXL_ASSERT(allow_macro_instructions_);
5314     SingleEmissionCheckScope guard(this);
5315     ldnf1sb(zt, pg, addr);
5316   }
Ldnf1sh(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5317   void Ldnf1sh(const ZRegister& zt,
5318                const PRegisterZ& pg,
5319                const SVEMemOperand& addr) {
5320     VIXL_ASSERT(allow_macro_instructions_);
5321     SingleEmissionCheckScope guard(this);
5322     ldnf1sh(zt, pg, addr);
5323   }
Ldnf1sw(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5324   void Ldnf1sw(const ZRegister& zt,
5325                const PRegisterZ& pg,
5326                const SVEMemOperand& addr) {
5327     VIXL_ASSERT(allow_macro_instructions_);
5328     SingleEmissionCheckScope guard(this);
5329     ldnf1sw(zt, pg, addr);
5330   }
Ldnf1w(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)5331   void Ldnf1w(const ZRegister& zt,
5332               const PRegisterZ& pg,
5333               const SVEMemOperand& addr) {
5334     VIXL_ASSERT(allow_macro_instructions_);
5335     SingleEmissionCheckScope guard(this);
5336     ldnf1w(zt, pg, addr);
5337   }
5338   void Ldnt1b(const ZRegister& zt,
5339               const PRegisterZ& pg,
5340               const SVEMemOperand& addr);
5341   void Ldnt1d(const ZRegister& zt,
5342               const PRegisterZ& pg,
5343               const SVEMemOperand& addr);
5344   void Ldnt1h(const ZRegister& zt,
5345               const PRegisterZ& pg,
5346               const SVEMemOperand& addr);
5347   void Ldnt1w(const ZRegister& zt,
5348               const PRegisterZ& pg,
5349               const SVEMemOperand& addr);
Ldr(const CPURegister & rt,const SVEMemOperand & addr)5350   void Ldr(const CPURegister& rt, const SVEMemOperand& addr) {
5351     VIXL_ASSERT(allow_macro_instructions_);
5352     SVELoadStoreScalarImmHelper(rt, addr, &MacroAssembler::ldr);
5353   }
Lsl(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)5354   void Lsl(const ZRegister& zd,
5355            const PRegisterM& pg,
5356            const ZRegister& zn,
5357            int shift) {
5358     VIXL_ASSERT(allow_macro_instructions_);
5359     MovprfxHelperScope guard(this, zd, pg, zn);
5360     lsl(zd, pg, zd, shift);
5361   }
5362   void Lsl(const ZRegister& zd,
5363            const PRegisterM& pg,
5364            const ZRegister& zn,
5365            const ZRegister& zm);
Lsl(const ZRegister & zd,const ZRegister & zn,int shift)5366   void Lsl(const ZRegister& zd, const ZRegister& zn, int shift) {
5367     VIXL_ASSERT(allow_macro_instructions_);
5368     SingleEmissionCheckScope guard(this);
5369     lsl(zd, zn, shift);
5370   }
Lsl(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)5371   void Lsl(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
5372     VIXL_ASSERT(allow_macro_instructions_);
5373     SingleEmissionCheckScope guard(this);
5374     lsl(zd, zn, zm);
5375   }
Lsr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)5376   void Lsr(const ZRegister& zd,
5377            const PRegisterM& pg,
5378            const ZRegister& zn,
5379            int shift) {
5380     VIXL_ASSERT(allow_macro_instructions_);
5381     MovprfxHelperScope guard(this, zd, pg, zn);
5382     lsr(zd, pg, zd, shift);
5383   }
5384   void Lsr(const ZRegister& zd,
5385            const PRegisterM& pg,
5386            const ZRegister& zn,
5387            const ZRegister& zm);
Lsr(const ZRegister & zd,const ZRegister & zn,int shift)5388   void Lsr(const ZRegister& zd, const ZRegister& zn, int shift) {
5389     VIXL_ASSERT(allow_macro_instructions_);
5390     SingleEmissionCheckScope guard(this);
5391     lsr(zd, zn, shift);
5392   }
Lsr(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)5393   void Lsr(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
5394     VIXL_ASSERT(allow_macro_instructions_);
5395     SingleEmissionCheckScope guard(this);
5396     lsr(zd, zn, zm);
5397   }
Mov(const PRegister & pd,const PRegister & pn)5398   void Mov(const PRegister& pd, const PRegister& pn) {
5399     VIXL_ASSERT(allow_macro_instructions_);
5400     SingleEmissionCheckScope guard(this);
5401     mov(pd.VnB(), pn.VnB());
5402   }
Mov(const PRegisterWithLaneSize & pd,const PRegisterM & pg,const PRegisterWithLaneSize & pn)5403   void Mov(const PRegisterWithLaneSize& pd,
5404            const PRegisterM& pg,
5405            const PRegisterWithLaneSize& pn) {
5406     VIXL_ASSERT(allow_macro_instructions_);
5407     SingleEmissionCheckScope guard(this);
5408     mov(pd, pg, pn);
5409   }
Mov(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn)5410   void Mov(const PRegisterWithLaneSize& pd,
5411            const PRegisterZ& pg,
5412            const PRegisterWithLaneSize& pn) {
5413     VIXL_ASSERT(allow_macro_instructions_);
5414     SingleEmissionCheckScope guard(this);
5415     mov(pd, pg, pn);
5416   }
Mov(const ZRegister & zd,const Register & xn)5417   void Mov(const ZRegister& zd, const Register& xn) {
5418     VIXL_ASSERT(allow_macro_instructions_);
5419     SingleEmissionCheckScope guard(this);
5420     mov(zd, xn);
5421   }
5422 
Mov(const ZRegister & zd,const VRegister & vn)5423   void Mov(const ZRegister& zd, const VRegister& vn) {
5424     VIXL_ASSERT(allow_macro_instructions_);
5425     SingleEmissionCheckScope guard(this);
5426     mov(zd, vn);
5427   }
5428 
Mov(const ZRegister & zd,const ZRegister & zn)5429   void Mov(const ZRegister& zd, const ZRegister& zn) {
5430     VIXL_ASSERT(allow_macro_instructions_);
5431     SingleEmissionCheckScope guard(this);
5432     mov(zd, zn);
5433   }
Mov(const ZRegister & zd,const ZRegister & zn,unsigned index)5434   void Mov(const ZRegister& zd, const ZRegister& zn, unsigned index) {
5435     VIXL_ASSERT(allow_macro_instructions_);
5436     SingleEmissionCheckScope guard(this);
5437     mov(zd, zn, index);
5438   }
Mov(const ZRegister & zd,const PRegister & pg,IntegerOperand imm)5439   void Mov(const ZRegister& zd, const PRegister& pg, IntegerOperand imm) {
5440     VIXL_ASSERT(allow_macro_instructions_);
5441     Cpy(zd, pg, imm);
5442   }
5443   // TODO: support zeroing predicated moves using movprfx.
Mov(const ZRegister & zd,const PRegisterM & pg,const Register & rn)5444   void Mov(const ZRegister& zd, const PRegisterM& pg, const Register& rn) {
5445     VIXL_ASSERT(allow_macro_instructions_);
5446     SingleEmissionCheckScope guard(this);
5447     mov(zd, pg, rn);
5448   }
Mov(const ZRegister & zd,const PRegisterM & pg,const VRegister & vn)5449   void Mov(const ZRegister& zd, const PRegisterM& pg, const VRegister& vn) {
5450     VIXL_ASSERT(allow_macro_instructions_);
5451     SingleEmissionCheckScope guard(this);
5452     mov(zd, pg, vn);
5453   }
Mov(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)5454   void Mov(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
5455     VIXL_ASSERT(allow_macro_instructions_);
5456     SingleEmissionCheckScope guard(this);
5457     mov(zd, pg, zn);
5458   }
Mov(const ZRegister & zd,IntegerOperand imm)5459   void Mov(const ZRegister& zd, IntegerOperand imm) {
5460     VIXL_ASSERT(allow_macro_instructions_);
5461     Dup(zd, imm);
5462   }
Movs(const PRegister & pd,const PRegister & pn)5463   void Movs(const PRegister& pd, const PRegister& pn) {
5464     VIXL_ASSERT(allow_macro_instructions_);
5465     SingleEmissionCheckScope guard(this);
5466     movs(pd, pn);
5467   }
Movs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn)5468   void Movs(const PRegisterWithLaneSize& pd,
5469             const PRegisterZ& pg,
5470             const PRegisterWithLaneSize& pn) {
5471     VIXL_ASSERT(allow_macro_instructions_);
5472     SingleEmissionCheckScope guard(this);
5473     movs(pd, pg, pn);
5474   }
5475   // zd = za + (zn * zm)
5476   void Mla(const ZRegister& zd,
5477            const PRegisterM& pg,
5478            const ZRegister& za,
5479            const ZRegister& zn,
5480            const ZRegister& zm);
5481   // zd = za - (zn * zm)
5482   void Mls(const ZRegister& zd,
5483            const PRegisterM& pg,
5484            const ZRegister& za,
5485            const ZRegister& zn,
5486            const ZRegister& zm);
5487   void Mul(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm);
Nand(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5488   void Nand(const PRegisterWithLaneSize& pd,
5489             const PRegisterZ& pg,
5490             const PRegisterWithLaneSize& pn,
5491             const PRegisterWithLaneSize& pm) {
5492     VIXL_ASSERT(allow_macro_instructions_);
5493     SingleEmissionCheckScope guard(this);
5494     nand(pd, pg, pn, pm);
5495   }
Nands(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5496   void Nands(const PRegisterWithLaneSize& pd,
5497              const PRegisterZ& pg,
5498              const PRegisterWithLaneSize& pn,
5499              const PRegisterWithLaneSize& pm) {
5500     VIXL_ASSERT(allow_macro_instructions_);
5501     SingleEmissionCheckScope guard(this);
5502     nands(pd, pg, pn, pm);
5503   }
5504   // There is no instruction with this form, but we can implement it using
5505   // `subr`.
Neg(const ZRegister & zd,const ZRegister & zn)5506   void Neg(const ZRegister& zd, const ZRegister& zn) {
5507     VIXL_ASSERT(allow_macro_instructions_);
5508     MovprfxHelperScope guard(this, zd, zn);
5509     subr(zd, zd, 0);
5510   }
Neg(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)5511   void Neg(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
5512     VIXL_ASSERT(allow_macro_instructions_);
5513     SingleEmissionCheckScope guard(this);
5514     neg(zd, pg, zn);
5515   }
Nor(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5516   void Nor(const PRegisterWithLaneSize& pd,
5517            const PRegisterZ& pg,
5518            const PRegisterWithLaneSize& pn,
5519            const PRegisterWithLaneSize& pm) {
5520     VIXL_ASSERT(allow_macro_instructions_);
5521     SingleEmissionCheckScope guard(this);
5522     nor(pd, pg, pn, pm);
5523   }
Nors(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5524   void Nors(const PRegisterWithLaneSize& pd,
5525             const PRegisterZ& pg,
5526             const PRegisterWithLaneSize& pn,
5527             const PRegisterWithLaneSize& pm) {
5528     VIXL_ASSERT(allow_macro_instructions_);
5529     SingleEmissionCheckScope guard(this);
5530     nors(pd, pg, pn, pm);
5531   }
Not(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn)5532   void Not(const PRegisterWithLaneSize& pd,
5533            const PRegisterZ& pg,
5534            const PRegisterWithLaneSize& pn) {
5535     VIXL_ASSERT(allow_macro_instructions_);
5536     SingleEmissionCheckScope guard(this);
5537     not_(pd, pg, pn);
5538   }
Not(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)5539   void Not(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
5540     VIXL_ASSERT(allow_macro_instructions_);
5541     SingleEmissionCheckScope guard(this);
5542     not_(zd, pg, zn);
5543   }
Nots(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn)5544   void Nots(const PRegisterWithLaneSize& pd,
5545             const PRegisterZ& pg,
5546             const PRegisterWithLaneSize& pn) {
5547     VIXL_ASSERT(allow_macro_instructions_);
5548     SingleEmissionCheckScope guard(this);
5549     nots(pd, pg, pn);
5550   }
Orn(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5551   void Orn(const PRegisterWithLaneSize& pd,
5552            const PRegisterZ& pg,
5553            const PRegisterWithLaneSize& pn,
5554            const PRegisterWithLaneSize& pm) {
5555     VIXL_ASSERT(allow_macro_instructions_);
5556     SingleEmissionCheckScope guard(this);
5557     orn(pd, pg, pn, pm);
5558   }
Orn(const ZRegister & zd,const ZRegister & zn,uint64_t imm)5559   void Orn(const ZRegister& zd, const ZRegister& zn, uint64_t imm) {
5560     VIXL_ASSERT(allow_macro_instructions_);
5561     SingleEmissionCheckScope guard(this);
5562     if (IsImmLogical(imm, zd.GetLaneSizeInBits())) {
5563       orn(zd, zn, imm);
5564     } else {
5565       // TODO: Synthesise the immediate once 'Mov' is implemented.
5566       VIXL_UNIMPLEMENTED();
5567     }
5568   }
Orns(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5569   void Orns(const PRegisterWithLaneSize& pd,
5570             const PRegisterZ& pg,
5571             const PRegisterWithLaneSize& pn,
5572             const PRegisterWithLaneSize& pm) {
5573     VIXL_ASSERT(allow_macro_instructions_);
5574     SingleEmissionCheckScope guard(this);
5575     orns(pd, pg, pn, pm);
5576   }
Orr(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5577   void Orr(const PRegisterWithLaneSize& pd,
5578            const PRegisterZ& pg,
5579            const PRegisterWithLaneSize& pn,
5580            const PRegisterWithLaneSize& pm) {
5581     VIXL_ASSERT(allow_macro_instructions_);
5582     SingleEmissionCheckScope guard(this);
5583     orr(pd, pg, pn, pm);
5584   }
Orr(const ZRegister & zd,const ZRegister & zn,uint64_t imm)5585   void Orr(const ZRegister& zd, const ZRegister& zn, uint64_t imm) {
5586     VIXL_ASSERT(allow_macro_instructions_);
5587     SingleEmissionCheckScope guard(this);
5588     if (IsImmLogical(imm, zd.GetLaneSizeInBits())) {
5589       orr(zd, zn, imm);
5590     } else {
5591       // TODO: Synthesise the immediate once 'Mov' is implemented.
5592       VIXL_UNIMPLEMENTED();
5593     }
5594   }
Orr(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)5595   void Orr(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
5596     VIXL_ASSERT(allow_macro_instructions_);
5597     VIXL_ASSERT(AreSameLaneSize(zd, zn, zm));
5598     SingleEmissionCheckScope guard(this);
5599     orr(zd.VnD(), zn.VnD(), zm.VnD());
5600   }
Orrs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5601   void Orrs(const PRegisterWithLaneSize& pd,
5602             const PRegisterZ& pg,
5603             const PRegisterWithLaneSize& pn,
5604             const PRegisterWithLaneSize& pm) {
5605     VIXL_ASSERT(allow_macro_instructions_);
5606     SingleEmissionCheckScope guard(this);
5607     orrs(pd, pg, pn, pm);
5608   }
Orv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)5609   void Orv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
5610     VIXL_ASSERT(allow_macro_instructions_);
5611     SingleEmissionCheckScope guard(this);
5612     orv(vd, pg, zn);
5613   }
Pfalse(const PRegister & pd)5614   void Pfalse(const PRegister& pd) {
5615     VIXL_ASSERT(allow_macro_instructions_);
5616     VIXL_ASSERT(pd.IsUnqualified());
5617     SingleEmissionCheckScope guard(this);
5618     // No matter what the lane size is, overall this operation just writes zeros
5619     // throughout the register.
5620     pfalse(pd.VnB());
5621   }
5622   void Pfirst(const PRegisterWithLaneSize& pd,
5623               const PRegister& pg,
5624               const PRegisterWithLaneSize& pn);
5625   void Pnext(const PRegisterWithLaneSize& pd,
5626              const PRegister& pg,
5627              const PRegisterWithLaneSize& pn);
Prfb(PrefetchOperation prfop,const PRegister & pg,const SVEMemOperand addr)5628   void Prfb(PrefetchOperation prfop,
5629             const PRegister& pg,
5630             const SVEMemOperand addr) {
5631     VIXL_ASSERT(allow_macro_instructions_);
5632     SingleEmissionCheckScope guard(this);
5633     prfb(prfop, pg, addr);
5634   }
Prfh(PrefetchOperation prfop,const PRegister & pg,const SVEMemOperand addr)5635   void Prfh(PrefetchOperation prfop,
5636             const PRegister& pg,
5637             const SVEMemOperand addr) {
5638     VIXL_ASSERT(allow_macro_instructions_);
5639     SingleEmissionCheckScope guard(this);
5640     prfh(prfop, pg, addr);
5641   }
Prfw(PrefetchOperation prfop,const PRegister & pg,const SVEMemOperand addr)5642   void Prfw(PrefetchOperation prfop,
5643             const PRegister& pg,
5644             const SVEMemOperand addr) {
5645     VIXL_ASSERT(allow_macro_instructions_);
5646     SingleEmissionCheckScope guard(this);
5647     prfw(prfop, pg, addr);
5648   }
Prfd(PrefetchOperation prfop,const PRegister & pg,const SVEMemOperand addr)5649   void Prfd(PrefetchOperation prfop,
5650             const PRegister& pg,
5651             const SVEMemOperand addr) {
5652     VIXL_ASSERT(allow_macro_instructions_);
5653     SingleEmissionCheckScope guard(this);
5654     prfd(prfop, pg, addr);
5655   }
Ptest(const PRegister & pg,const PRegisterWithLaneSize & pn)5656   void Ptest(const PRegister& pg, const PRegisterWithLaneSize& pn) {
5657     VIXL_ASSERT(allow_macro_instructions_);
5658     SingleEmissionCheckScope guard(this);
5659     ptest(pg, pn);
5660   }
5661   void Ptrue(const PRegisterWithLaneSize& pd,
5662              SVEPredicateConstraint pattern,
5663              FlagsUpdate s);
5664   void Ptrue(const PRegisterWithLaneSize& pd,
5665              SVEPredicateConstraint pattern = SVE_ALL) {
5666     VIXL_ASSERT(allow_macro_instructions_);
5667     SingleEmissionCheckScope guard(this);
5668     ptrue(pd, pattern);
5669   }
5670   void Ptrues(const PRegisterWithLaneSize& pd,
5671               SVEPredicateConstraint pattern = SVE_ALL) {
5672     VIXL_ASSERT(allow_macro_instructions_);
5673     SingleEmissionCheckScope guard(this);
5674     ptrues(pd, pattern);
5675   }
Punpkhi(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn)5676   void Punpkhi(const PRegisterWithLaneSize& pd,
5677                const PRegisterWithLaneSize& pn) {
5678     VIXL_ASSERT(allow_macro_instructions_);
5679     SingleEmissionCheckScope guard(this);
5680     punpkhi(pd, pn);
5681   }
Punpklo(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn)5682   void Punpklo(const PRegisterWithLaneSize& pd,
5683                const PRegisterWithLaneSize& pn) {
5684     VIXL_ASSERT(allow_macro_instructions_);
5685     SingleEmissionCheckScope guard(this);
5686     punpklo(pd, pn);
5687   }
Rbit(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)5688   void Rbit(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
5689     VIXL_ASSERT(allow_macro_instructions_);
5690     SingleEmissionCheckScope guard(this);
5691     rbit(zd, pg, zn);
5692   }
Rdffr(const PRegister & pd)5693   void Rdffr(const PRegister& pd) {
5694     VIXL_ASSERT(allow_macro_instructions_);
5695     // Although this is essentially just a move, it writes every bit and so can
5696     // only support b-sized lane because other lane sizes would simplicity clear
5697     // bits in `pd`.
5698     VIXL_ASSERT(!pd.HasLaneSize() || pd.IsLaneSizeB());
5699     VIXL_ASSERT(pd.IsUnqualified());
5700     SingleEmissionCheckScope guard(this);
5701     rdffr(pd.VnB());
5702   }
Rdffr(const PRegisterWithLaneSize & pd,const PRegisterZ & pg)5703   void Rdffr(const PRegisterWithLaneSize& pd, const PRegisterZ& pg) {
5704     VIXL_ASSERT(allow_macro_instructions_);
5705     SingleEmissionCheckScope guard(this);
5706     rdffr(pd, pg);
5707   }
Rdffrs(const PRegisterWithLaneSize & pd,const PRegisterZ & pg)5708   void Rdffrs(const PRegisterWithLaneSize& pd, const PRegisterZ& pg) {
5709     VIXL_ASSERT(allow_macro_instructions_);
5710     SingleEmissionCheckScope guard(this);
5711     rdffrs(pd, pg);
5712   }
5713   // Note that there is no `rdpl` instruction, but this macro emulates it (for
5714   // symmetry with `Rdvl`).
Rdpl(const Register & xd,int64_t multiplier)5715   void Rdpl(const Register& xd, int64_t multiplier) {
5716     VIXL_ASSERT(allow_macro_instructions_);
5717     Addpl(xd, xzr, multiplier);
5718   }
Rdvl(const Register & xd,int64_t multiplier)5719   void Rdvl(const Register& xd, int64_t multiplier) {
5720     VIXL_ASSERT(allow_macro_instructions_);
5721     Addvl(xd, xzr, multiplier);
5722   }
Rev(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn)5723   void Rev(const PRegisterWithLaneSize& pd, const PRegisterWithLaneSize& pn) {
5724     VIXL_ASSERT(allow_macro_instructions_);
5725     SingleEmissionCheckScope guard(this);
5726     rev(pd, pn);
5727   }
Rev(const ZRegister & zd,const ZRegister & zn)5728   void Rev(const ZRegister& zd, const ZRegister& zn) {
5729     VIXL_ASSERT(allow_macro_instructions_);
5730     SingleEmissionCheckScope guard(this);
5731     rev(zd, zn);
5732   }
Revb(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)5733   void Revb(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
5734     VIXL_ASSERT(allow_macro_instructions_);
5735     SingleEmissionCheckScope guard(this);
5736     revb(zd, pg, zn);
5737   }
Revh(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)5738   void Revh(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
5739     VIXL_ASSERT(allow_macro_instructions_);
5740     SingleEmissionCheckScope guard(this);
5741     revh(zd, pg, zn);
5742   }
Revw(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)5743   void Revw(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
5744     VIXL_ASSERT(allow_macro_instructions_);
5745     SingleEmissionCheckScope guard(this);
5746     revw(zd, pg, zn);
5747   }
Saddv(const VRegister & dd,const PRegister & pg,const ZRegister & zn)5748   void Saddv(const VRegister& dd, const PRegister& pg, const ZRegister& zn) {
5749     VIXL_ASSERT(allow_macro_instructions_);
5750     SingleEmissionCheckScope guard(this);
5751     saddv(dd, pg, zn);
5752   }
Scvtf(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)5753   void Scvtf(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
5754     VIXL_ASSERT(allow_macro_instructions_);
5755     SingleEmissionCheckScope guard(this);
5756     scvtf(zd, pg, zn);
5757   }
5758   void Sdiv(const ZRegister& zd,
5759             const PRegisterM& pg,
5760             const ZRegister& zn,
5761             const ZRegister& zm);
5762   void Sdot(const ZRegister& zd,
5763             const ZRegister& za,
5764             const ZRegister& zn,
5765             const ZRegister& zm);
5766   void Sdot(const ZRegister& zd,
5767             const ZRegister& za,
5768             const ZRegister& zn,
5769             const ZRegister& zm,
5770             int index);
Sel(const PRegisterWithLaneSize & pd,const PRegister & pg,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)5771   void Sel(const PRegisterWithLaneSize& pd,
5772            const PRegister& pg,
5773            const PRegisterWithLaneSize& pn,
5774            const PRegisterWithLaneSize& pm) {
5775     VIXL_ASSERT(allow_macro_instructions_);
5776     SingleEmissionCheckScope guard(this);
5777     sel(pd, pg, pn, pm);
5778   }
Sel(const ZRegister & zd,const PRegister & pg,const ZRegister & zn,const ZRegister & zm)5779   void Sel(const ZRegister& zd,
5780            const PRegister& pg,
5781            const ZRegister& zn,
5782            const ZRegister& zm) {
5783     VIXL_ASSERT(allow_macro_instructions_);
5784     SingleEmissionCheckScope guard(this);
5785     sel(zd, pg, zn, zm);
5786   }
Setffr()5787   void Setffr() {
5788     VIXL_ASSERT(allow_macro_instructions_);
5789     SingleEmissionCheckScope guard(this);
5790     setffr();
5791   }
5792   void Smax(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm);
Smaxv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)5793   void Smaxv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
5794     VIXL_ASSERT(allow_macro_instructions_);
5795     SingleEmissionCheckScope guard(this);
5796     smaxv(vd, pg, zn);
5797   }
5798   void Smin(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm);
Sminv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)5799   void Sminv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
5800     VIXL_ASSERT(allow_macro_instructions_);
5801     SingleEmissionCheckScope guard(this);
5802     sminv(vd, pg, zn);
5803   }
5804   void Splice(const ZRegister& zd,
5805               const PRegister& pg,
5806               const ZRegister& zn,
5807               const ZRegister& zm);
Sqadd(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)5808   void Sqadd(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
5809     VIXL_ASSERT(allow_macro_instructions_);
5810     SingleEmissionCheckScope guard(this);
5811     sqadd(zd, zn, zm);
5812   }
Sqadd(const ZRegister & zd,const ZRegister & zn,IntegerOperand imm)5813   void Sqadd(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm) {
5814     VIXL_ASSERT(allow_macro_instructions_);
5815     VIXL_ASSERT(imm.IsUint8() ||
5816                 (imm.IsUint16() && ((imm.AsUint16() & 0xff) == 0)));
5817     MovprfxHelperScope guard(this, zd, zn);
5818     sqadd(zd, zd, imm.AsUint16());
5819   }
5820   void Sqdecb(const Register& xd,
5821               const Register& wn,
5822               int pattern = SVE_ALL,
5823               int multiplier = 1) {
5824     VIXL_ASSERT(allow_macro_instructions_);
5825     SingleEmissionCheckScope guard(this);
5826     sqdecb(xd, wn, pattern, multiplier);
5827   }
5828   void Sqdecb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
5829     VIXL_ASSERT(allow_macro_instructions_);
5830     SingleEmissionCheckScope guard(this);
5831     sqdecb(rdn, pattern, multiplier);
5832   }
5833   void Sqdecd(const Register& xd,
5834               const Register& wn,
5835               int pattern = SVE_ALL,
5836               int multiplier = 1) {
5837     VIXL_ASSERT(allow_macro_instructions_);
5838     SingleEmissionCheckScope guard(this);
5839     sqdecd(xd, wn, pattern, multiplier);
5840   }
5841   void Sqdecd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
5842     VIXL_ASSERT(allow_macro_instructions_);
5843     SingleEmissionCheckScope guard(this);
5844     sqdecd(rdn, pattern, multiplier);
5845   }
5846   void Sqdecd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
5847     VIXL_ASSERT(allow_macro_instructions_);
5848     SingleEmissionCheckScope guard(this);
5849     sqdecd(zdn, pattern, multiplier);
5850   }
5851   void Sqdech(const Register& xd,
5852               const Register& wn,
5853               int pattern = SVE_ALL,
5854               int multiplier = 1) {
5855     VIXL_ASSERT(allow_macro_instructions_);
5856     SingleEmissionCheckScope guard(this);
5857     sqdech(xd, wn, pattern, multiplier);
5858   }
5859   void Sqdech(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
5860     VIXL_ASSERT(allow_macro_instructions_);
5861     SingleEmissionCheckScope guard(this);
5862     sqdech(rdn, pattern, multiplier);
5863   }
5864   void Sqdech(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
5865     VIXL_ASSERT(allow_macro_instructions_);
5866     SingleEmissionCheckScope guard(this);
5867     sqdech(zdn, pattern, multiplier);
5868   }
Sqdecp(const Register & xdn,const PRegisterWithLaneSize & pg,const Register & wdn)5869   void Sqdecp(const Register& xdn,
5870               const PRegisterWithLaneSize& pg,
5871               const Register& wdn) {
5872     VIXL_ASSERT(allow_macro_instructions_);
5873     SingleEmissionCheckScope guard(this);
5874     sqdecp(xdn, pg, wdn);
5875   }
Sqdecp(const Register & xdn,const PRegisterWithLaneSize & pg)5876   void Sqdecp(const Register& xdn, const PRegisterWithLaneSize& pg) {
5877     VIXL_ASSERT(allow_macro_instructions_);
5878     SingleEmissionCheckScope guard(this);
5879     sqdecp(xdn, pg);
5880   }
Sqdecp(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)5881   void Sqdecp(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) {
5882     VIXL_ASSERT(allow_macro_instructions_);
5883     VIXL_ASSERT(AreSameFormat(zd, zn));
5884     // `sqdecp` writes every lane, so use an unpredicated movprfx.
5885     MovprfxHelperScope guard(this, zd, zn);
5886     sqdecp(zd, pg);
5887   }
Sqdecp(const ZRegister & zdn,const PRegister & pg)5888   void Sqdecp(const ZRegister& zdn, const PRegister& pg) {
5889     Sqdecp(zdn, pg, zdn);
5890   }
5891   void Sqdecw(const Register& xd,
5892               const Register& wn,
5893               int pattern = SVE_ALL,
5894               int multiplier = 1) {
5895     VIXL_ASSERT(allow_macro_instructions_);
5896     SingleEmissionCheckScope guard(this);
5897     sqdecw(xd, wn, pattern, multiplier);
5898   }
5899   void Sqdecw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
5900     VIXL_ASSERT(allow_macro_instructions_);
5901     SingleEmissionCheckScope guard(this);
5902     sqdecw(rdn, pattern, multiplier);
5903   }
5904   void Sqdecw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
5905     VIXL_ASSERT(allow_macro_instructions_);
5906     SingleEmissionCheckScope guard(this);
5907     sqdecw(zdn, pattern, multiplier);
5908   }
5909   void Sqincb(const Register& xd,
5910               const Register& wn,
5911               int pattern = SVE_ALL,
5912               int multiplier = 1) {
5913     VIXL_ASSERT(allow_macro_instructions_);
5914     SingleEmissionCheckScope guard(this);
5915     sqincb(xd, wn, pattern, multiplier);
5916   }
5917   void Sqincb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
5918     VIXL_ASSERT(allow_macro_instructions_);
5919     SingleEmissionCheckScope guard(this);
5920     sqincb(rdn, pattern, multiplier);
5921   }
5922   void Sqincd(const Register& xd,
5923               const Register& wn,
5924               int pattern = SVE_ALL,
5925               int multiplier = 1) {
5926     VIXL_ASSERT(allow_macro_instructions_);
5927     SingleEmissionCheckScope guard(this);
5928     sqincd(xd, wn, pattern, multiplier);
5929   }
5930   void Sqincd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
5931     VIXL_ASSERT(allow_macro_instructions_);
5932     SingleEmissionCheckScope guard(this);
5933     sqincd(rdn, pattern, multiplier);
5934   }
5935   void Sqincd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
5936     VIXL_ASSERT(allow_macro_instructions_);
5937     SingleEmissionCheckScope guard(this);
5938     sqincd(zdn, pattern, multiplier);
5939   }
5940   void Sqinch(const Register& xd,
5941               const Register& wn,
5942               int pattern = SVE_ALL,
5943               int multiplier = 1) {
5944     VIXL_ASSERT(allow_macro_instructions_);
5945     SingleEmissionCheckScope guard(this);
5946     sqinch(xd, wn, pattern, multiplier);
5947   }
5948   void Sqinch(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
5949     VIXL_ASSERT(allow_macro_instructions_);
5950     SingleEmissionCheckScope guard(this);
5951     sqinch(rdn, pattern, multiplier);
5952   }
5953   void Sqinch(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
5954     VIXL_ASSERT(allow_macro_instructions_);
5955     SingleEmissionCheckScope guard(this);
5956     sqinch(zdn, pattern, multiplier);
5957   }
Sqincp(const Register & xdn,const PRegisterWithLaneSize & pg,const Register & wdn)5958   void Sqincp(const Register& xdn,
5959               const PRegisterWithLaneSize& pg,
5960               const Register& wdn) {
5961     VIXL_ASSERT(allow_macro_instructions_);
5962     SingleEmissionCheckScope guard(this);
5963     sqincp(xdn, pg, wdn);
5964   }
Sqincp(const Register & xdn,const PRegisterWithLaneSize & pg)5965   void Sqincp(const Register& xdn, const PRegisterWithLaneSize& pg) {
5966     VIXL_ASSERT(allow_macro_instructions_);
5967     SingleEmissionCheckScope guard(this);
5968     sqincp(xdn, pg);
5969   }
Sqincp(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)5970   void Sqincp(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) {
5971     VIXL_ASSERT(allow_macro_instructions_);
5972     VIXL_ASSERT(AreSameFormat(zd, zn));
5973     // `sqincp` writes every lane, so use an unpredicated movprfx.
5974     MovprfxHelperScope guard(this, zd, zn);
5975     sqincp(zd, pg);
5976   }
Sqincp(const ZRegister & zdn,const PRegister & pg)5977   void Sqincp(const ZRegister& zdn, const PRegister& pg) {
5978     Sqincp(zdn, pg, zdn);
5979   }
5980   void Sqincw(const Register& xd,
5981               const Register& wn,
5982               int pattern = SVE_ALL,
5983               int multiplier = 1) {
5984     VIXL_ASSERT(allow_macro_instructions_);
5985     SingleEmissionCheckScope guard(this);
5986     sqincw(xd, wn, pattern, multiplier);
5987   }
5988   void Sqincw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
5989     VIXL_ASSERT(allow_macro_instructions_);
5990     SingleEmissionCheckScope guard(this);
5991     sqincw(rdn, pattern, multiplier);
5992   }
5993   void Sqincw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
5994     VIXL_ASSERT(allow_macro_instructions_);
5995     SingleEmissionCheckScope guard(this);
5996     sqincw(zdn, pattern, multiplier);
5997   }
Sqsub(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)5998   void Sqsub(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
5999     VIXL_ASSERT(allow_macro_instructions_);
6000     SingleEmissionCheckScope guard(this);
6001     sqsub(zd, zn, zm);
6002   }
Sqsub(const ZRegister & zd,const ZRegister & zn,IntegerOperand imm)6003   void Sqsub(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm) {
6004     VIXL_ASSERT(allow_macro_instructions_);
6005     VIXL_ASSERT(imm.IsUint8() ||
6006                 (imm.IsUint16() && ((imm.AsUint16() & 0xff) == 0)));
6007     MovprfxHelperScope guard(this, zd, zn);
6008     sqsub(zd, zd, imm.AsUint16());
6009   }
6010   void St1b(const ZRegister& zt,
6011             const PRegister& pg,
6012             const SVEMemOperand& addr);
6013   void St1h(const ZRegister& zt,
6014             const PRegister& pg,
6015             const SVEMemOperand& addr);
6016   void St1w(const ZRegister& zt,
6017             const PRegister& pg,
6018             const SVEMemOperand& addr);
6019   void St1d(const ZRegister& zt,
6020             const PRegister& pg,
6021             const SVEMemOperand& addr);
St2b(const ZRegister & zt1,const ZRegister & zt2,const PRegister & pg,const SVEMemOperand & addr)6022   void St2b(const ZRegister& zt1,
6023             const ZRegister& zt2,
6024             const PRegister& pg,
6025             const SVEMemOperand& addr) {
6026     VIXL_ASSERT(allow_macro_instructions_);
6027     SingleEmissionCheckScope guard(this);
6028     st2b(zt1, zt2, pg, addr);
6029   }
St2h(const ZRegister & zt1,const ZRegister & zt2,const PRegister & pg,const SVEMemOperand & addr)6030   void St2h(const ZRegister& zt1,
6031             const ZRegister& zt2,
6032             const PRegister& pg,
6033             const SVEMemOperand& addr) {
6034     VIXL_ASSERT(allow_macro_instructions_);
6035     SingleEmissionCheckScope guard(this);
6036     st2h(zt1, zt2, pg, addr);
6037   }
St2w(const ZRegister & zt1,const ZRegister & zt2,const PRegister & pg,const SVEMemOperand & addr)6038   void St2w(const ZRegister& zt1,
6039             const ZRegister& zt2,
6040             const PRegister& pg,
6041             const SVEMemOperand& addr) {
6042     VIXL_ASSERT(allow_macro_instructions_);
6043     SingleEmissionCheckScope guard(this);
6044     st2w(zt1, zt2, pg, addr);
6045   }
St2d(const ZRegister & zt1,const ZRegister & zt2,const PRegister & pg,const SVEMemOperand & addr)6046   void St2d(const ZRegister& zt1,
6047             const ZRegister& zt2,
6048             const PRegister& pg,
6049             const SVEMemOperand& addr) {
6050     VIXL_ASSERT(allow_macro_instructions_);
6051     SingleEmissionCheckScope guard(this);
6052     st2d(zt1, zt2, pg, addr);
6053   }
St3b(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const PRegister & pg,const SVEMemOperand & addr)6054   void St3b(const ZRegister& zt1,
6055             const ZRegister& zt2,
6056             const ZRegister& zt3,
6057             const PRegister& pg,
6058             const SVEMemOperand& addr) {
6059     VIXL_ASSERT(allow_macro_instructions_);
6060     SingleEmissionCheckScope guard(this);
6061     st3b(zt1, zt2, zt3, pg, addr);
6062   }
St3h(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const PRegister & pg,const SVEMemOperand & addr)6063   void St3h(const ZRegister& zt1,
6064             const ZRegister& zt2,
6065             const ZRegister& zt3,
6066             const PRegister& pg,
6067             const SVEMemOperand& addr) {
6068     VIXL_ASSERT(allow_macro_instructions_);
6069     SingleEmissionCheckScope guard(this);
6070     st3h(zt1, zt2, zt3, pg, addr);
6071   }
St3w(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const PRegister & pg,const SVEMemOperand & addr)6072   void St3w(const ZRegister& zt1,
6073             const ZRegister& zt2,
6074             const ZRegister& zt3,
6075             const PRegister& pg,
6076             const SVEMemOperand& addr) {
6077     VIXL_ASSERT(allow_macro_instructions_);
6078     SingleEmissionCheckScope guard(this);
6079     st3w(zt1, zt2, zt3, pg, addr);
6080   }
St3d(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const PRegister & pg,const SVEMemOperand & addr)6081   void St3d(const ZRegister& zt1,
6082             const ZRegister& zt2,
6083             const ZRegister& zt3,
6084             const PRegister& pg,
6085             const SVEMemOperand& addr) {
6086     VIXL_ASSERT(allow_macro_instructions_);
6087     SingleEmissionCheckScope guard(this);
6088     st3d(zt1, zt2, zt3, pg, addr);
6089   }
St4b(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const ZRegister & zt4,const PRegister & pg,const SVEMemOperand & addr)6090   void St4b(const ZRegister& zt1,
6091             const ZRegister& zt2,
6092             const ZRegister& zt3,
6093             const ZRegister& zt4,
6094             const PRegister& pg,
6095             const SVEMemOperand& addr) {
6096     VIXL_ASSERT(allow_macro_instructions_);
6097     SingleEmissionCheckScope guard(this);
6098     st4b(zt1, zt2, zt3, zt4, pg, addr);
6099   }
St4h(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const ZRegister & zt4,const PRegister & pg,const SVEMemOperand & addr)6100   void St4h(const ZRegister& zt1,
6101             const ZRegister& zt2,
6102             const ZRegister& zt3,
6103             const ZRegister& zt4,
6104             const PRegister& pg,
6105             const SVEMemOperand& addr) {
6106     VIXL_ASSERT(allow_macro_instructions_);
6107     SingleEmissionCheckScope guard(this);
6108     st4h(zt1, zt2, zt3, zt4, pg, addr);
6109   }
St4w(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const ZRegister & zt4,const PRegister & pg,const SVEMemOperand & addr)6110   void St4w(const ZRegister& zt1,
6111             const ZRegister& zt2,
6112             const ZRegister& zt3,
6113             const ZRegister& zt4,
6114             const PRegister& pg,
6115             const SVEMemOperand& addr) {
6116     VIXL_ASSERT(allow_macro_instructions_);
6117     SingleEmissionCheckScope guard(this);
6118     st4w(zt1, zt2, zt3, zt4, pg, addr);
6119   }
St4d(const ZRegister & zt1,const ZRegister & zt2,const ZRegister & zt3,const ZRegister & zt4,const PRegister & pg,const SVEMemOperand & addr)6120   void St4d(const ZRegister& zt1,
6121             const ZRegister& zt2,
6122             const ZRegister& zt3,
6123             const ZRegister& zt4,
6124             const PRegister& pg,
6125             const SVEMemOperand& addr) {
6126     VIXL_ASSERT(allow_macro_instructions_);
6127     SingleEmissionCheckScope guard(this);
6128     st4d(zt1, zt2, zt3, zt4, pg, addr);
6129   }
6130   void Stnt1b(const ZRegister& zt,
6131               const PRegister& pg,
6132               const SVEMemOperand& addr);
6133   void Stnt1d(const ZRegister& zt,
6134               const PRegister& pg,
6135               const SVEMemOperand& addr);
6136   void Stnt1h(const ZRegister& zt,
6137               const PRegister& pg,
6138               const SVEMemOperand& addr);
6139   void Stnt1w(const ZRegister& zt,
6140               const PRegister& pg,
6141               const SVEMemOperand& addr);
Str(const CPURegister & rt,const SVEMemOperand & addr)6142   void Str(const CPURegister& rt, const SVEMemOperand& addr) {
6143     VIXL_ASSERT(allow_macro_instructions_);
6144     SVELoadStoreScalarImmHelper(rt, addr, &MacroAssembler::str);
6145   }
6146   void Sub(const ZRegister& zd,
6147            const PRegisterM& pg,
6148            const ZRegister& zn,
6149            const ZRegister& zm);
Sub(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6150   void Sub(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6151     VIXL_ASSERT(allow_macro_instructions_);
6152     SingleEmissionCheckScope guard(this);
6153     sub(zd, zn, zm);
6154   }
Sub(const ZRegister & zd,const ZRegister & zn,IntegerOperand imm)6155   void Sub(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm) {
6156     VIXL_ASSERT(allow_macro_instructions_);
6157     AddSubHelper(kSubImmediate, zd, zn, imm);
6158   }
6159   void Sub(const ZRegister& zd, IntegerOperand imm, const ZRegister& zm);
Sunpkhi(const ZRegister & zd,const ZRegister & zn)6160   void Sunpkhi(const ZRegister& zd, const ZRegister& zn) {
6161     VIXL_ASSERT(allow_macro_instructions_);
6162     SingleEmissionCheckScope guard(this);
6163     sunpkhi(zd, zn);
6164   }
Sunpklo(const ZRegister & zd,const ZRegister & zn)6165   void Sunpklo(const ZRegister& zd, const ZRegister& zn) {
6166     VIXL_ASSERT(allow_macro_instructions_);
6167     SingleEmissionCheckScope guard(this);
6168     sunpklo(zd, zn);
6169   }
Sxtb(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)6170   void Sxtb(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
6171     VIXL_ASSERT(allow_macro_instructions_);
6172     SingleEmissionCheckScope guard(this);
6173     sxtb(zd, pg, zn);
6174   }
Sxth(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)6175   void Sxth(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
6176     VIXL_ASSERT(allow_macro_instructions_);
6177     SingleEmissionCheckScope guard(this);
6178     sxth(zd, pg, zn);
6179   }
Sxtw(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)6180   void Sxtw(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
6181     VIXL_ASSERT(allow_macro_instructions_);
6182     SingleEmissionCheckScope guard(this);
6183     sxtw(zd, pg, zn);
6184   }
Tbl(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6185   void Tbl(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6186     VIXL_ASSERT(allow_macro_instructions_);
6187     SingleEmissionCheckScope guard(this);
6188     tbl(zd, zn, zm);
6189   }
Trn1(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6190   void Trn1(const PRegisterWithLaneSize& pd,
6191             const PRegisterWithLaneSize& pn,
6192             const PRegisterWithLaneSize& pm) {
6193     VIXL_ASSERT(allow_macro_instructions_);
6194     SingleEmissionCheckScope guard(this);
6195     trn1(pd, pn, pm);
6196   }
Trn1(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6197   void Trn1(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6198     VIXL_ASSERT(allow_macro_instructions_);
6199     SingleEmissionCheckScope guard(this);
6200     trn1(zd, zn, zm);
6201   }
Trn2(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6202   void Trn2(const PRegisterWithLaneSize& pd,
6203             const PRegisterWithLaneSize& pn,
6204             const PRegisterWithLaneSize& pm) {
6205     VIXL_ASSERT(allow_macro_instructions_);
6206     SingleEmissionCheckScope guard(this);
6207     trn2(pd, pn, pm);
6208   }
Trn2(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6209   void Trn2(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6210     VIXL_ASSERT(allow_macro_instructions_);
6211     SingleEmissionCheckScope guard(this);
6212     trn2(zd, zn, zm);
6213   }
Uaddv(const VRegister & dd,const PRegister & pg,const ZRegister & zn)6214   void Uaddv(const VRegister& dd, const PRegister& pg, const ZRegister& zn) {
6215     VIXL_ASSERT(allow_macro_instructions_);
6216     SingleEmissionCheckScope guard(this);
6217     uaddv(dd, pg, zn);
6218   }
Ucvtf(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)6219   void Ucvtf(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
6220     VIXL_ASSERT(allow_macro_instructions_);
6221     SingleEmissionCheckScope guard(this);
6222     ucvtf(zd, pg, zn);
6223   }
6224   void Udiv(const ZRegister& zd,
6225             const PRegisterM& pg,
6226             const ZRegister& zn,
6227             const ZRegister& zm);
6228   void Udot(const ZRegister& zd,
6229             const ZRegister& za,
6230             const ZRegister& zn,
6231             const ZRegister& zm);
6232   void Udot(const ZRegister& zd,
6233             const ZRegister& za,
6234             const ZRegister& zn,
6235             const ZRegister& zm,
6236             int index);
6237   void Umax(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm);
Umaxv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)6238   void Umaxv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
6239     VIXL_ASSERT(allow_macro_instructions_);
6240     SingleEmissionCheckScope guard(this);
6241     umaxv(vd, pg, zn);
6242   }
6243   void Umin(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm);
Uminv(const VRegister & vd,const PRegister & pg,const ZRegister & zn)6244   void Uminv(const VRegister& vd, const PRegister& pg, const ZRegister& zn) {
6245     VIXL_ASSERT(allow_macro_instructions_);
6246     SingleEmissionCheckScope guard(this);
6247     uminv(vd, pg, zn);
6248   }
Uqadd(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6249   void Uqadd(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6250     VIXL_ASSERT(allow_macro_instructions_);
6251     SingleEmissionCheckScope guard(this);
6252     uqadd(zd, zn, zm);
6253   }
Uqadd(const ZRegister & zd,const ZRegister & zn,IntegerOperand imm)6254   void Uqadd(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm) {
6255     VIXL_ASSERT(allow_macro_instructions_);
6256     VIXL_ASSERT(imm.IsUint8() ||
6257                 (imm.IsUint16() && ((imm.AsUint16() & 0xff) == 0)));
6258     MovprfxHelperScope guard(this, zd, zn);
6259     uqadd(zd, zd, imm.AsUint16());
6260   }
6261   void Uqdecb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
6262     VIXL_ASSERT(allow_macro_instructions_);
6263     SingleEmissionCheckScope guard(this);
6264     uqdecb(rdn, pattern, multiplier);
6265   }
6266   void Uqdecd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
6267     VIXL_ASSERT(allow_macro_instructions_);
6268     SingleEmissionCheckScope guard(this);
6269     uqdecd(rdn, pattern, multiplier);
6270   }
6271   void Uqdecd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
6272     VIXL_ASSERT(allow_macro_instructions_);
6273     SingleEmissionCheckScope guard(this);
6274     uqdecd(zdn, pattern, multiplier);
6275   }
6276   void Uqdech(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
6277     VIXL_ASSERT(allow_macro_instructions_);
6278     SingleEmissionCheckScope guard(this);
6279     uqdech(rdn, pattern, multiplier);
6280   }
6281   void Uqdech(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
6282     VIXL_ASSERT(allow_macro_instructions_);
6283     SingleEmissionCheckScope guard(this);
6284     uqdech(zdn, pattern, multiplier);
6285   }
6286   // The saturation is based on the size of `rn`. The result is zero-extended
6287   // into `rd`, which must be at least as big.
Uqdecp(const Register & rd,const PRegisterWithLaneSize & pg,const Register & rn)6288   void Uqdecp(const Register& rd,
6289               const PRegisterWithLaneSize& pg,
6290               const Register& rn) {
6291     VIXL_ASSERT(allow_macro_instructions_);
6292     VIXL_ASSERT(rd.Aliases(rn));
6293     VIXL_ASSERT(rd.GetSizeInBytes() >= rn.GetSizeInBytes());
6294     SingleEmissionCheckScope guard(this);
6295     if (rn.Is64Bits()) {
6296       uqdecp(rd, pg);
6297     } else {
6298       // Convert <Xd> into <Wd>, to make this more consistent with Sqdecp.
6299       uqdecp(rd.W(), pg);
6300     }
6301   }
Uqdecp(const Register & rdn,const PRegisterWithLaneSize & pg)6302   void Uqdecp(const Register& rdn, const PRegisterWithLaneSize& pg) {
6303     Uqdecp(rdn, pg, rdn);
6304   }
Uqdecp(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)6305   void Uqdecp(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) {
6306     VIXL_ASSERT(allow_macro_instructions_);
6307     VIXL_ASSERT(AreSameFormat(zd, zn));
6308     // `sqdecp` writes every lane, so use an unpredicated movprfx.
6309     MovprfxHelperScope guard(this, zd, zn);
6310     uqdecp(zd, pg);
6311   }
Uqdecp(const ZRegister & zdn,const PRegister & pg)6312   void Uqdecp(const ZRegister& zdn, const PRegister& pg) {
6313     Uqdecp(zdn, pg, zdn);
6314   }
6315   void Uqdecw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
6316     VIXL_ASSERT(allow_macro_instructions_);
6317     SingleEmissionCheckScope guard(this);
6318     uqdecw(rdn, pattern, multiplier);
6319   }
6320   void Uqdecw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
6321     VIXL_ASSERT(allow_macro_instructions_);
6322     SingleEmissionCheckScope guard(this);
6323     uqdecw(zdn, pattern, multiplier);
6324   }
6325   void Uqincb(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
6326     VIXL_ASSERT(allow_macro_instructions_);
6327     SingleEmissionCheckScope guard(this);
6328     uqincb(rdn, pattern, multiplier);
6329   }
6330   void Uqincd(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
6331     VIXL_ASSERT(allow_macro_instructions_);
6332     SingleEmissionCheckScope guard(this);
6333     uqincd(rdn, pattern, multiplier);
6334   }
6335   void Uqincd(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
6336     VIXL_ASSERT(allow_macro_instructions_);
6337     SingleEmissionCheckScope guard(this);
6338     uqincd(zdn, pattern, multiplier);
6339   }
6340   void Uqinch(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
6341     VIXL_ASSERT(allow_macro_instructions_);
6342     SingleEmissionCheckScope guard(this);
6343     uqinch(rdn, pattern, multiplier);
6344   }
6345   void Uqinch(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
6346     VIXL_ASSERT(allow_macro_instructions_);
6347     SingleEmissionCheckScope guard(this);
6348     uqinch(zdn, pattern, multiplier);
6349   }
6350   // The saturation is based on the size of `rn`. The result is zero-extended
6351   // into `rd`, which must be at least as big.
Uqincp(const Register & rd,const PRegisterWithLaneSize & pg,const Register & rn)6352   void Uqincp(const Register& rd,
6353               const PRegisterWithLaneSize& pg,
6354               const Register& rn) {
6355     VIXL_ASSERT(allow_macro_instructions_);
6356     VIXL_ASSERT(rd.Aliases(rn));
6357     VIXL_ASSERT(rd.GetSizeInBytes() >= rn.GetSizeInBytes());
6358     SingleEmissionCheckScope guard(this);
6359     if (rn.Is64Bits()) {
6360       uqincp(rd, pg);
6361     } else {
6362       // Convert <Xd> into <Wd>, to make this more consistent with Sqincp.
6363       uqincp(rd.W(), pg);
6364     }
6365   }
Uqincp(const Register & rdn,const PRegisterWithLaneSize & pg)6366   void Uqincp(const Register& rdn, const PRegisterWithLaneSize& pg) {
6367     Uqincp(rdn, pg, rdn);
6368   }
Uqincp(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)6369   void Uqincp(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) {
6370     VIXL_ASSERT(allow_macro_instructions_);
6371     VIXL_ASSERT(AreSameFormat(zd, zn));
6372     // `sqincp` writes every lane, so use an unpredicated movprfx.
6373     MovprfxHelperScope guard(this, zd, zn);
6374     uqincp(zd, pg);
6375   }
Uqincp(const ZRegister & zdn,const PRegister & pg)6376   void Uqincp(const ZRegister& zdn, const PRegister& pg) {
6377     Uqincp(zdn, pg, zdn);
6378   }
6379   void Uqincw(const Register& rdn, int pattern = SVE_ALL, int multiplier = 1) {
6380     VIXL_ASSERT(allow_macro_instructions_);
6381     SingleEmissionCheckScope guard(this);
6382     uqincw(rdn, pattern, multiplier);
6383   }
6384   void Uqincw(const ZRegister& zdn, int pattern = SVE_ALL, int multiplier = 1) {
6385     VIXL_ASSERT(allow_macro_instructions_);
6386     SingleEmissionCheckScope guard(this);
6387     uqincw(zdn, pattern, multiplier);
6388   }
Uqsub(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6389   void Uqsub(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6390     VIXL_ASSERT(allow_macro_instructions_);
6391     SingleEmissionCheckScope guard(this);
6392     uqsub(zd, zn, zm);
6393   }
Uqsub(const ZRegister & zd,const ZRegister & zn,IntegerOperand imm)6394   void Uqsub(const ZRegister& zd, const ZRegister& zn, IntegerOperand imm) {
6395     VIXL_ASSERT(allow_macro_instructions_);
6396     VIXL_ASSERT(imm.IsUint8() ||
6397                 (imm.IsUint16() && ((imm.AsUint16() & 0xff) == 0)));
6398     MovprfxHelperScope guard(this, zd, zn);
6399     uqsub(zd, zd, imm.AsUint16());
6400   }
Uunpkhi(const ZRegister & zd,const ZRegister & zn)6401   void Uunpkhi(const ZRegister& zd, const ZRegister& zn) {
6402     VIXL_ASSERT(allow_macro_instructions_);
6403     SingleEmissionCheckScope guard(this);
6404     uunpkhi(zd, zn);
6405   }
Uunpklo(const ZRegister & zd,const ZRegister & zn)6406   void Uunpklo(const ZRegister& zd, const ZRegister& zn) {
6407     VIXL_ASSERT(allow_macro_instructions_);
6408     SingleEmissionCheckScope guard(this);
6409     uunpklo(zd, zn);
6410   }
Uxtb(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)6411   void Uxtb(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
6412     VIXL_ASSERT(allow_macro_instructions_);
6413     SingleEmissionCheckScope guard(this);
6414     uxtb(zd, pg, zn);
6415   }
Uxth(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)6416   void Uxth(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
6417     VIXL_ASSERT(allow_macro_instructions_);
6418     SingleEmissionCheckScope guard(this);
6419     uxth(zd, pg, zn);
6420   }
Uxtw(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)6421   void Uxtw(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
6422     VIXL_ASSERT(allow_macro_instructions_);
6423     SingleEmissionCheckScope guard(this);
6424     uxtw(zd, pg, zn);
6425   }
Uzp1(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6426   void Uzp1(const PRegisterWithLaneSize& pd,
6427             const PRegisterWithLaneSize& pn,
6428             const PRegisterWithLaneSize& pm) {
6429     VIXL_ASSERT(allow_macro_instructions_);
6430     SingleEmissionCheckScope guard(this);
6431     uzp1(pd, pn, pm);
6432   }
Uzp1(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6433   void Uzp1(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6434     VIXL_ASSERT(allow_macro_instructions_);
6435     SingleEmissionCheckScope guard(this);
6436     uzp1(zd, zn, zm);
6437   }
Uzp2(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6438   void Uzp2(const PRegisterWithLaneSize& pd,
6439             const PRegisterWithLaneSize& pn,
6440             const PRegisterWithLaneSize& pm) {
6441     VIXL_ASSERT(allow_macro_instructions_);
6442     SingleEmissionCheckScope guard(this);
6443     uzp2(pd, pn, pm);
6444   }
Uzp2(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6445   void Uzp2(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6446     VIXL_ASSERT(allow_macro_instructions_);
6447     SingleEmissionCheckScope guard(this);
6448     uzp2(zd, zn, zm);
6449   }
Whilele(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)6450   void Whilele(const PRegisterWithLaneSize& pd,
6451                const Register& rn,
6452                const Register& rm) {
6453     VIXL_ASSERT(allow_macro_instructions_);
6454     SingleEmissionCheckScope guard(this);
6455     whilele(pd, rn, rm);
6456   }
Whilelo(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)6457   void Whilelo(const PRegisterWithLaneSize& pd,
6458                const Register& rn,
6459                const Register& rm) {
6460     VIXL_ASSERT(allow_macro_instructions_);
6461     SingleEmissionCheckScope guard(this);
6462     whilelo(pd, rn, rm);
6463   }
Whilels(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)6464   void Whilels(const PRegisterWithLaneSize& pd,
6465                const Register& rn,
6466                const Register& rm) {
6467     VIXL_ASSERT(allow_macro_instructions_);
6468     SingleEmissionCheckScope guard(this);
6469     whilels(pd, rn, rm);
6470   }
Whilelt(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)6471   void Whilelt(const PRegisterWithLaneSize& pd,
6472                const Register& rn,
6473                const Register& rm) {
6474     VIXL_ASSERT(allow_macro_instructions_);
6475     SingleEmissionCheckScope guard(this);
6476     whilelt(pd, rn, rm);
6477   }
Wrffr(const PRegister & pn)6478   void Wrffr(const PRegister& pn) {
6479     VIXL_ASSERT(allow_macro_instructions_);
6480     // Although this is essentially just a move, it writes every bit and so can
6481     // only support b-sized lane because other lane sizes would implicitly clear
6482     // bits in `ffr`.
6483     VIXL_ASSERT(!pn.HasLaneSize() || pn.IsLaneSizeB());
6484     VIXL_ASSERT(pn.IsUnqualified());
6485     SingleEmissionCheckScope guard(this);
6486     wrffr(pn.VnB());
6487   }
Zip1(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6488   void Zip1(const PRegisterWithLaneSize& pd,
6489             const PRegisterWithLaneSize& pn,
6490             const PRegisterWithLaneSize& pm) {
6491     VIXL_ASSERT(allow_macro_instructions_);
6492     SingleEmissionCheckScope guard(this);
6493     zip1(pd, pn, pm);
6494   }
Zip1(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6495   void Zip1(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6496     VIXL_ASSERT(allow_macro_instructions_);
6497     SingleEmissionCheckScope guard(this);
6498     zip1(zd, zn, zm);
6499   }
Zip2(const PRegisterWithLaneSize & pd,const PRegisterWithLaneSize & pn,const PRegisterWithLaneSize & pm)6500   void Zip2(const PRegisterWithLaneSize& pd,
6501             const PRegisterWithLaneSize& pn,
6502             const PRegisterWithLaneSize& pm) {
6503     VIXL_ASSERT(allow_macro_instructions_);
6504     SingleEmissionCheckScope guard(this);
6505     zip2(pd, pn, pm);
6506   }
Zip2(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6507   void Zip2(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6508     VIXL_ASSERT(allow_macro_instructions_);
6509     SingleEmissionCheckScope guard(this);
6510     zip2(zd, zn, zm);
6511   }
6512 
6513   // SVE2
6514   void Adclb(const ZRegister& zd,
6515              const ZRegister& za,
6516              const ZRegister& zn,
6517              const ZRegister& zm);
6518   void Adclt(const ZRegister& zd,
6519              const ZRegister& za,
6520              const ZRegister& zn,
6521              const ZRegister& zm);
Addhnb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6522   void Addhnb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6523     VIXL_ASSERT(allow_macro_instructions_);
6524     SingleEmissionCheckScope guard(this);
6525     addhnb(zd, zn, zm);
6526   }
Addhnt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6527   void Addhnt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6528     VIXL_ASSERT(allow_macro_instructions_);
6529     SingleEmissionCheckScope guard(this);
6530     addhnt(zd, zn, zm);
6531   }
6532   void Addp(const ZRegister& zd,
6533             const PRegisterM& pg,
6534             const ZRegister& zn,
6535             const ZRegister& zm);
6536   void Bcax(const ZRegister& zd,
6537             const ZRegister& zn,
6538             const ZRegister& zm,
6539             const ZRegister& zk);
Bdep(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6540   void Bdep(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6541     VIXL_ASSERT(allow_macro_instructions_);
6542     SingleEmissionCheckScope guard(this);
6543     bdep(zd, zn, zm);
6544   }
Bext(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6545   void Bext(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6546     VIXL_ASSERT(allow_macro_instructions_);
6547     SingleEmissionCheckScope guard(this);
6548     bext(zd, zn, zm);
6549   }
Bgrp(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6550   void Bgrp(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6551     VIXL_ASSERT(allow_macro_instructions_);
6552     SingleEmissionCheckScope guard(this);
6553     bgrp(zd, zn, zm);
6554   }
6555   void Bsl(const ZRegister& zd,
6556            const ZRegister& zn,
6557            const ZRegister& zm,
6558            const ZRegister& zk);
6559   void Bsl1n(const ZRegister& zd,
6560              const ZRegister& zn,
6561              const ZRegister& zm,
6562              const ZRegister& zk);
6563   void Bsl2n(const ZRegister& zd,
6564              const ZRegister& zn,
6565              const ZRegister& zm,
6566              const ZRegister& zk);
6567   void Cadd(const ZRegister& zd,
6568             const ZRegister& zn,
6569             const ZRegister& zm,
6570             int rot);
6571   void Cdot(const ZRegister& zd,
6572             const ZRegister& za,
6573             const ZRegister& zn,
6574             const ZRegister& zm,
6575             int index,
6576             int rot);
6577   void Cdot(const ZRegister& zd,
6578             const ZRegister& za,
6579             const ZRegister& zn,
6580             const ZRegister& zm,
6581             int rot);
6582   void Cmla(const ZRegister& zd,
6583             const ZRegister& za,
6584             const ZRegister& zn,
6585             const ZRegister& zm,
6586             int index,
6587             int rot);
6588   void Cmla(const ZRegister& zd,
6589             const ZRegister& za,
6590             const ZRegister& zn,
6591             const ZRegister& zm,
6592             int rot);
6593   void Eor3(const ZRegister& zd,
6594             const ZRegister& zn,
6595             const ZRegister& zm,
6596             const ZRegister& zk);
Eorbt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6597   void Eorbt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6598     VIXL_ASSERT(allow_macro_instructions_);
6599     SingleEmissionCheckScope guard(this);
6600     eorbt(zd, zn, zm);
6601   }
Eortb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6602   void Eortb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6603     VIXL_ASSERT(allow_macro_instructions_);
6604     SingleEmissionCheckScope guard(this);
6605     eortb(zd, zn, zm);
6606   }
6607   void Faddp(const ZRegister& zd,
6608              const PRegisterM& pg,
6609              const ZRegister& zn,
6610              const ZRegister& zm);
Fcvtlt(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)6611   void Fcvtlt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
6612     VIXL_ASSERT(allow_macro_instructions_);
6613     SingleEmissionCheckScope guard(this);
6614     fcvtlt(zd, pg, zn);
6615   }
Fcvtnt(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)6616   void Fcvtnt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
6617     VIXL_ASSERT(allow_macro_instructions_);
6618     SingleEmissionCheckScope guard(this);
6619     fcvtnt(zd, pg, zn);
6620   }
Fcvtx(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)6621   void Fcvtx(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) {
6622     VIXL_ASSERT(allow_macro_instructions_);
6623     VIXL_ASSERT(zn.IsLaneSizeD());
6624     MovprfxHelperScope guard(this, zd.VnD(), pg, zd.VnD());
6625     fcvtx(zd, pg.Merging(), zn);
6626   }
Fcvtxnt(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn)6627   void Fcvtxnt(const ZRegister& zd, const PRegisterM& pg, const ZRegister& zn) {
6628     VIXL_ASSERT(allow_macro_instructions_);
6629     SingleEmissionCheckScope guard(this);
6630     fcvtxnt(zd, pg, zn);
6631   }
Flogb(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)6632   void Flogb(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) {
6633     VIXL_ASSERT(allow_macro_instructions_);
6634     MovprfxHelperScope guard(this, zd, pg, zd);
6635     flogb(zd, pg.Merging(), zn);
6636   }
6637   void Fmaxnmp(const ZRegister& zd,
6638                const PRegisterM& pg,
6639                const ZRegister& zn,
6640                const ZRegister& zm);
6641   void Fmaxp(const ZRegister& zd,
6642              const PRegisterM& pg,
6643              const ZRegister& zn,
6644              const ZRegister& zm);
6645   void Fminnmp(const ZRegister& zd,
6646                const PRegisterM& pg,
6647                const ZRegister& zn,
6648                const ZRegister& zm);
6649   void Fminp(const ZRegister& zd,
6650              const PRegisterM& pg,
6651              const ZRegister& zn,
6652              const ZRegister& zm);
6653   void Fmlalb(const ZRegister& zd,
6654               const ZRegister& za,
6655               const ZRegister& zn,
6656               const ZRegister& zm);
6657   void Fmlalt(const ZRegister& zd,
6658               const ZRegister& za,
6659               const ZRegister& zn,
6660               const ZRegister& zm);
6661   void Fmlslb(const ZRegister& zd,
6662               const ZRegister& za,
6663               const ZRegister& zn,
6664               const ZRegister& zm);
6665   void Fmlslt(const ZRegister& zd,
6666               const ZRegister& za,
6667               const ZRegister& zn,
6668               const ZRegister& zm);
6669   void Fmlalb(const ZRegister& zd,
6670               const ZRegister& za,
6671               const ZRegister& zn,
6672               const ZRegister& zm,
6673               int index);
6674   void Fmlalt(const ZRegister& zd,
6675               const ZRegister& za,
6676               const ZRegister& zn,
6677               const ZRegister& zm,
6678               int index);
6679   void Fmlslb(const ZRegister& zd,
6680               const ZRegister& za,
6681               const ZRegister& zn,
6682               const ZRegister& zm,
6683               int index);
6684   void Fmlslt(const ZRegister& zd,
6685               const ZRegister& za,
6686               const ZRegister& zn,
6687               const ZRegister& zm,
6688               int index);
Histcnt(const ZRegister & zd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)6689   void Histcnt(const ZRegister& zd,
6690                const PRegisterZ& pg,
6691                const ZRegister& zn,
6692                const ZRegister& zm) {
6693     VIXL_ASSERT(allow_macro_instructions_);
6694     SingleEmissionCheckScope guard(this);
6695     histcnt(zd, pg, zn, zm);
6696   }
Histseg(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6697   void Histseg(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6698     VIXL_ASSERT(allow_macro_instructions_);
6699     SingleEmissionCheckScope guard(this);
6700     histseg(zd, zn, zm);
6701   }
Ldnt1sb(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)6702   void Ldnt1sb(const ZRegister& zt,
6703                const PRegisterZ& pg,
6704                const SVEMemOperand& addr) {
6705     VIXL_ASSERT(allow_macro_instructions_);
6706     SingleEmissionCheckScope guard(this);
6707     ldnt1sb(zt, pg, addr);
6708   }
Ldnt1sh(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)6709   void Ldnt1sh(const ZRegister& zt,
6710                const PRegisterZ& pg,
6711                const SVEMemOperand& addr) {
6712     VIXL_ASSERT(allow_macro_instructions_);
6713     SingleEmissionCheckScope guard(this);
6714     ldnt1sh(zt, pg, addr);
6715   }
Ldnt1sw(const ZRegister & zt,const PRegisterZ & pg,const SVEMemOperand & addr)6716   void Ldnt1sw(const ZRegister& zt,
6717                const PRegisterZ& pg,
6718                const SVEMemOperand& addr) {
6719     VIXL_ASSERT(allow_macro_instructions_);
6720     SingleEmissionCheckScope guard(this);
6721     ldnt1sw(zt, pg, addr);
6722   }
Match(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)6723   void Match(const PRegisterWithLaneSize& pd,
6724              const PRegisterZ& pg,
6725              const ZRegister& zn,
6726              const ZRegister& zm) {
6727     VIXL_ASSERT(allow_macro_instructions_);
6728     SingleEmissionCheckScope guard(this);
6729     match(pd, pg, zn, zm);
6730   }
6731   void Mla(const ZRegister& zd,
6732            const ZRegister& za,
6733            const ZRegister& zn,
6734            const ZRegister& zm,
6735            int index);
6736   void Mls(const ZRegister& zd,
6737            const ZRegister& za,
6738            const ZRegister& zn,
6739            const ZRegister& zm,
6740            int index);
Mul(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int index)6741   void Mul(const ZRegister& zd,
6742            const ZRegister& zn,
6743            const ZRegister& zm,
6744            int index) {
6745     VIXL_ASSERT(allow_macro_instructions_);
6746     SingleEmissionCheckScope guard(this);
6747     mul(zd, zn, zm, index);
6748   }
Mul(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6749   void Mul(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6750     VIXL_ASSERT(allow_macro_instructions_);
6751     SingleEmissionCheckScope guard(this);
6752     mul(zd, zn, zm);
6753   }
6754   void Nbsl(const ZRegister& zd,
6755             const ZRegister& zn,
6756             const ZRegister& zm,
6757             const ZRegister& zk);
Nmatch(const PRegisterWithLaneSize & pd,const PRegisterZ & pg,const ZRegister & zn,const ZRegister & zm)6758   void Nmatch(const PRegisterWithLaneSize& pd,
6759               const PRegisterZ& pg,
6760               const ZRegister& zn,
6761               const ZRegister& zm) {
6762     VIXL_ASSERT(allow_macro_instructions_);
6763     SingleEmissionCheckScope guard(this);
6764     nmatch(pd, pg, zn, zm);
6765   }
Pmul(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6766   void Pmul(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6767     VIXL_ASSERT(allow_macro_instructions_);
6768     SingleEmissionCheckScope guard(this);
6769     pmul(zd, zn, zm);
6770   }
Pmullb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6771   void Pmullb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6772     VIXL_ASSERT(allow_macro_instructions_);
6773     SingleEmissionCheckScope guard(this);
6774     pmullb(zd, zn, zm);
6775   }
Pmullt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6776   void Pmullt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6777     VIXL_ASSERT(allow_macro_instructions_);
6778     SingleEmissionCheckScope guard(this);
6779     pmullt(zd, zn, zm);
6780   }
Raddhnb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6781   void Raddhnb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6782     VIXL_ASSERT(allow_macro_instructions_);
6783     SingleEmissionCheckScope guard(this);
6784     raddhnb(zd, zn, zm);
6785   }
Raddhnt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6786   void Raddhnt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6787     VIXL_ASSERT(allow_macro_instructions_);
6788     SingleEmissionCheckScope guard(this);
6789     raddhnt(zd, zn, zm);
6790   }
Rshrnb(const ZRegister & zd,const ZRegister & zn,int shift)6791   void Rshrnb(const ZRegister& zd, const ZRegister& zn, int shift) {
6792     VIXL_ASSERT(allow_macro_instructions_);
6793     SingleEmissionCheckScope guard(this);
6794     rshrnb(zd, zn, shift);
6795   }
Rshrnt(const ZRegister & zd,const ZRegister & zn,int shift)6796   void Rshrnt(const ZRegister& zd, const ZRegister& zn, int shift) {
6797     VIXL_ASSERT(allow_macro_instructions_);
6798     SingleEmissionCheckScope guard(this);
6799     rshrnt(zd, zn, shift);
6800   }
Rsubhnb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6801   void Rsubhnb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6802     VIXL_ASSERT(allow_macro_instructions_);
6803     SingleEmissionCheckScope guard(this);
6804     rsubhnb(zd, zn, zm);
6805   }
Rsubhnt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6806   void Rsubhnt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6807     VIXL_ASSERT(allow_macro_instructions_);
6808     SingleEmissionCheckScope guard(this);
6809     rsubhnt(zd, zn, zm);
6810   }
6811   void Saba(const ZRegister& zd,
6812             const ZRegister& za,
6813             const ZRegister& zn,
6814             const ZRegister& zm);
6815   void Sabalb(const ZRegister& zd,
6816               const ZRegister& za,
6817               const ZRegister& zn,
6818               const ZRegister& zm);
6819   void Sabalt(const ZRegister& zd,
6820               const ZRegister& za,
6821               const ZRegister& zn,
6822               const ZRegister& zm);
Sabdlb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6823   void Sabdlb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6824     VIXL_ASSERT(allow_macro_instructions_);
6825     SingleEmissionCheckScope guard(this);
6826     sabdlb(zd, zn, zm);
6827   }
Sabdlt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6828   void Sabdlt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6829     VIXL_ASSERT(allow_macro_instructions_);
6830     SingleEmissionCheckScope guard(this);
6831     sabdlt(zd, zn, zm);
6832   }
Sadalp(const ZRegister & zda,const PRegisterM & pg,const ZRegister & zn)6833   void Sadalp(const ZRegister& zda, const PRegisterM& pg, const ZRegister& zn) {
6834     VIXL_ASSERT(allow_macro_instructions_);
6835     SingleEmissionCheckScope guard(this);
6836     sadalp(zda, pg, zn);
6837   }
Saddlb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6838   void Saddlb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6839     VIXL_ASSERT(allow_macro_instructions_);
6840     SingleEmissionCheckScope guard(this);
6841     saddlb(zd, zn, zm);
6842   }
Saddlbt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6843   void Saddlbt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6844     VIXL_ASSERT(allow_macro_instructions_);
6845     SingleEmissionCheckScope guard(this);
6846     saddlbt(zd, zn, zm);
6847   }
Saddlt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6848   void Saddlt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6849     VIXL_ASSERT(allow_macro_instructions_);
6850     SingleEmissionCheckScope guard(this);
6851     saddlt(zd, zn, zm);
6852   }
Saddwb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6853   void Saddwb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6854     VIXL_ASSERT(allow_macro_instructions_);
6855     SingleEmissionCheckScope guard(this);
6856     saddwb(zd, zn, zm);
6857   }
Saddwt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6858   void Saddwt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6859     VIXL_ASSERT(allow_macro_instructions_);
6860     SingleEmissionCheckScope guard(this);
6861     saddwt(zd, zn, zm);
6862   }
6863   void Sbclb(const ZRegister& zd,
6864              const ZRegister& za,
6865              const ZRegister& zn,
6866              const ZRegister& zm);
6867   void Sbclt(const ZRegister& zd,
6868              const ZRegister& za,
6869              const ZRegister& zn,
6870              const ZRegister& zm);
Shrnb(const ZRegister & zd,const ZRegister & zn,int shift)6871   void Shrnb(const ZRegister& zd, const ZRegister& zn, int shift) {
6872     VIXL_ASSERT(allow_macro_instructions_);
6873     SingleEmissionCheckScope guard(this);
6874     shrnb(zd, zn, shift);
6875   }
Shrnt(const ZRegister & zd,const ZRegister & zn,int shift)6876   void Shrnt(const ZRegister& zd, const ZRegister& zn, int shift) {
6877     VIXL_ASSERT(allow_macro_instructions_);
6878     SingleEmissionCheckScope guard(this);
6879     shrnt(zd, zn, shift);
6880   }
6881   void Shsub(const ZRegister& zd,
6882              const PRegisterM& pg,
6883              const ZRegister& zn,
6884              const ZRegister& zm);
Sli(const ZRegister & zd,const ZRegister & zn,int shift)6885   void Sli(const ZRegister& zd, const ZRegister& zn, int shift) {
6886     VIXL_ASSERT(allow_macro_instructions_);
6887     SingleEmissionCheckScope guard(this);
6888     sli(zd, zn, shift);
6889   }
6890   void Smaxp(const ZRegister& zd,
6891              const PRegisterM& pg,
6892              const ZRegister& zn,
6893              const ZRegister& zm);
6894   void Sminp(const ZRegister& zd,
6895              const PRegisterM& pg,
6896              const ZRegister& zn,
6897              const ZRegister& zm);
6898   void Smlalb(const ZRegister& zd,
6899               const ZRegister& za,
6900               const ZRegister& zn,
6901               const ZRegister& zm,
6902               int index);
6903   void Smlalb(const ZRegister& zd,
6904               const ZRegister& za,
6905               const ZRegister& zn,
6906               const ZRegister& zm);
6907   void Smlalt(const ZRegister& zd,
6908               const ZRegister& za,
6909               const ZRegister& zn,
6910               const ZRegister& zm,
6911               int index);
6912   void Smlalt(const ZRegister& zd,
6913               const ZRegister& za,
6914               const ZRegister& zn,
6915               const ZRegister& zm);
6916   void Smlslb(const ZRegister& zd,
6917               const ZRegister& za,
6918               const ZRegister& zn,
6919               const ZRegister& zm,
6920               int index);
6921   void Smlslb(const ZRegister& zd,
6922               const ZRegister& za,
6923               const ZRegister& zn,
6924               const ZRegister& zm);
6925   void Smlslt(const ZRegister& zd,
6926               const ZRegister& za,
6927               const ZRegister& zn,
6928               const ZRegister& zm,
6929               int index);
6930   void Smlslt(const ZRegister& zd,
6931               const ZRegister& za,
6932               const ZRegister& zn,
6933               const ZRegister& zm);
Smulh(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6934   void Smulh(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6935     VIXL_ASSERT(allow_macro_instructions_);
6936     SingleEmissionCheckScope guard(this);
6937     smulh(zd, zn, zm);
6938   }
Smullb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int index)6939   void Smullb(const ZRegister& zd,
6940               const ZRegister& zn,
6941               const ZRegister& zm,
6942               int index) {
6943     VIXL_ASSERT(allow_macro_instructions_);
6944     SingleEmissionCheckScope guard(this);
6945     smullb(zd, zn, zm, index);
6946   }
Smullb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6947   void Smullb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6948     VIXL_ASSERT(allow_macro_instructions_);
6949     SingleEmissionCheckScope guard(this);
6950     smullb(zd, zn, zm);
6951   }
Smullt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int index)6952   void Smullt(const ZRegister& zd,
6953               const ZRegister& zn,
6954               const ZRegister& zm,
6955               int index) {
6956     VIXL_ASSERT(allow_macro_instructions_);
6957     SingleEmissionCheckScope guard(this);
6958     smullt(zd, zn, zm, index);
6959   }
Smullt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)6960   void Smullt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
6961     VIXL_ASSERT(allow_macro_instructions_);
6962     SingleEmissionCheckScope guard(this);
6963     smullt(zd, zn, zm);
6964   }
Sqabs(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)6965   void Sqabs(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) {
6966     VIXL_ASSERT(allow_macro_instructions_);
6967     MovprfxHelperScope guard(this, zd, pg, zd);
6968     sqabs(zd, pg.Merging(), zn);
6969   }
6970   void Sqcadd(const ZRegister& zd,
6971               const ZRegister& zn,
6972               const ZRegister& zm,
6973               int rot);
6974   void Sqdmlalb(const ZRegister& zd,
6975                 const ZRegister& za,
6976                 const ZRegister& zn,
6977                 const ZRegister& zm,
6978                 int index);
6979   void Sqdmlalb(const ZRegister& zd,
6980                 const ZRegister& za,
6981                 const ZRegister& zn,
6982                 const ZRegister& zm);
6983   void Sqdmlalbt(const ZRegister& zd,
6984                  const ZRegister& za,
6985                  const ZRegister& zn,
6986                  const ZRegister& zm);
6987   void Sqdmlalt(const ZRegister& zd,
6988                 const ZRegister& za,
6989                 const ZRegister& zn,
6990                 const ZRegister& zm,
6991                 int index);
6992   void Sqdmlalt(const ZRegister& zd,
6993                 const ZRegister& za,
6994                 const ZRegister& zn,
6995                 const ZRegister& zm);
6996   void Sqdmlslb(const ZRegister& zd,
6997                 const ZRegister& za,
6998                 const ZRegister& zn,
6999                 const ZRegister& zm,
7000                 int index);
7001   void Sqdmlslb(const ZRegister& zd,
7002                 const ZRegister& za,
7003                 const ZRegister& zn,
7004                 const ZRegister& zm);
7005   void Sqdmlslbt(const ZRegister& zd,
7006                  const ZRegister& za,
7007                  const ZRegister& zn,
7008                  const ZRegister& zm);
7009   void Sqdmlslt(const ZRegister& zd,
7010                 const ZRegister& za,
7011                 const ZRegister& zn,
7012                 const ZRegister& zm,
7013                 int index);
7014   void Sqdmlslt(const ZRegister& zd,
7015                 const ZRegister& za,
7016                 const ZRegister& zn,
7017                 const ZRegister& zm);
Sqdmulh(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int index)7018   void Sqdmulh(const ZRegister& zd,
7019                const ZRegister& zn,
7020                const ZRegister& zm,
7021                int index) {
7022     VIXL_ASSERT(allow_macro_instructions_);
7023     SingleEmissionCheckScope guard(this);
7024     sqdmulh(zd, zn, zm, index);
7025   }
Sqdmulh(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7026   void Sqdmulh(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7027     VIXL_ASSERT(allow_macro_instructions_);
7028     SingleEmissionCheckScope guard(this);
7029     sqdmulh(zd, zn, zm);
7030   }
Sqdmullb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int index)7031   void Sqdmullb(const ZRegister& zd,
7032                 const ZRegister& zn,
7033                 const ZRegister& zm,
7034                 int index) {
7035     VIXL_ASSERT(allow_macro_instructions_);
7036     SingleEmissionCheckScope guard(this);
7037     sqdmullb(zd, zn, zm, index);
7038   }
Sqdmullb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7039   void Sqdmullb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7040     VIXL_ASSERT(allow_macro_instructions_);
7041     SingleEmissionCheckScope guard(this);
7042     sqdmullb(zd, zn, zm);
7043   }
Sqdmullt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int index)7044   void Sqdmullt(const ZRegister& zd,
7045                 const ZRegister& zn,
7046                 const ZRegister& zm,
7047                 int index) {
7048     VIXL_ASSERT(allow_macro_instructions_);
7049     SingleEmissionCheckScope guard(this);
7050     sqdmullt(zd, zn, zm, index);
7051   }
Sqdmullt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7052   void Sqdmullt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7053     VIXL_ASSERT(allow_macro_instructions_);
7054     SingleEmissionCheckScope guard(this);
7055     sqdmullt(zd, zn, zm);
7056   }
Sqneg(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)7057   void Sqneg(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) {
7058     VIXL_ASSERT(allow_macro_instructions_);
7059     MovprfxHelperScope guard(this, zd, pg, zd);
7060     sqneg(zd, pg.Merging(), zn);
7061   }
7062   void Sqrdcmlah(const ZRegister& zd,
7063                  const ZRegister& za,
7064                  const ZRegister& zn,
7065                  const ZRegister& zm,
7066                  int index,
7067                  int rot);
7068   void Sqrdcmlah(const ZRegister& zd,
7069                  const ZRegister& za,
7070                  const ZRegister& zn,
7071                  const ZRegister& zm,
7072                  int rot);
7073   void Sqrdmlah(const ZRegister& zd,
7074                 const ZRegister& za,
7075                 const ZRegister& zn,
7076                 const ZRegister& zm);
7077   void Sqrdmlah(const ZRegister& zd,
7078                 const ZRegister& za,
7079                 const ZRegister& zn,
7080                 const ZRegister& zm,
7081                 int index);
7082   void Sqrdmlsh(const ZRegister& zd,
7083                 const ZRegister& za,
7084                 const ZRegister& zn,
7085                 const ZRegister& zm);
7086   void Sqrdmlsh(const ZRegister& zd,
7087                 const ZRegister& za,
7088                 const ZRegister& zn,
7089                 const ZRegister& zm,
7090                 int index);
Sqrdmulh(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int index)7091   void Sqrdmulh(const ZRegister& zd,
7092                 const ZRegister& zn,
7093                 const ZRegister& zm,
7094                 int index) {
7095     VIXL_ASSERT(allow_macro_instructions_);
7096     SingleEmissionCheckScope guard(this);
7097     sqrdmulh(zd, zn, zm, index);
7098   }
Sqrdmulh(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7099   void Sqrdmulh(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7100     VIXL_ASSERT(allow_macro_instructions_);
7101     SingleEmissionCheckScope guard(this);
7102     sqrdmulh(zd, zn, zm);
7103   }
7104   void Sqrshl(const ZRegister& zd,
7105               const PRegisterM& pg,
7106               const ZRegister& zn,
7107               const ZRegister& zm);
Sqrshrnb(const ZRegister & zd,const ZRegister & zn,int shift)7108   void Sqrshrnb(const ZRegister& zd, const ZRegister& zn, int shift) {
7109     VIXL_ASSERT(allow_macro_instructions_);
7110     SingleEmissionCheckScope guard(this);
7111     sqrshrnb(zd, zn, shift);
7112   }
Sqrshrnt(const ZRegister & zd,const ZRegister & zn,int shift)7113   void Sqrshrnt(const ZRegister& zd, const ZRegister& zn, int shift) {
7114     VIXL_ASSERT(allow_macro_instructions_);
7115     SingleEmissionCheckScope guard(this);
7116     sqrshrnt(zd, zn, shift);
7117   }
Sqrshrunb(const ZRegister & zd,const ZRegister & zn,int shift)7118   void Sqrshrunb(const ZRegister& zd, const ZRegister& zn, int shift) {
7119     VIXL_ASSERT(allow_macro_instructions_);
7120     SingleEmissionCheckScope guard(this);
7121     sqrshrunb(zd, zn, shift);
7122   }
Sqrshrunt(const ZRegister & zd,const ZRegister & zn,int shift)7123   void Sqrshrunt(const ZRegister& zd, const ZRegister& zn, int shift) {
7124     VIXL_ASSERT(allow_macro_instructions_);
7125     SingleEmissionCheckScope guard(this);
7126     sqrshrunt(zd, zn, shift);
7127   }
Sqshl(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)7128   void Sqshl(const ZRegister& zd,
7129              const PRegisterM& pg,
7130              const ZRegister& zn,
7131              int shift) {
7132     VIXL_ASSERT(allow_macro_instructions_);
7133     MovprfxHelperScope guard(this, zd, pg, zn);
7134     sqshl(zd, pg, zd, shift);
7135   }
7136   void Sqshl(const ZRegister& zd,
7137              const PRegisterM& pg,
7138              const ZRegister& zn,
7139              const ZRegister& zm);
Sqshlu(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)7140   void Sqshlu(const ZRegister& zd,
7141               const PRegisterM& pg,
7142               const ZRegister& zn,
7143               int shift) {
7144     VIXL_ASSERT(allow_macro_instructions_);
7145     MovprfxHelperScope guard(this, zd, pg, zn);
7146     sqshlu(zd, pg, zd, shift);
7147   }
Sqshrnb(const ZRegister & zd,const ZRegister & zn,int shift)7148   void Sqshrnb(const ZRegister& zd, const ZRegister& zn, int shift) {
7149     VIXL_ASSERT(allow_macro_instructions_);
7150     SingleEmissionCheckScope guard(this);
7151     sqshrnb(zd, zn, shift);
7152   }
Sqshrnt(const ZRegister & zd,const ZRegister & zn,int shift)7153   void Sqshrnt(const ZRegister& zd, const ZRegister& zn, int shift) {
7154     VIXL_ASSERT(allow_macro_instructions_);
7155     SingleEmissionCheckScope guard(this);
7156     sqshrnt(zd, zn, shift);
7157   }
Sqshrunb(const ZRegister & zd,const ZRegister & zn,int shift)7158   void Sqshrunb(const ZRegister& zd, const ZRegister& zn, int shift) {
7159     VIXL_ASSERT(allow_macro_instructions_);
7160     SingleEmissionCheckScope guard(this);
7161     sqshrunb(zd, zn, shift);
7162   }
Sqshrunt(const ZRegister & zd,const ZRegister & zn,int shift)7163   void Sqshrunt(const ZRegister& zd, const ZRegister& zn, int shift) {
7164     VIXL_ASSERT(allow_macro_instructions_);
7165     SingleEmissionCheckScope guard(this);
7166     sqshrunt(zd, zn, shift);
7167   }
7168   void Sqsub(const ZRegister& zd,
7169              const PRegisterM& pg,
7170              const ZRegister& zn,
7171              const ZRegister& zm);
Sqxtnb(const ZRegister & zd,const ZRegister & zn)7172   void Sqxtnb(const ZRegister& zd, const ZRegister& zn) {
7173     VIXL_ASSERT(allow_macro_instructions_);
7174     SingleEmissionCheckScope guard(this);
7175     sqxtnb(zd, zn);
7176   }
Sqxtnt(const ZRegister & zd,const ZRegister & zn)7177   void Sqxtnt(const ZRegister& zd, const ZRegister& zn) {
7178     VIXL_ASSERT(allow_macro_instructions_);
7179     SingleEmissionCheckScope guard(this);
7180     sqxtnt(zd, zn);
7181   }
Sqxtunb(const ZRegister & zd,const ZRegister & zn)7182   void Sqxtunb(const ZRegister& zd, const ZRegister& zn) {
7183     VIXL_ASSERT(allow_macro_instructions_);
7184     SingleEmissionCheckScope guard(this);
7185     sqxtunb(zd, zn);
7186   }
Sqxtunt(const ZRegister & zd,const ZRegister & zn)7187   void Sqxtunt(const ZRegister& zd, const ZRegister& zn) {
7188     VIXL_ASSERT(allow_macro_instructions_);
7189     SingleEmissionCheckScope guard(this);
7190     sqxtunt(zd, zn);
7191   }
Sri(const ZRegister & zd,const ZRegister & zn,int shift)7192   void Sri(const ZRegister& zd, const ZRegister& zn, int shift) {
7193     VIXL_ASSERT(allow_macro_instructions_);
7194     SingleEmissionCheckScope guard(this);
7195     sri(zd, zn, shift);
7196   }
7197   void Srshl(const ZRegister& zd,
7198              const PRegisterM& pg,
7199              const ZRegister& zn,
7200              const ZRegister& zm);
Srshr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)7201   void Srshr(const ZRegister& zd,
7202              const PRegisterM& pg,
7203              const ZRegister& zn,
7204              int shift) {
7205     VIXL_ASSERT(allow_macro_instructions_);
7206     MovprfxHelperScope guard(this, zd, pg, zn);
7207     srshr(zd, pg, zd, shift);
7208   }
7209   void Srsra(const ZRegister& zd,
7210              const ZRegister& za,
7211              const ZRegister& zn,
7212              int shift);
Sshllb(const ZRegister & zd,const ZRegister & zn,int shift)7213   void Sshllb(const ZRegister& zd, const ZRegister& zn, int shift) {
7214     VIXL_ASSERT(allow_macro_instructions_);
7215     SingleEmissionCheckScope guard(this);
7216     sshllb(zd, zn, shift);
7217   }
Sshllt(const ZRegister & zd,const ZRegister & zn,int shift)7218   void Sshllt(const ZRegister& zd, const ZRegister& zn, int shift) {
7219     VIXL_ASSERT(allow_macro_instructions_);
7220     SingleEmissionCheckScope guard(this);
7221     sshllt(zd, zn, shift);
7222   }
7223   void Ssra(const ZRegister& zd,
7224             const ZRegister& za,
7225             const ZRegister& zn,
7226             int shift);
Ssublb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7227   void Ssublb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7228     VIXL_ASSERT(allow_macro_instructions_);
7229     SingleEmissionCheckScope guard(this);
7230     ssublb(zd, zn, zm);
7231   }
Ssublbt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7232   void Ssublbt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7233     VIXL_ASSERT(allow_macro_instructions_);
7234     SingleEmissionCheckScope guard(this);
7235     ssublbt(zd, zn, zm);
7236   }
Ssublt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7237   void Ssublt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7238     VIXL_ASSERT(allow_macro_instructions_);
7239     SingleEmissionCheckScope guard(this);
7240     ssublt(zd, zn, zm);
7241   }
Ssubltb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7242   void Ssubltb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7243     VIXL_ASSERT(allow_macro_instructions_);
7244     SingleEmissionCheckScope guard(this);
7245     ssubltb(zd, zn, zm);
7246   }
Ssubwb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7247   void Ssubwb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7248     VIXL_ASSERT(allow_macro_instructions_);
7249     SingleEmissionCheckScope guard(this);
7250     ssubwb(zd, zn, zm);
7251   }
Ssubwt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7252   void Ssubwt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7253     VIXL_ASSERT(allow_macro_instructions_);
7254     SingleEmissionCheckScope guard(this);
7255     ssubwt(zd, zn, zm);
7256   }
Subhnb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7257   void Subhnb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7258     VIXL_ASSERT(allow_macro_instructions_);
7259     SingleEmissionCheckScope guard(this);
7260     subhnb(zd, zn, zm);
7261   }
Subhnt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7262   void Subhnt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7263     VIXL_ASSERT(allow_macro_instructions_);
7264     SingleEmissionCheckScope guard(this);
7265     subhnt(zd, zn, zm);
7266   }
7267   void Suqadd(const ZRegister& zd,
7268               const PRegisterM& pg,
7269               const ZRegister& zn,
7270               const ZRegister& zm);
Tbl(const ZRegister & zd,const ZRegister & zn1,const ZRegister & zn2,const ZRegister & zm)7271   void Tbl(const ZRegister& zd,
7272            const ZRegister& zn1,
7273            const ZRegister& zn2,
7274            const ZRegister& zm) {
7275     VIXL_ASSERT(allow_macro_instructions_);
7276     SingleEmissionCheckScope guard(this);
7277     tbl(zd, zn1, zn2, zm);
7278   }
Tbx(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7279   void Tbx(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7280     VIXL_ASSERT(allow_macro_instructions_);
7281     SingleEmissionCheckScope guard(this);
7282     tbx(zd, zn, zm);
7283   }
7284   void Uaba(const ZRegister& zd,
7285             const ZRegister& za,
7286             const ZRegister& zn,
7287             const ZRegister& zm);
7288   void Uabalb(const ZRegister& zd,
7289               const ZRegister& za,
7290               const ZRegister& zn,
7291               const ZRegister& zm);
7292   void Uabalt(const ZRegister& zd,
7293               const ZRegister& za,
7294               const ZRegister& zn,
7295               const ZRegister& zm);
Uabdlb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7296   void Uabdlb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7297     VIXL_ASSERT(allow_macro_instructions_);
7298     SingleEmissionCheckScope guard(this);
7299     uabdlb(zd, zn, zm);
7300   }
Uabdlt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7301   void Uabdlt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7302     VIXL_ASSERT(allow_macro_instructions_);
7303     SingleEmissionCheckScope guard(this);
7304     uabdlt(zd, zn, zm);
7305   }
Uadalp(const ZRegister & zda,const PRegisterM & pg,const ZRegister & zn)7306   void Uadalp(const ZRegister& zda, const PRegisterM& pg, const ZRegister& zn) {
7307     VIXL_ASSERT(allow_macro_instructions_);
7308     SingleEmissionCheckScope guard(this);
7309     uadalp(zda, pg, zn);
7310   }
Uaddlb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7311   void Uaddlb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7312     VIXL_ASSERT(allow_macro_instructions_);
7313     SingleEmissionCheckScope guard(this);
7314     uaddlb(zd, zn, zm);
7315   }
Uaddlt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7316   void Uaddlt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7317     VIXL_ASSERT(allow_macro_instructions_);
7318     SingleEmissionCheckScope guard(this);
7319     uaddlt(zd, zn, zm);
7320   }
Uaddwb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7321   void Uaddwb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7322     VIXL_ASSERT(allow_macro_instructions_);
7323     SingleEmissionCheckScope guard(this);
7324     uaddwb(zd, zn, zm);
7325   }
Uaddwt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7326   void Uaddwt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7327     VIXL_ASSERT(allow_macro_instructions_);
7328     SingleEmissionCheckScope guard(this);
7329     uaddwt(zd, zn, zm);
7330   }
7331   void Uhsub(const ZRegister& zd,
7332              const PRegisterM& pg,
7333              const ZRegister& zn,
7334              const ZRegister& zm);
7335   void Umaxp(const ZRegister& zd,
7336              const PRegisterM& pg,
7337              const ZRegister& zn,
7338              const ZRegister& zm);
7339   void Uminp(const ZRegister& zd,
7340              const PRegisterM& pg,
7341              const ZRegister& zn,
7342              const ZRegister& zm);
7343   void Umlalb(const ZRegister& zd,
7344               const ZRegister& za,
7345               const ZRegister& zn,
7346               const ZRegister& zm,
7347               int index);
7348   void Umlalb(const ZRegister& zd,
7349               const ZRegister& za,
7350               const ZRegister& zn,
7351               const ZRegister& zm);
7352   void Umlalt(const ZRegister& zd,
7353               const ZRegister& za,
7354               const ZRegister& zn,
7355               const ZRegister& zm,
7356               int index);
7357   void Umlalt(const ZRegister& zd,
7358               const ZRegister& za,
7359               const ZRegister& zn,
7360               const ZRegister& zm);
7361   void Umlslb(const ZRegister& zd,
7362               const ZRegister& za,
7363               const ZRegister& zn,
7364               const ZRegister& zm,
7365               int index);
7366   void Umlslb(const ZRegister& zd,
7367               const ZRegister& za,
7368               const ZRegister& zn,
7369               const ZRegister& zm);
7370   void Umlslt(const ZRegister& zd,
7371               const ZRegister& za,
7372               const ZRegister& zn,
7373               const ZRegister& zm,
7374               int index);
7375   void Umlslt(const ZRegister& zd,
7376               const ZRegister& za,
7377               const ZRegister& zn,
7378               const ZRegister& zm);
Umulh(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7379   void Umulh(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7380     VIXL_ASSERT(allow_macro_instructions_);
7381     SingleEmissionCheckScope guard(this);
7382     umulh(zd, zn, zm);
7383   }
Umullb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int index)7384   void Umullb(const ZRegister& zd,
7385               const ZRegister& zn,
7386               const ZRegister& zm,
7387               int index) {
7388     VIXL_ASSERT(allow_macro_instructions_);
7389     SingleEmissionCheckScope guard(this);
7390     umullb(zd, zn, zm, index);
7391   }
Umullb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7392   void Umullb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7393     VIXL_ASSERT(allow_macro_instructions_);
7394     SingleEmissionCheckScope guard(this);
7395     umullb(zd, zn, zm);
7396   }
Umullt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int index)7397   void Umullt(const ZRegister& zd,
7398               const ZRegister& zn,
7399               const ZRegister& zm,
7400               int index) {
7401     VIXL_ASSERT(allow_macro_instructions_);
7402     SingleEmissionCheckScope guard(this);
7403     umullt(zd, zn, zm, index);
7404   }
Umullt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7405   void Umullt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7406     VIXL_ASSERT(allow_macro_instructions_);
7407     SingleEmissionCheckScope guard(this);
7408     umullt(zd, zn, zm);
7409   }
7410   void Uqrshl(const ZRegister& zd,
7411               const PRegisterM& pg,
7412               const ZRegister& zn,
7413               const ZRegister& zm);
Uqrshrnb(const ZRegister & zd,const ZRegister & zn,int shift)7414   void Uqrshrnb(const ZRegister& zd, const ZRegister& zn, int shift) {
7415     VIXL_ASSERT(allow_macro_instructions_);
7416     SingleEmissionCheckScope guard(this);
7417     uqrshrnb(zd, zn, shift);
7418   }
Uqrshrnt(const ZRegister & zd,const ZRegister & zn,int shift)7419   void Uqrshrnt(const ZRegister& zd, const ZRegister& zn, int shift) {
7420     VIXL_ASSERT(allow_macro_instructions_);
7421     SingleEmissionCheckScope guard(this);
7422     uqrshrnt(zd, zn, shift);
7423   }
Uqshl(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)7424   void Uqshl(const ZRegister& zd,
7425              const PRegisterM& pg,
7426              const ZRegister& zn,
7427              int shift) {
7428     VIXL_ASSERT(allow_macro_instructions_);
7429     MovprfxHelperScope guard(this, zd, pg, zn);
7430     uqshl(zd, pg, zd, shift);
7431   }
7432   void Uqshl(const ZRegister& zd,
7433              const PRegisterM& pg,
7434              const ZRegister& zn,
7435              const ZRegister& zm);
Uqshrnb(const ZRegister & zd,const ZRegister & zn,int shift)7436   void Uqshrnb(const ZRegister& zd, const ZRegister& zn, int shift) {
7437     VIXL_ASSERT(allow_macro_instructions_);
7438     SingleEmissionCheckScope guard(this);
7439     uqshrnb(zd, zn, shift);
7440   }
Uqshrnt(const ZRegister & zd,const ZRegister & zn,int shift)7441   void Uqshrnt(const ZRegister& zd, const ZRegister& zn, int shift) {
7442     VIXL_ASSERT(allow_macro_instructions_);
7443     SingleEmissionCheckScope guard(this);
7444     uqshrnt(zd, zn, shift);
7445   }
7446   void Uqsub(const ZRegister& zd,
7447              const PRegisterM& pg,
7448              const ZRegister& zn,
7449              const ZRegister& zm);
Uqxtnb(const ZRegister & zd,const ZRegister & zn)7450   void Uqxtnb(const ZRegister& zd, const ZRegister& zn) {
7451     VIXL_ASSERT(allow_macro_instructions_);
7452     SingleEmissionCheckScope guard(this);
7453     uqxtnb(zd, zn);
7454   }
Uqxtnt(const ZRegister & zd,const ZRegister & zn)7455   void Uqxtnt(const ZRegister& zd, const ZRegister& zn) {
7456     VIXL_ASSERT(allow_macro_instructions_);
7457     SingleEmissionCheckScope guard(this);
7458     uqxtnt(zd, zn);
7459   }
Urecpe(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)7460   void Urecpe(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) {
7461     VIXL_ASSERT(allow_macro_instructions_);
7462     MovprfxHelperScope guard(this, zd, pg, zd);
7463     urecpe(zd, pg.Merging(), zn);
7464   }
7465   void Urshl(const ZRegister& zd,
7466              const PRegisterM& pg,
7467              const ZRegister& zn,
7468              const ZRegister& zm);
Urshr(const ZRegister & zd,const PRegisterM & pg,const ZRegister & zn,int shift)7469   void Urshr(const ZRegister& zd,
7470              const PRegisterM& pg,
7471              const ZRegister& zn,
7472              int shift) {
7473     VIXL_ASSERT(allow_macro_instructions_);
7474     MovprfxHelperScope guard(this, zd, pg, zn);
7475     urshr(zd, pg, zd, shift);
7476   }
Ursqrte(const ZRegister & zd,const PRegister & pg,const ZRegister & zn)7477   void Ursqrte(const ZRegister& zd, const PRegister& pg, const ZRegister& zn) {
7478     VIXL_ASSERT(allow_macro_instructions_);
7479     MovprfxHelperScope guard(this, zd, pg, zd);
7480     ursqrte(zd, pg.Merging(), zn);
7481   }
7482   void Ursra(const ZRegister& zd,
7483              const ZRegister& za,
7484              const ZRegister& zn,
7485              int shift);
Ushllb(const ZRegister & zd,const ZRegister & zn,int shift)7486   void Ushllb(const ZRegister& zd, const ZRegister& zn, int shift) {
7487     VIXL_ASSERT(allow_macro_instructions_);
7488     SingleEmissionCheckScope guard(this);
7489     ushllb(zd, zn, shift);
7490   }
Ushllt(const ZRegister & zd,const ZRegister & zn,int shift)7491   void Ushllt(const ZRegister& zd, const ZRegister& zn, int shift) {
7492     VIXL_ASSERT(allow_macro_instructions_);
7493     SingleEmissionCheckScope guard(this);
7494     ushllt(zd, zn, shift);
7495   }
7496   void Usqadd(const ZRegister& zd,
7497               const PRegisterM& pg,
7498               const ZRegister& zn,
7499               const ZRegister& zm);
7500   void Usra(const ZRegister& zd,
7501             const ZRegister& za,
7502             const ZRegister& zn,
7503             int shift);
Usublb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7504   void Usublb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7505     VIXL_ASSERT(allow_macro_instructions_);
7506     SingleEmissionCheckScope guard(this);
7507     usublb(zd, zn, zm);
7508   }
Usublt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7509   void Usublt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7510     VIXL_ASSERT(allow_macro_instructions_);
7511     SingleEmissionCheckScope guard(this);
7512     usublt(zd, zn, zm);
7513   }
Usubwb(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7514   void Usubwb(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7515     VIXL_ASSERT(allow_macro_instructions_);
7516     SingleEmissionCheckScope guard(this);
7517     usubwb(zd, zn, zm);
7518   }
Usubwt(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm)7519   void Usubwt(const ZRegister& zd, const ZRegister& zn, const ZRegister& zm) {
7520     VIXL_ASSERT(allow_macro_instructions_);
7521     SingleEmissionCheckScope guard(this);
7522     usubwt(zd, zn, zm);
7523   }
Whilege(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)7524   void Whilege(const PRegisterWithLaneSize& pd,
7525                const Register& rn,
7526                const Register& rm) {
7527     VIXL_ASSERT(allow_macro_instructions_);
7528     SingleEmissionCheckScope guard(this);
7529     whilege(pd, rn, rm);
7530   }
Whilegt(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)7531   void Whilegt(const PRegisterWithLaneSize& pd,
7532                const Register& rn,
7533                const Register& rm) {
7534     VIXL_ASSERT(allow_macro_instructions_);
7535     SingleEmissionCheckScope guard(this);
7536     whilegt(pd, rn, rm);
7537   }
Whilehi(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)7538   void Whilehi(const PRegisterWithLaneSize& pd,
7539                const Register& rn,
7540                const Register& rm) {
7541     VIXL_ASSERT(allow_macro_instructions_);
7542     SingleEmissionCheckScope guard(this);
7543     whilehi(pd, rn, rm);
7544   }
Whilehs(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)7545   void Whilehs(const PRegisterWithLaneSize& pd,
7546                const Register& rn,
7547                const Register& rm) {
7548     VIXL_ASSERT(allow_macro_instructions_);
7549     SingleEmissionCheckScope guard(this);
7550     whilehs(pd, rn, rm);
7551   }
Whilerw(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)7552   void Whilerw(const PRegisterWithLaneSize& pd,
7553                const Register& rn,
7554                const Register& rm) {
7555     VIXL_ASSERT(allow_macro_instructions_);
7556     SingleEmissionCheckScope guard(this);
7557     whilerw(pd, rn, rm);
7558   }
Whilewr(const PRegisterWithLaneSize & pd,const Register & rn,const Register & rm)7559   void Whilewr(const PRegisterWithLaneSize& pd,
7560                const Register& rn,
7561                const Register& rm) {
7562     VIXL_ASSERT(allow_macro_instructions_);
7563     SingleEmissionCheckScope guard(this);
7564     whilewr(pd, rn, rm);
7565   }
Xar(const ZRegister & zd,const ZRegister & zn,const ZRegister & zm,int shift)7566   void Xar(const ZRegister& zd,
7567            const ZRegister& zn,
7568            const ZRegister& zm,
7569            int shift) {
7570     VIXL_ASSERT(allow_macro_instructions_);
7571     if (zd.Aliases(zm)) {
7572       SingleEmissionCheckScope guard(this);
7573       xar(zd, zm, zn, shift);
7574     } else {
7575       MovprfxHelperScope guard(this, zd, zn);
7576       xar(zd, zd, zm, shift);
7577     }
7578   }
7579   void Fmmla(const ZRegister& zd,
7580              const ZRegister& za,
7581              const ZRegister& zn,
7582              const ZRegister& zm);
7583   void Smmla(const ZRegister& zd,
7584              const ZRegister& za,
7585              const ZRegister& zn,
7586              const ZRegister& zm);
7587   void Ummla(const ZRegister& zd,
7588              const ZRegister& za,
7589              const ZRegister& zn,
7590              const ZRegister& zm);
7591   void Usmmla(const ZRegister& zd,
7592               const ZRegister& za,
7593               const ZRegister& zn,
7594               const ZRegister& zm);
7595   void Usdot(const ZRegister& zd,
7596              const ZRegister& za,
7597              const ZRegister& zn,
7598              const ZRegister& zm);
7599   void Usdot(const ZRegister& zd,
7600              const ZRegister& za,
7601              const ZRegister& zn,
7602              const ZRegister& zm,
7603              int index);
7604   void Sudot(const ZRegister& zd,
7605              const ZRegister& za,
7606              const ZRegister& zn,
7607              const ZRegister& zm,
7608              int index);
7609 
7610   // MTE
7611   void St2g(const Register& rt, const MemOperand& addr);
7612   void Stg(const Register& rt, const MemOperand& addr);
7613   void Stgp(const Register& rt1, const Register& rt2, const MemOperand& addr);
7614   void Stz2g(const Register& rt, const MemOperand& addr);
7615   void Stzg(const Register& rt, const MemOperand& addr);
7616   void Ldg(const Register& rt, const MemOperand& addr);
7617 
Cpye(const Register & rd,const Register & rs,const Register & rn)7618   void Cpye(const Register& rd, const Register& rs, const Register& rn) {
7619     VIXL_ASSERT(allow_macro_instructions_);
7620     SingleEmissionCheckScope guard(this);
7621     cpye(rd, rs, rn);
7622   }
7623 
Cpyen(const Register & rd,const Register & rs,const Register & rn)7624   void Cpyen(const Register& rd, const Register& rs, const Register& rn) {
7625     VIXL_ASSERT(allow_macro_instructions_);
7626     SingleEmissionCheckScope guard(this);
7627     cpyen(rd, rs, rn);
7628   }
7629 
Cpyern(const Register & rd,const Register & rs,const Register & rn)7630   void Cpyern(const Register& rd, const Register& rs, const Register& rn) {
7631     VIXL_ASSERT(allow_macro_instructions_);
7632     SingleEmissionCheckScope guard(this);
7633     cpyern(rd, rs, rn);
7634   }
7635 
Cpyewn(const Register & rd,const Register & rs,const Register & rn)7636   void Cpyewn(const Register& rd, const Register& rs, const Register& rn) {
7637     VIXL_ASSERT(allow_macro_instructions_);
7638     SingleEmissionCheckScope guard(this);
7639     cpyewn(rd, rs, rn);
7640   }
7641 
Cpyfe(const Register & rd,const Register & rs,const Register & rn)7642   void Cpyfe(const Register& rd, const Register& rs, const Register& rn) {
7643     VIXL_ASSERT(allow_macro_instructions_);
7644     SingleEmissionCheckScope guard(this);
7645     cpyfe(rd, rs, rn);
7646   }
7647 
Cpyfen(const Register & rd,const Register & rs,const Register & rn)7648   void Cpyfen(const Register& rd, const Register& rs, const Register& rn) {
7649     VIXL_ASSERT(allow_macro_instructions_);
7650     SingleEmissionCheckScope guard(this);
7651     cpyfen(rd, rs, rn);
7652   }
7653 
Cpyfern(const Register & rd,const Register & rs,const Register & rn)7654   void Cpyfern(const Register& rd, const Register& rs, const Register& rn) {
7655     VIXL_ASSERT(allow_macro_instructions_);
7656     SingleEmissionCheckScope guard(this);
7657     cpyfern(rd, rs, rn);
7658   }
7659 
Cpyfewn(const Register & rd,const Register & rs,const Register & rn)7660   void Cpyfewn(const Register& rd, const Register& rs, const Register& rn) {
7661     VIXL_ASSERT(allow_macro_instructions_);
7662     SingleEmissionCheckScope guard(this);
7663     cpyfewn(rd, rs, rn);
7664   }
7665 
Cpyfm(const Register & rd,const Register & rs,const Register & rn)7666   void Cpyfm(const Register& rd, const Register& rs, const Register& rn) {
7667     VIXL_ASSERT(allow_macro_instructions_);
7668     SingleEmissionCheckScope guard(this);
7669     cpyfm(rd, rs, rn);
7670   }
7671 
Cpyfmn(const Register & rd,const Register & rs,const Register & rn)7672   void Cpyfmn(const Register& rd, const Register& rs, const Register& rn) {
7673     VIXL_ASSERT(allow_macro_instructions_);
7674     SingleEmissionCheckScope guard(this);
7675     cpyfmn(rd, rs, rn);
7676   }
7677 
Cpyfmrn(const Register & rd,const Register & rs,const Register & rn)7678   void Cpyfmrn(const Register& rd, const Register& rs, const Register& rn) {
7679     VIXL_ASSERT(allow_macro_instructions_);
7680     SingleEmissionCheckScope guard(this);
7681     cpyfmrn(rd, rs, rn);
7682   }
7683 
Cpyfmwn(const Register & rd,const Register & rs,const Register & rn)7684   void Cpyfmwn(const Register& rd, const Register& rs, const Register& rn) {
7685     VIXL_ASSERT(allow_macro_instructions_);
7686     SingleEmissionCheckScope guard(this);
7687     cpyfmwn(rd, rs, rn);
7688   }
7689 
Cpyfp(const Register & rd,const Register & rs,const Register & rn)7690   void Cpyfp(const Register& rd, const Register& rs, const Register& rn) {
7691     VIXL_ASSERT(allow_macro_instructions_);
7692     SingleEmissionCheckScope guard(this);
7693     cpyfp(rd, rs, rn);
7694   }
7695 
Cpyfpn(const Register & rd,const Register & rs,const Register & rn)7696   void Cpyfpn(const Register& rd, const Register& rs, const Register& rn) {
7697     VIXL_ASSERT(allow_macro_instructions_);
7698     SingleEmissionCheckScope guard(this);
7699     cpyfpn(rd, rs, rn);
7700   }
7701 
Cpyfprn(const Register & rd,const Register & rs,const Register & rn)7702   void Cpyfprn(const Register& rd, const Register& rs, const Register& rn) {
7703     VIXL_ASSERT(allow_macro_instructions_);
7704     SingleEmissionCheckScope guard(this);
7705     cpyfprn(rd, rs, rn);
7706   }
7707 
Cpyfpwn(const Register & rd,const Register & rs,const Register & rn)7708   void Cpyfpwn(const Register& rd, const Register& rs, const Register& rn) {
7709     VIXL_ASSERT(allow_macro_instructions_);
7710     SingleEmissionCheckScope guard(this);
7711     cpyfpwn(rd, rs, rn);
7712   }
7713 
Cpym(const Register & rd,const Register & rs,const Register & rn)7714   void Cpym(const Register& rd, const Register& rs, const Register& rn) {
7715     VIXL_ASSERT(allow_macro_instructions_);
7716     SingleEmissionCheckScope guard(this);
7717     cpym(rd, rs, rn);
7718   }
7719 
Cpymn(const Register & rd,const Register & rs,const Register & rn)7720   void Cpymn(const Register& rd, const Register& rs, const Register& rn) {
7721     VIXL_ASSERT(allow_macro_instructions_);
7722     SingleEmissionCheckScope guard(this);
7723     cpymn(rd, rs, rn);
7724   }
7725 
Cpymrn(const Register & rd,const Register & rs,const Register & rn)7726   void Cpymrn(const Register& rd, const Register& rs, const Register& rn) {
7727     VIXL_ASSERT(allow_macro_instructions_);
7728     SingleEmissionCheckScope guard(this);
7729     cpymrn(rd, rs, rn);
7730   }
7731 
Cpymwn(const Register & rd,const Register & rs,const Register & rn)7732   void Cpymwn(const Register& rd, const Register& rs, const Register& rn) {
7733     VIXL_ASSERT(allow_macro_instructions_);
7734     SingleEmissionCheckScope guard(this);
7735     cpymwn(rd, rs, rn);
7736   }
7737 
Cpyp(const Register & rd,const Register & rs,const Register & rn)7738   void Cpyp(const Register& rd, const Register& rs, const Register& rn) {
7739     VIXL_ASSERT(allow_macro_instructions_);
7740     SingleEmissionCheckScope guard(this);
7741     cpyp(rd, rs, rn);
7742   }
7743 
Cpypn(const Register & rd,const Register & rs,const Register & rn)7744   void Cpypn(const Register& rd, const Register& rs, const Register& rn) {
7745     VIXL_ASSERT(allow_macro_instructions_);
7746     SingleEmissionCheckScope guard(this);
7747     cpypn(rd, rs, rn);
7748   }
7749 
Cpyprn(const Register & rd,const Register & rs,const Register & rn)7750   void Cpyprn(const Register& rd, const Register& rs, const Register& rn) {
7751     VIXL_ASSERT(allow_macro_instructions_);
7752     SingleEmissionCheckScope guard(this);
7753     cpyprn(rd, rs, rn);
7754   }
7755 
Cpypwn(const Register & rd,const Register & rs,const Register & rn)7756   void Cpypwn(const Register& rd, const Register& rs, const Register& rn) {
7757     VIXL_ASSERT(allow_macro_instructions_);
7758     SingleEmissionCheckScope guard(this);
7759     cpypwn(rd, rs, rn);
7760   }
7761 
Sete(const Register & rd,const Register & rn,const Register & rs)7762   void Sete(const Register& rd, const Register& rn, const Register& rs) {
7763     VIXL_ASSERT(allow_macro_instructions_);
7764     SingleEmissionCheckScope guard(this);
7765     sete(rd, rn, rs);
7766   }
7767 
Seten(const Register & rd,const Register & rn,const Register & rs)7768   void Seten(const Register& rd, const Register& rn, const Register& rs) {
7769     VIXL_ASSERT(allow_macro_instructions_);
7770     SingleEmissionCheckScope guard(this);
7771     seten(rd, rn, rs);
7772   }
7773 
Setge(const Register & rd,const Register & rn,const Register & rs)7774   void Setge(const Register& rd, const Register& rn, const Register& rs) {
7775     VIXL_ASSERT(allow_macro_instructions_);
7776     SingleEmissionCheckScope guard(this);
7777     setge(rd, rn, rs);
7778   }
7779 
Setgen(const Register & rd,const Register & rn,const Register & rs)7780   void Setgen(const Register& rd, const Register& rn, const Register& rs) {
7781     VIXL_ASSERT(allow_macro_instructions_);
7782     SingleEmissionCheckScope guard(this);
7783     setgen(rd, rn, rs);
7784   }
7785 
Setgm(const Register & rd,const Register & rn,const Register & rs)7786   void Setgm(const Register& rd, const Register& rn, const Register& rs) {
7787     VIXL_ASSERT(allow_macro_instructions_);
7788     SingleEmissionCheckScope guard(this);
7789     setgm(rd, rn, rs);
7790   }
7791 
Setgmn(const Register & rd,const Register & rn,const Register & rs)7792   void Setgmn(const Register& rd, const Register& rn, const Register& rs) {
7793     VIXL_ASSERT(allow_macro_instructions_);
7794     SingleEmissionCheckScope guard(this);
7795     setgmn(rd, rn, rs);
7796   }
7797 
Setgp(const Register & rd,const Register & rn,const Register & rs)7798   void Setgp(const Register& rd, const Register& rn, const Register& rs) {
7799     VIXL_ASSERT(allow_macro_instructions_);
7800     SingleEmissionCheckScope guard(this);
7801     setgp(rd, rn, rs);
7802   }
7803 
Setgpn(const Register & rd,const Register & rn,const Register & rs)7804   void Setgpn(const Register& rd, const Register& rn, const Register& rs) {
7805     VIXL_ASSERT(allow_macro_instructions_);
7806     SingleEmissionCheckScope guard(this);
7807     setgpn(rd, rn, rs);
7808   }
7809 
Setm(const Register & rd,const Register & rn,const Register & rs)7810   void Setm(const Register& rd, const Register& rn, const Register& rs) {
7811     VIXL_ASSERT(allow_macro_instructions_);
7812     SingleEmissionCheckScope guard(this);
7813     setm(rd, rn, rs);
7814   }
7815 
Setmn(const Register & rd,const Register & rn,const Register & rs)7816   void Setmn(const Register& rd, const Register& rn, const Register& rs) {
7817     VIXL_ASSERT(allow_macro_instructions_);
7818     SingleEmissionCheckScope guard(this);
7819     setmn(rd, rn, rs);
7820   }
7821 
Setp(const Register & rd,const Register & rn,const Register & rs)7822   void Setp(const Register& rd, const Register& rn, const Register& rs) {
7823     VIXL_ASSERT(allow_macro_instructions_);
7824     SingleEmissionCheckScope guard(this);
7825     setp(rd, rn, rs);
7826   }
7827 
Setpn(const Register & rd,const Register & rn,const Register & rs)7828   void Setpn(const Register& rd, const Register& rn, const Register& rs) {
7829     VIXL_ASSERT(allow_macro_instructions_);
7830     SingleEmissionCheckScope guard(this);
7831     setpn(rd, rn, rs);
7832   }
7833 
7834 // Macro assembler wrappers that package the MOPS instructions into a single
7835 // call.
7836 #define MOPS_LIST(V)  \
7837   V(Set, set, )       \
7838   V(Setn, set, n)     \
7839   V(Setg, setg, )     \
7840   V(Setgn, setg, n)   \
7841   V(Cpy, cpy, )       \
7842   V(Cpyn, cpy, n)     \
7843   V(Cpyrn, cpy, rn)   \
7844   V(Cpywn, cpy, wn)   \
7845   V(Cpyf, cpyf, )     \
7846   V(Cpyfn, cpyf, n)   \
7847   V(Cpyfrn, cpyf, rn) \
7848   V(Cpyfwn, cpyf, wn)
7849 
7850 #define DEFINE_MACRO_ASM_FUNC(MASM, ASMPREFIX, ASMSUFFIX)                 \
7851   void MASM(const Register& ra, const Register& rb, const Register& rc) { \
7852     ExactAssemblyScope scope(this, 3 * kInstructionSize);                 \
7853     ASMPREFIX##p##ASMSUFFIX(ra, rb, rc);                                  \
7854     ASMPREFIX##m##ASMSUFFIX(ra, rb, rc);                                  \
7855     ASMPREFIX##e##ASMSUFFIX(ra, rb, rc);                                  \
7856   }
MOPS_LIST(DEFINE_MACRO_ASM_FUNC)7857   MOPS_LIST(DEFINE_MACRO_ASM_FUNC)
7858 #undef DEFINE_MACRO_ASM_FUNC
7859 
7860   void Abs(const Register& rd, const Register& rn) {
7861     VIXL_ASSERT(allow_macro_instructions_);
7862     SingleEmissionCheckScope guard(this);
7863     abs(rd, rn);
7864   }
7865 
Cnt(const Register & rd,const Register & rn)7866   void Cnt(const Register& rd, const Register& rn) {
7867     VIXL_ASSERT(allow_macro_instructions_);
7868     SingleEmissionCheckScope guard(this);
7869     cnt(rd, rn);
7870   }
7871 
Ctz(const Register & rd,const Register & rn)7872   void Ctz(const Register& rd, const Register& rn) {
7873     VIXL_ASSERT(allow_macro_instructions_);
7874     SingleEmissionCheckScope guard(this);
7875     ctz(rd, rn);
7876   }
7877 
7878   void Smax(const Register& rd, const Register& rn, const Operand& op);
7879   void Smin(const Register& rd, const Register& rn, const Operand& op);
7880   void Umax(const Register& rd, const Register& rn, const Operand& op);
7881   void Umin(const Register& rd, const Register& rn, const Operand& op);
7882 
7883   template <typename T>
CreateLiteralDestroyedWithPool(T value)7884   Literal<T>* CreateLiteralDestroyedWithPool(T value) {
7885     return new Literal<T>(value,
7886                           &literal_pool_,
7887                           RawLiteral::kDeletedOnPoolDestruction);
7888   }
7889 
7890   template <typename T>
CreateLiteralDestroyedWithPool(T high64,T low64)7891   Literal<T>* CreateLiteralDestroyedWithPool(T high64, T low64) {
7892     return new Literal<T>(high64,
7893                           low64,
7894                           &literal_pool_,
7895                           RawLiteral::kDeletedOnPoolDestruction);
7896   }
7897 
7898   // Push the system stack pointer (sp) down to allow the same to be done to
7899   // the current stack pointer (according to StackPointer()). This must be
7900   // called _before_ accessing the memory.
7901   //
7902   // This is necessary when pushing or otherwise adding things to the stack, to
7903   // satisfy the AAPCS64 constraint that the memory below the system stack
7904   // pointer is not accessed.
7905   //
7906   // This method asserts that StackPointer() is not sp, since the call does
7907   // not make sense in that context.
7908   //
7909   // TODO: This method can only accept values of 'space' that can be encoded in
7910   // one instruction. Refer to the implementation for details.
7911   void BumpSystemStackPointer(const Operand& space);
7912 
AllowMacroInstructions()7913   virtual bool AllowMacroInstructions() const VIXL_OVERRIDE {
7914     return allow_macro_instructions_;
7915   }
7916 
ArePoolsBlocked()7917   virtual bool ArePoolsBlocked() const VIXL_OVERRIDE {
7918     return IsLiteralPoolBlocked() && IsVeneerPoolBlocked();
7919   }
7920 
SetGenerateSimulatorCode(bool value)7921   void SetGenerateSimulatorCode(bool value) {
7922     generate_simulator_code_ = value;
7923   }
7924 
GenerateSimulatorCode()7925   bool GenerateSimulatorCode() const { return generate_simulator_code_; }
7926 
GetLiteralPoolSize()7927   size_t GetLiteralPoolSize() const { return literal_pool_.GetSize(); }
7928   VIXL_DEPRECATED("GetLiteralPoolSize", size_t LiteralPoolSize() const) {
7929     return GetLiteralPoolSize();
7930   }
7931 
GetLiteralPoolMaxSize()7932   size_t GetLiteralPoolMaxSize() const { return literal_pool_.GetMaxSize(); }
7933   VIXL_DEPRECATED("GetLiteralPoolMaxSize", size_t LiteralPoolMaxSize() const) {
7934     return GetLiteralPoolMaxSize();
7935   }
7936 
GetVeneerPoolMaxSize()7937   size_t GetVeneerPoolMaxSize() const { return veneer_pool_.GetMaxSize(); }
7938   VIXL_DEPRECATED("GetVeneerPoolMaxSize", size_t VeneerPoolMaxSize() const) {
7939     return GetVeneerPoolMaxSize();
7940   }
7941 
7942   // The number of unresolved branches that may require a veneer.
GetNumberOfPotentialVeneers()7943   int GetNumberOfPotentialVeneers() const {
7944     return veneer_pool_.GetNumberOfPotentialVeneers();
7945   }
7946   VIXL_DEPRECATED("GetNumberOfPotentialVeneers",
NumberOfPotentialVeneers()7947                   int NumberOfPotentialVeneers() const) {
7948     return GetNumberOfPotentialVeneers();
7949   }
7950 
GetNextCheckPoint()7951   ptrdiff_t GetNextCheckPoint() const {
7952     ptrdiff_t next_checkpoint_for_pools =
7953         std::min(literal_pool_.GetCheckpoint(), veneer_pool_.GetCheckpoint());
7954     return std::min(next_checkpoint_for_pools,
7955                     static_cast<ptrdiff_t>(GetBuffer().GetCapacity()));
7956   }
7957   VIXL_DEPRECATED("GetNextCheckPoint", ptrdiff_t NextCheckPoint()) {
7958     return GetNextCheckPoint();
7959   }
7960 
EmitLiteralPool(LiteralPool::EmitOption option)7961   void EmitLiteralPool(LiteralPool::EmitOption option) {
7962     if (!literal_pool_.IsEmpty()) literal_pool_.Emit(option);
7963 
7964     checkpoint_ = GetNextCheckPoint();
7965     recommended_checkpoint_ = literal_pool_.GetNextRecommendedCheckpoint();
7966   }
7967 
7968   void CheckEmitFor(size_t amount);
EnsureEmitFor(size_t amount)7969   void EnsureEmitFor(size_t amount) {
7970     ptrdiff_t offset = amount;
7971     ptrdiff_t max_pools_size =
7972         literal_pool_.GetMaxSize() + veneer_pool_.GetMaxSize();
7973     ptrdiff_t cursor = GetCursorOffset();
7974     if ((cursor >= recommended_checkpoint_) ||
7975         ((cursor + offset + max_pools_size) >= checkpoint_)) {
7976       CheckEmitFor(amount);
7977     }
7978   }
7979 
7980   void CheckEmitPoolsFor(size_t amount);
EnsureEmitPoolsFor(size_t amount)7981   virtual void EnsureEmitPoolsFor(size_t amount) VIXL_OVERRIDE {
7982     ptrdiff_t offset = amount;
7983     ptrdiff_t max_pools_size =
7984         literal_pool_.GetMaxSize() + veneer_pool_.GetMaxSize();
7985     ptrdiff_t cursor = GetCursorOffset();
7986     if ((cursor >= recommended_checkpoint_) ||
7987         ((cursor + offset + max_pools_size) >= checkpoint_)) {
7988       CheckEmitPoolsFor(amount);
7989     }
7990   }
7991 
7992   // Set the current stack pointer, but don't generate any code.
SetStackPointer(const Register & stack_pointer)7993   void SetStackPointer(const Register& stack_pointer) {
7994     VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(stack_pointer));
7995     sp_ = stack_pointer;
7996   }
7997 
7998   // Return the current stack pointer, as set by SetStackPointer.
StackPointer()7999   const Register& StackPointer() const { return sp_; }
8000 
GetScratchRegisterList()8001   CPURegList* GetScratchRegisterList() { return &tmp_list_; }
8002   VIXL_DEPRECATED("GetScratchRegisterList", CPURegList* TmpList()) {
8003     return GetScratchRegisterList();
8004   }
8005 
GetScratchVRegisterList()8006   CPURegList* GetScratchVRegisterList() { return &v_tmp_list_; }
8007   VIXL_DEPRECATED("GetScratchVRegisterList", CPURegList* FPTmpList()) {
8008     return GetScratchVRegisterList();
8009   }
8010 
GetScratchPRegisterList()8011   CPURegList* GetScratchPRegisterList() { return &p_tmp_list_; }
8012 
8013   // Get or set the current (most-deeply-nested) UseScratchRegisterScope.
SetCurrentScratchRegisterScope(UseScratchRegisterScope * scope)8014   void SetCurrentScratchRegisterScope(UseScratchRegisterScope* scope) {
8015     current_scratch_scope_ = scope;
8016   }
GetCurrentScratchRegisterScope()8017   UseScratchRegisterScope* GetCurrentScratchRegisterScope() {
8018     return current_scratch_scope_;
8019   }
8020 
8021   // Like printf, but print at run-time from generated code.
8022   //
8023   // The caller must ensure that arguments for floating-point placeholders
8024   // (such as %e, %f or %g) are VRegisters in format 1S or 1D, and that
8025   // arguments for integer placeholders are Registers.
8026   //
8027   // At the moment it is only possible to print the value of sp if it is the
8028   // current stack pointer. Otherwise, the MacroAssembler will automatically
8029   // update sp on every push (using BumpSystemStackPointer), so determining its
8030   // value is difficult.
8031   //
8032   // Format placeholders that refer to more than one argument, or to a specific
8033   // argument, are not supported. This includes formats like "%1$d" or "%.*d".
8034   //
8035   // This function automatically preserves caller-saved registers so that
8036   // calling code can use Printf at any point without having to worry about
8037   // corruption. The preservation mechanism generates a lot of code. If this is
8038   // a problem, preserve the important registers manually and then call
8039   // PrintfNoPreserve. Callee-saved registers are not used by Printf, and are
8040   // implicitly preserved.
8041   void Printf(const char* format,
8042               CPURegister arg0 = NoCPUReg,
8043               CPURegister arg1 = NoCPUReg,
8044               CPURegister arg2 = NoCPUReg,
8045               CPURegister arg3 = NoCPUReg);
8046 
8047   // Like Printf, but don't preserve any caller-saved registers, not even 'lr'.
8048   //
8049   // The return code from the system printf call will be returned in x0.
8050   void PrintfNoPreserve(const char* format,
8051                         const CPURegister& arg0 = NoCPUReg,
8052                         const CPURegister& arg1 = NoCPUReg,
8053                         const CPURegister& arg2 = NoCPUReg,
8054                         const CPURegister& arg3 = NoCPUReg);
8055 
8056   // Trace control when running the debug simulator.
8057   //
8058   // For example:
8059   //
8060   // __ Trace(LOG_REGS, TRACE_ENABLE);
8061   // Will add registers to the trace if it wasn't already the case.
8062   //
8063   // __ Trace(LOG_DISASM, TRACE_DISABLE);
8064   // Will stop logging disassembly. It has no effect if the disassembly wasn't
8065   // already being logged.
8066   void Trace(TraceParameters parameters, TraceCommand command);
8067 
8068   // Log the requested data independently of what is being traced.
8069   //
8070   // For example:
8071   //
8072   // __ Log(LOG_FLAGS)
8073   // Will output the flags.
8074   void Log(TraceParameters parameters);
8075 
8076   // Enable or disable CPU features dynamically. This mechanism allows users to
8077   // strictly check the use of CPU features in different regions of code.
8078   void SetSimulatorCPUFeatures(const CPUFeatures& features);
8079   void EnableSimulatorCPUFeatures(const CPUFeatures& features);
8080   void DisableSimulatorCPUFeatures(const CPUFeatures& features);
8081   void SaveSimulatorCPUFeatures();
8082   void RestoreSimulatorCPUFeatures();
8083 
GetLiteralPool()8084   LiteralPool* GetLiteralPool() { return &literal_pool_; }
8085 
8086 // Support for simulated runtime calls.
8087 
8088 // `CallRuntime` requires variadic templating, that is only available from
8089 // C++11.
8090 #if __cplusplus >= 201103L
8091 #define VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT
8092 #endif  // #if __cplusplus >= 201103L
8093 
8094 #ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT
8095   template <typename R, typename... P>
8096   void CallRuntimeHelper(R (*function)(P...), RuntimeCallType call_type);
8097 
8098   template <typename R, typename... P>
CallRuntime(R (* function)(P...))8099   void CallRuntime(R (*function)(P...)) {
8100     CallRuntimeHelper(function, kCallRuntime);
8101   }
8102 
8103   template <typename R, typename... P>
TailCallRuntime(R (* function)(P...))8104   void TailCallRuntime(R (*function)(P...)) {
8105     CallRuntimeHelper(function, kTailCallRuntime);
8106   }
8107 #endif  // #ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT
8108 
8109  protected:
BlockLiteralPool()8110   void BlockLiteralPool() { literal_pool_.Block(); }
ReleaseLiteralPool()8111   void ReleaseLiteralPool() { literal_pool_.Release(); }
IsLiteralPoolBlocked()8112   bool IsLiteralPoolBlocked() const { return literal_pool_.IsBlocked(); }
BlockVeneerPool()8113   void BlockVeneerPool() { veneer_pool_.Block(); }
ReleaseVeneerPool()8114   void ReleaseVeneerPool() { veneer_pool_.Release(); }
IsVeneerPoolBlocked()8115   bool IsVeneerPoolBlocked() const { return veneer_pool_.IsBlocked(); }
8116 
BlockPools()8117   virtual void BlockPools() VIXL_OVERRIDE {
8118     BlockLiteralPool();
8119     BlockVeneerPool();
8120   }
8121 
ReleasePools()8122   virtual void ReleasePools() VIXL_OVERRIDE {
8123     ReleaseLiteralPool();
8124     ReleaseVeneerPool();
8125   }
8126 
8127   // The scopes below need to able to block and release a particular pool.
8128   // TODO: Consider removing those scopes or move them to
8129   // code-generation-scopes-vixl.h.
8130   friend class BlockPoolsScope;
8131   friend class BlockLiteralPoolScope;
8132   friend class BlockVeneerPoolScope;
8133 
SetAllowMacroInstructions(bool value)8134   virtual void SetAllowMacroInstructions(bool value) VIXL_OVERRIDE {
8135     allow_macro_instructions_ = value;
8136   }
8137 
8138   // Helper used to query information about code generation and to generate
8139   // code for `csel`.
8140   // Here and for the related helpers below:
8141   // - Code is generated when `masm` is not `NULL`.
8142   // - On return and when set, `should_synthesise_left` and
8143   //   `should_synthesise_right` will indicate whether `left` and `right`
8144   //   should be synthesized in a temporary register.
8145   static void CselHelper(MacroAssembler* masm,
8146                          const Register& rd,
8147                          Operand left,
8148                          Operand right,
8149                          Condition cond,
8150                          bool* should_synthesise_left = NULL,
8151                          bool* should_synthesise_right = NULL);
8152 
8153   // The helper returns `true` if it can handle the specified arguments.
8154   // Also see comments for `CselHelper()`.
8155   static bool CselSubHelperTwoImmediates(MacroAssembler* masm,
8156                                          const Register& rd,
8157                                          int64_t left,
8158                                          int64_t right,
8159                                          Condition cond,
8160                                          bool* should_synthesise_left,
8161                                          bool* should_synthesise_right);
8162 
8163   // See comments for `CselHelper()`.
8164   static bool CselSubHelperTwoOrderedImmediates(MacroAssembler* masm,
8165                                                 const Register& rd,
8166                                                 int64_t left,
8167                                                 int64_t right,
8168                                                 Condition cond);
8169 
8170   // See comments for `CselHelper()`.
8171   static void CselSubHelperRightSmallImmediate(MacroAssembler* masm,
8172                                                UseScratchRegisterScope* temps,
8173                                                const Register& rd,
8174                                                const Operand& left,
8175                                                const Operand& right,
8176                                                Condition cond,
8177                                                bool* should_synthesise_left);
8178 
8179   // Generate code to calculate the address represented by `addr` and write it
8180   // into `xd`. This is used as a common fall-back for out-of-range load and
8181   // store operands.
8182   //
8183   // The vl_divisor_log2 argument is used to scale the VL, for use with
8184   // SVE_MUL_VL.
8185   void CalculateSVEAddress(const Register& xd,
8186                            const SVEMemOperand& addr,
8187                            int vl_divisor_log2 = 0);
8188 
CalculateSVEAddress(const Register & xd,const SVEMemOperand & addr,const CPURegister & rt)8189   void CalculateSVEAddress(const Register& xd,
8190                            const SVEMemOperand& addr,
8191                            const CPURegister& rt) {
8192     VIXL_ASSERT(rt.IsPRegister() || rt.IsZRegister());
8193     int vl_divisor_log2 = rt.IsPRegister() ? kZRegBitsPerPRegBitLog2 : 0;
8194     CalculateSVEAddress(xd, addr, vl_divisor_log2);
8195   }
8196 
SetFPNaNPropagationOption(FPMacroNaNPropagationOption nan_option)8197   void SetFPNaNPropagationOption(FPMacroNaNPropagationOption nan_option) {
8198     fp_nan_propagation_ = nan_option;
8199   }
8200 
ResolveFPNaNPropagationOption(FPMacroNaNPropagationOption * nan_option)8201   void ResolveFPNaNPropagationOption(FPMacroNaNPropagationOption* nan_option) {
8202     // The input option has priority over the option that has set.
8203     if (*nan_option == NoFPMacroNaNPropagationSelected) {
8204       *nan_option = fp_nan_propagation_;
8205     }
8206     VIXL_ASSERT(*nan_option != NoFPMacroNaNPropagationSelected);
8207   }
8208 
8209  private:
8210   // The actual Push and Pop implementations. These don't generate any code
8211   // other than that required for the push or pop. This allows
8212   // (Push|Pop)CPURegList to bundle together setup code for a large block of
8213   // registers.
8214   //
8215   // Note that size is per register, and is specified in bytes.
8216   void PushHelper(int count,
8217                   int size,
8218                   const CPURegister& src0,
8219                   const CPURegister& src1,
8220                   const CPURegister& src2,
8221                   const CPURegister& src3);
8222   void PopHelper(int count,
8223                  int size,
8224                  const CPURegister& dst0,
8225                  const CPURegister& dst1,
8226                  const CPURegister& dst2,
8227                  const CPURegister& dst3);
8228 
8229   void Movi16bitHelper(const VRegister& vd, uint64_t imm);
8230   void Movi32bitHelper(const VRegister& vd, uint64_t imm);
8231   void Movi64bitHelper(const VRegister& vd, uint64_t imm);
8232 
8233   // Perform necessary maintenance operations before a push or pop.
8234   //
8235   // Note that size is per register, and is specified in bytes.
8236   void PrepareForPush(int count, int size);
8237   void PrepareForPop(int count, int size);
8238 
8239   // The actual implementation of load and store operations for CPURegList.
8240   enum LoadStoreCPURegListAction { kLoad, kStore };
8241   void LoadStoreCPURegListHelper(LoadStoreCPURegListAction operation,
8242                                  CPURegList registers,
8243                                  const MemOperand& mem);
8244   // Returns a MemOperand suitable for loading or storing a CPURegList at `dst`.
8245   // This helper may allocate registers from `scratch_scope` and generate code
8246   // to compute an intermediate address. The resulting MemOperand is only valid
8247   // as long as `scratch_scope` remains valid.
8248   MemOperand BaseMemOperandForLoadStoreCPURegList(
8249       const CPURegList& registers,
8250       const MemOperand& mem,
8251       UseScratchRegisterScope* scratch_scope);
8252 
LabelIsOutOfRange(Label * label,ImmBranchType branch_type)8253   bool LabelIsOutOfRange(Label* label, ImmBranchType branch_type) {
8254     int64_t offset = label->GetLocation() - GetCursorOffset();
8255     VIXL_ASSERT(IsMultiple(offset, kInstructionSize));
8256     return !Instruction::IsValidImmPCOffset(branch_type,
8257                                             offset / kInstructionSize);
8258   }
8259 
8260   void ConfigureSimulatorCPUFeaturesHelper(const CPUFeatures& features,
8261                                            DebugHltOpcode action);
8262 
8263   void CompareHelper(Condition cond,
8264                      const PRegisterWithLaneSize& pd,
8265                      const PRegisterZ& pg,
8266                      const ZRegister& zn,
8267                      IntegerOperand imm);
8268 
8269   // E.g. Ld1rb.
8270   typedef void (Assembler::*SVELoadBroadcastFn)(const ZRegister& zt,
8271                                                 const PRegisterZ& pg,
8272                                                 const SVEMemOperand& addr);
8273 
8274   void SVELoadBroadcastImmHelper(const ZRegister& zt,
8275                                  const PRegisterZ& pg,
8276                                  const SVEMemOperand& addr,
8277                                  SVELoadBroadcastFn fn,
8278                                  int divisor);
8279 
8280   // E.g. ldr/str
8281   typedef void (Assembler::*SVELoadStoreFn)(const CPURegister& rt,
8282                                             const SVEMemOperand& addr);
8283 
8284   void SVELoadStoreScalarImmHelper(const CPURegister& rt,
8285                                    const SVEMemOperand& addr,
8286                                    SVELoadStoreFn fn);
8287 
8288   typedef void (Assembler::*SVELoad1Fn)(const ZRegister& zt,
8289                                         const PRegisterZ& pg,
8290                                         const SVEMemOperand& addr);
8291   typedef void (Assembler::*SVEStore1Fn)(const ZRegister& zt,
8292                                          const PRegister& pg,
8293                                          const SVEMemOperand& addr);
8294 
8295   // Helper for predicated Z register loads with addressing modes not directly
8296   // encodable in the instruction. The supported_modifier parameter indicates
8297   // which offset modifier the calling instruction encoder supports (eg.
8298   // SVE_MUL_VL). The ratio log2 of VL to memory access size is passed as
8299   // vl_divisor_log2; pass -1 to indicate no dependency.
8300   template <typename Tg, typename Tf>
8301   void SVELoadStoreNTBroadcastQOHelper(
8302       const ZRegister& zt,
8303       const Tg& pg,
8304       const SVEMemOperand& addr,
8305       Tf fn,
8306       int imm_bits,
8307       int shift_amount,
8308       SVEOffsetModifier supported_modifier = NO_SVE_OFFSET_MODIFIER,
8309       int vl_divisor_log2 = 0);
8310 
8311   template <typename Tg, typename Tf>
8312   void SVELoadStore1Helper(int msize_in_bytes_log2,
8313                            const ZRegister& zt,
8314                            const Tg& pg,
8315                            const SVEMemOperand& addr,
8316                            Tf fn);
8317 
8318   template <typename Tf>
8319   void SVELoadFFHelper(int msize_in_bytes_log2,
8320                        const ZRegister& zt,
8321                        const PRegisterZ& pg,
8322                        const SVEMemOperand& addr,
8323                        Tf fn);
8324 
8325   typedef void (MacroAssembler::*IntWideImmMacroFn)(const ZRegister& zd,
8326                                                     const ZRegister& zn,
8327                                                     IntegerOperand imm);
8328 
8329   typedef void (Assembler::*IntWideImmShiftFn)(const ZRegister& zd,
8330                                                const ZRegister& zn,
8331                                                int imm,
8332                                                int shift);
8333 
8334   typedef void (Assembler::*Int3ArithFn)(const ZRegister& zd,
8335                                          const ZRegister& zn,
8336                                          const ZRegister& zm);
8337 
8338   typedef void (Assembler::*Int4ArithFn)(const ZRegister& zd,
8339                                          const ZRegister& za,
8340                                          const ZRegister& zn,
8341                                          const ZRegister& zm);
8342 
8343   typedef void (Assembler::*IntArithImmFn)(const ZRegister& zd,
8344                                            const ZRegister& zn,
8345                                            int imm);
8346 
8347   typedef void (Assembler::*ZZZImmFn)(const ZRegister& zd,
8348                                       const ZRegister& zn,
8349                                       const ZRegister& zm,
8350                                       int imm);
8351 
8352   typedef void (MacroAssembler::*SVEArithPredicatedFn)(const ZRegister& zd,
8353                                                        const PRegisterM& pg,
8354                                                        const ZRegister& zn,
8355                                                        const ZRegister& zm);
8356 
8357   void IntWideImmHelper(IntArithImmFn imm_fn,
8358                         SVEArithPredicatedFn reg_fn,
8359                         const ZRegister& zd,
8360                         const ZRegister& zn,
8361                         IntegerOperand imm,
8362                         bool is_signed_imm);
8363 
8364   enum AddSubHelperOption { kAddImmediate, kSubImmediate };
8365 
8366   void AddSubHelper(AddSubHelperOption option,
8367                     const ZRegister& zd,
8368                     const ZRegister& zn,
8369                     IntegerOperand imm);
8370 
8371   // Try to emit an add- or sub-like instruction (imm_fn) with `imm`, or the
8372   // corresponding sub- or add-like instruction (n_imm_fn) with a negated `imm`.
8373   // A `movprfx` is automatically generated if one is required. If successful,
8374   // return true. Otherwise, return false.
8375   //
8376   // This helper uses two's complement equivalences, for example treating 0xffff
8377   // as -1 for H-sized lanes.
8378   bool TrySingleAddSub(AddSubHelperOption option,
8379                        const ZRegister& zd,
8380                        const ZRegister& zn,
8381                        IntegerOperand imm);
8382 
8383   void AbsoluteDifferenceAccumulate(Int3ArithFn fn,
8384                                     const ZRegister& zd,
8385                                     const ZRegister& za,
8386                                     const ZRegister& zn,
8387                                     const ZRegister& zm);
8388 
8389   void FourRegDestructiveHelper(Int3ArithFn fn,
8390                                 const ZRegister& zd,
8391                                 const ZRegister& za,
8392                                 const ZRegister& zn,
8393                                 const ZRegister& zm);
8394 
8395   void FourRegDestructiveHelper(Int4ArithFn fn,
8396                                 const ZRegister& zd,
8397                                 const ZRegister& za,
8398                                 const ZRegister& zn,
8399                                 const ZRegister& zm);
8400 
8401   void SVEDotIndexHelper(ZZZImmFn fn,
8402                          const ZRegister& zd,
8403                          const ZRegister& za,
8404                          const ZRegister& zn,
8405                          const ZRegister& zm,
8406                          int index);
8407 
8408   // For noncommutative arithmetic operations.
8409   void NoncommutativeArithmeticHelper(const ZRegister& zd,
8410                                       const PRegisterM& pg,
8411                                       const ZRegister& zn,
8412                                       const ZRegister& zm,
8413                                       SVEArithPredicatedFn fn,
8414                                       SVEArithPredicatedFn rev_fn);
8415 
8416   void FPCommutativeArithmeticHelper(const ZRegister& zd,
8417                                      const PRegisterM& pg,
8418                                      const ZRegister& zn,
8419                                      const ZRegister& zm,
8420                                      SVEArithPredicatedFn fn,
8421                                      FPMacroNaNPropagationOption nan_option);
8422 
8423   // Floating-point fused multiply-add vectors (predicated), writing addend.
8424   typedef void (Assembler::*SVEMulAddPredicatedZdaFn)(const ZRegister& zda,
8425                                                       const PRegisterM& pg,
8426                                                       const ZRegister& zn,
8427                                                       const ZRegister& zm);
8428 
8429   // Floating-point fused multiply-add vectors (predicated), writing
8430   // multiplicand.
8431   typedef void (Assembler::*SVEMulAddPredicatedZdnFn)(const ZRegister& zdn,
8432                                                       const PRegisterM& pg,
8433                                                       const ZRegister& zn,
8434                                                       const ZRegister& zm);
8435 
8436   void FPMulAddHelper(const ZRegister& zd,
8437                       const PRegisterM& pg,
8438                       const ZRegister& za,
8439                       const ZRegister& zn,
8440                       const ZRegister& zm,
8441                       SVEMulAddPredicatedZdaFn fn_zda,
8442                       SVEMulAddPredicatedZdnFn fn_zdn,
8443                       FPMacroNaNPropagationOption nan_option);
8444 
8445   typedef void (Assembler::*SVEMulAddIndexFn)(const ZRegister& zda,
8446                                               const ZRegister& zn,
8447                                               const ZRegister& zm,
8448                                               int index);
8449 
8450   void FourRegOneImmDestructiveHelper(ZZZImmFn fn,
8451                                       const ZRegister& zd,
8452                                       const ZRegister& za,
8453                                       const ZRegister& zn,
8454                                       const ZRegister& zm,
8455                                       int imm);
8456 
8457   void ShiftRightAccumulate(IntArithImmFn fn,
8458                             const ZRegister& zd,
8459                             const ZRegister& za,
8460                             const ZRegister& zn,
8461                             int imm);
8462 
8463   void ComplexAddition(ZZZImmFn fn,
8464                        const ZRegister& zd,
8465                        const ZRegister& zn,
8466                        const ZRegister& zm,
8467                        int rot);
8468 
8469   // Tell whether any of the macro instruction can be used. When false the
8470   // MacroAssembler will assert if a method which can emit a variable number
8471   // of instructions is called.
8472   bool allow_macro_instructions_;
8473 
8474   // Indicates whether we should generate simulator or native code.
8475   bool generate_simulator_code_;
8476 
8477   // The register to use as a stack pointer for stack operations.
8478   Register sp_;
8479 
8480   // Scratch registers available for use by the MacroAssembler.
8481   CPURegList tmp_list_;
8482   CPURegList v_tmp_list_;
8483   CPURegList p_tmp_list_;
8484 
8485   UseScratchRegisterScope* current_scratch_scope_;
8486 
8487   LiteralPool literal_pool_;
8488   VeneerPool veneer_pool_;
8489 
8490   ptrdiff_t checkpoint_;
8491   ptrdiff_t recommended_checkpoint_;
8492 
8493   FPMacroNaNPropagationOption fp_nan_propagation_;
8494 
8495   friend class Pool;
8496   friend class LiteralPool;
8497 };
8498 
8499 
GetOtherPoolsMaxSize()8500 inline size_t VeneerPool::GetOtherPoolsMaxSize() const {
8501   return masm_->GetLiteralPoolMaxSize();
8502 }
8503 
8504 
GetOtherPoolsMaxSize()8505 inline size_t LiteralPool::GetOtherPoolsMaxSize() const {
8506   return masm_->GetVeneerPoolMaxSize();
8507 }
8508 
8509 
SetNextRecommendedCheckpoint(ptrdiff_t offset)8510 inline void LiteralPool::SetNextRecommendedCheckpoint(ptrdiff_t offset) {
8511   masm_->recommended_checkpoint_ =
8512       std::min(masm_->recommended_checkpoint_, offset);
8513   recommended_checkpoint_ = offset;
8514 }
8515 
8516 class InstructionAccurateScope : public ExactAssemblyScope {
8517  public:
8518   VIXL_DEPRECATED("ExactAssemblyScope",
8519                   InstructionAccurateScope(MacroAssembler* masm,
8520                                            int64_t count,
8521                                            SizePolicy size_policy = kExactSize))
ExactAssemblyScope(masm,count * kInstructionSize,size_policy)8522       : ExactAssemblyScope(masm, count * kInstructionSize, size_policy) {}
8523 };
8524 
8525 class BlockLiteralPoolScope {
8526  public:
BlockLiteralPoolScope(MacroAssembler * masm)8527   explicit BlockLiteralPoolScope(MacroAssembler* masm) : masm_(masm) {
8528     masm_->BlockLiteralPool();
8529   }
8530 
~BlockLiteralPoolScope()8531   ~BlockLiteralPoolScope() { masm_->ReleaseLiteralPool(); }
8532 
8533  private:
8534   MacroAssembler* masm_;
8535 };
8536 
8537 
8538 class BlockVeneerPoolScope {
8539  public:
BlockVeneerPoolScope(MacroAssembler * masm)8540   explicit BlockVeneerPoolScope(MacroAssembler* masm) : masm_(masm) {
8541     masm_->BlockVeneerPool();
8542   }
8543 
~BlockVeneerPoolScope()8544   ~BlockVeneerPoolScope() { masm_->ReleaseVeneerPool(); }
8545 
8546  private:
8547   MacroAssembler* masm_;
8548 };
8549 
8550 
8551 class BlockPoolsScope {
8552  public:
BlockPoolsScope(MacroAssembler * masm)8553   explicit BlockPoolsScope(MacroAssembler* masm) : masm_(masm) {
8554     masm_->BlockPools();
8555   }
8556 
~BlockPoolsScope()8557   ~BlockPoolsScope() { masm_->ReleasePools(); }
8558 
8559  private:
8560   MacroAssembler* masm_;
8561 };
8562 
MovprfxHelperScope(MacroAssembler * masm,const ZRegister & dst,const ZRegister & src)8563 MovprfxHelperScope::MovprfxHelperScope(MacroAssembler* masm,
8564                                        const ZRegister& dst,
8565                                        const ZRegister& src)
8566     : ExactAssemblyScope(masm,
8567                          ShouldGenerateMovprfx(dst, src)
8568                              ? (2 * kInstructionSize)
8569                              : kInstructionSize) {
8570   if (ShouldGenerateMovprfx(dst, src)) {
8571     masm->movprfx(dst, src);
8572   }
8573 }
8574 
MovprfxHelperScope(MacroAssembler * masm,const ZRegister & dst,const PRegister & pg,const ZRegister & src)8575 MovprfxHelperScope::MovprfxHelperScope(MacroAssembler* masm,
8576                                        const ZRegister& dst,
8577                                        const PRegister& pg,
8578                                        const ZRegister& src)
8579     : ExactAssemblyScope(masm,
8580                          ShouldGenerateMovprfx(dst, pg, src)
8581                              ? (2 * kInstructionSize)
8582                              : kInstructionSize) {
8583   if (ShouldGenerateMovprfx(dst, pg, src)) {
8584     masm->movprfx(dst, pg, src);
8585   }
8586 }
8587 
8588 // This scope utility allows scratch registers to be managed safely. The
8589 // MacroAssembler's GetScratch*RegisterList() are used as a pool of scratch
8590 // registers. These registers can be allocated on demand, and will be returned
8591 // at the end of the scope.
8592 //
8593 // When the scope ends, the MacroAssembler's lists will be restored to their
8594 // original state, even if the lists were modified by some other means.
8595 class UseScratchRegisterScope {
8596  public:
8597   // This constructor implicitly calls `Open` to initialise the scope (`masm`
8598   // must not be `NULL`), so it is ready to use immediately after it has been
8599   // constructed.
UseScratchRegisterScope(MacroAssembler * masm)8600   explicit UseScratchRegisterScope(MacroAssembler* masm)
8601       : masm_(NULL),
8602         parent_(NULL),
8603         old_available_(0),
8604         old_available_v_(0),
8605         old_available_p_(0) {
8606     Open(masm);
8607   }
8608   // This constructor does not implicitly initialise the scope. Instead, the
8609   // user is required to explicitly call the `Open` function before using the
8610   // scope.
UseScratchRegisterScope()8611   UseScratchRegisterScope()
8612       : masm_(NULL),
8613         parent_(NULL),
8614         old_available_(0),
8615         old_available_v_(0),
8616         old_available_p_(0) {}
8617 
8618   // This function performs the actual initialisation work.
8619   void Open(MacroAssembler* masm);
8620 
8621   // The destructor always implicitly calls the `Close` function.
~UseScratchRegisterScope()8622   ~UseScratchRegisterScope() { Close(); }
8623 
8624   // This function performs the cleaning-up work. It must succeed even if the
8625   // scope has not been opened. It is safe to call multiple times.
8626   void Close();
8627 
8628 
8629   bool IsAvailable(const CPURegister& reg) const;
8630 
8631   // Take a register from the appropriate temps list. It will be returned
8632   // automatically when the scope ends.
AcquireW()8633   Register AcquireW() {
8634     return AcquireFrom(masm_->GetScratchRegisterList()).W();
8635   }
AcquireX()8636   Register AcquireX() {
8637     return AcquireFrom(masm_->GetScratchRegisterList()).X();
8638   }
AcquireH()8639   VRegister AcquireH() {
8640     return AcquireFrom(masm_->GetScratchVRegisterList()).H();
8641   }
AcquireS()8642   VRegister AcquireS() {
8643     return AcquireFrom(masm_->GetScratchVRegisterList()).S();
8644   }
AcquireD()8645   VRegister AcquireD() {
8646     return AcquireFrom(masm_->GetScratchVRegisterList()).D();
8647   }
AcquireZ()8648   ZRegister AcquireZ() {
8649     return AcquireFrom(masm_->GetScratchVRegisterList()).Z();
8650   }
AcquireP()8651   PRegister AcquireP() {
8652     // Prefer to allocate p8-p15 if we can, to leave p0-p7 available for use as
8653     // governing predicates.
8654     CPURegList* available = masm_->GetScratchPRegisterList();
8655     RegList preferred = ~kGoverningPRegisterMask;
8656     if ((available->GetList() & preferred) != 0) {
8657       return AcquireFrom(available, preferred).P();
8658     }
8659     return AcquireFrom(available).P();
8660   }
8661   // Acquire a P register suitable for use as a governing predicate in
8662   // instructions which only accept p0-p7 for that purpose.
AcquireGoverningP()8663   PRegister AcquireGoverningP() {
8664     CPURegList* available = masm_->GetScratchPRegisterList();
8665     return AcquireFrom(available, kGoverningPRegisterMask).P();
8666   }
8667 
8668   // TODO: extend to other scratch register lists.
TryAcquire(const Register & required_reg)8669   bool TryAcquire(const Register& required_reg) {
8670     CPURegList* list = masm_->GetScratchRegisterList();
8671     if (list->IncludesAliasOf(required_reg)) {
8672       list->Remove(required_reg);
8673       return true;
8674     }
8675     return false;
8676   }
8677 
8678   Register AcquireRegisterOfSize(int size_in_bits);
AcquireSameSizeAs(const Register & reg)8679   Register AcquireSameSizeAs(const Register& reg) {
8680     return AcquireRegisterOfSize(reg.GetSizeInBits());
8681   }
8682   VRegister AcquireVRegisterOfSize(int size_in_bits);
AcquireSameSizeAs(const VRegister & reg)8683   VRegister AcquireSameSizeAs(const VRegister& reg) {
8684     return AcquireVRegisterOfSize(reg.GetSizeInBits());
8685   }
AcquireCPURegisterOfSize(int size_in_bits)8686   CPURegister AcquireCPURegisterOfSize(int size_in_bits) {
8687     return masm_->GetScratchRegisterList()->IsEmpty()
8688                ? CPURegister(AcquireVRegisterOfSize(size_in_bits))
8689                : CPURegister(AcquireRegisterOfSize(size_in_bits));
8690   }
8691 
8692   // Acquire a register big enough to represent one lane of `vector`.
AcquireRegisterToHoldLane(const CPURegister & vector)8693   Register AcquireRegisterToHoldLane(const CPURegister& vector) {
8694     VIXL_ASSERT(vector.GetLaneSizeInBits() <= kXRegSize);
8695     return (vector.GetLaneSizeInBits() > kWRegSize) ? AcquireX() : AcquireW();
8696   }
8697 
8698 
8699   // Explicitly release an acquired (or excluded) register, putting it back in
8700   // the appropriate temps list.
8701   void Release(const CPURegister& reg);
8702 
8703 
8704   // Make the specified registers available as scratch registers for the
8705   // duration of this scope.
8706   void Include(const CPURegList& list);
8707   void Include(const Register& reg1,
8708                const Register& reg2 = NoReg,
8709                const Register& reg3 = NoReg,
8710                const Register& reg4 = NoReg);
8711   void Include(const VRegister& reg1,
8712                const VRegister& reg2 = NoVReg,
8713                const VRegister& reg3 = NoVReg,
8714                const VRegister& reg4 = NoVReg);
8715   void Include(const CPURegister& reg1,
8716                const CPURegister& reg2 = NoCPUReg,
8717                const CPURegister& reg3 = NoCPUReg,
8718                const CPURegister& reg4 = NoCPUReg);
8719 
8720 
8721   // Make sure that the specified registers are not available in this scope.
8722   // This can be used to prevent helper functions from using sensitive
8723   // registers, for example.
8724   void Exclude(const CPURegList& list);
8725   void Exclude(const Register& reg1,
8726                const Register& reg2 = NoReg,
8727                const Register& reg3 = NoReg,
8728                const Register& reg4 = NoReg);
8729   void Exclude(const VRegister& reg1,
8730                const VRegister& reg2 = NoVReg,
8731                const VRegister& reg3 = NoVReg,
8732                const VRegister& reg4 = NoVReg);
8733   void Exclude(const CPURegister& reg1,
8734                const CPURegister& reg2 = NoCPUReg,
8735                const CPURegister& reg3 = NoCPUReg,
8736                const CPURegister& reg4 = NoCPUReg);
8737 
8738   // Convenience for excluding registers that are part of Operands. This is
8739   // useful for sequences like this:
8740   //
8741   //    // Use 'rd' as a scratch, but only if it's not aliased by an input.
8742   //    temps.Include(rd);
8743   //    temps.Exclude(rn);
8744   //    temps.Exclude(operand);
8745   //
8746   // Otherwise, a conditional check is needed on the last 'Exclude'.
Exclude(const Operand & operand)8747   void Exclude(const Operand& operand) {
8748     if (operand.IsShiftedRegister() || operand.IsExtendedRegister()) {
8749       Exclude(operand.GetRegister());
8750     } else {
8751       VIXL_ASSERT(operand.IsImmediate());
8752     }
8753   }
8754 
8755   // Prevent any scratch registers from being used in this scope.
8756   void ExcludeAll();
8757 
8758  private:
8759   static CPURegister AcquireFrom(CPURegList* available,
8760                                  RegList mask = ~static_cast<RegList>(0));
8761 
8762   static void ReleaseByCode(CPURegList* available, int code);
8763   static void ReleaseByRegList(CPURegList* available, RegList regs);
8764   static void IncludeByRegList(CPURegList* available, RegList exclude);
8765   static void ExcludeByRegList(CPURegList* available, RegList exclude);
8766 
8767   CPURegList* GetAvailableListFor(CPURegister::RegisterBank bank);
8768 
8769   static const RegList kGoverningPRegisterMask =
8770       (static_cast<RegList>(1) << kNumberOfGoverningPRegisters) - 1;
8771 
8772   // The MacroAssembler maintains a list of available scratch registers, and
8773   // also keeps track of the most recently-opened scope so that on destruction
8774   // we can check that scopes do not outlive their parents.
8775   MacroAssembler* masm_;
8776   UseScratchRegisterScope* parent_;
8777 
8778   // The state of the available lists at the start of this scope.
8779   RegList old_available_;    // kRegister
8780   RegList old_available_v_;  // kVRegister / kZRegister
8781   RegList old_available_p_;  // kPRegister
8782 
8783   // Disallow copy constructor and operator=.
UseScratchRegisterScope(const UseScratchRegisterScope &)8784   VIXL_NO_RETURN_IN_DEBUG_MODE UseScratchRegisterScope(
8785       const UseScratchRegisterScope&) {
8786     VIXL_UNREACHABLE();
8787   }
8788   VIXL_NO_RETURN_IN_DEBUG_MODE void operator=(const UseScratchRegisterScope&) {
8789     VIXL_UNREACHABLE();
8790   }
8791 };
8792 
8793 
8794 // Like CPUFeaturesScope, but also generate Simulation pseudo-instructions to
8795 // control a Simulator's CPUFeatures dynamically.
8796 //
8797 // One major difference from CPUFeaturesScope is that this scope cannot offer
8798 // a writable "CPUFeatures* GetCPUFeatures()", because every write to the
8799 // features needs a corresponding macro instruction.
8800 class SimulationCPUFeaturesScope {
8801  public:
8802   template <typename... T>
SimulationCPUFeaturesScope(MacroAssembler * masm,T...features)8803   explicit SimulationCPUFeaturesScope(MacroAssembler* masm, T... features)
8804       : masm_(masm), cpu_features_scope_(masm, features...) {
8805     masm_->SaveSimulatorCPUFeatures();
8806     masm_->EnableSimulatorCPUFeatures(CPUFeatures(features...));
8807   }
8808 
~SimulationCPUFeaturesScope()8809   ~SimulationCPUFeaturesScope() { masm_->RestoreSimulatorCPUFeatures(); }
8810 
GetCPUFeatures()8811   const CPUFeatures* GetCPUFeatures() const {
8812     return cpu_features_scope_.GetCPUFeatures();
8813   }
8814 
SetCPUFeatures(const CPUFeatures & cpu_features)8815   void SetCPUFeatures(const CPUFeatures& cpu_features) {
8816     cpu_features_scope_.SetCPUFeatures(cpu_features);
8817     masm_->SetSimulatorCPUFeatures(cpu_features);
8818   }
8819 
8820  private:
8821   MacroAssembler* masm_;
8822   CPUFeaturesScope cpu_features_scope_;
8823 };
8824 
8825 
8826 // Variadic templating is only available from C++11.
8827 #ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT
8828 
8829 // `R` stands for 'return type', and `P` for 'parameter types'.
8830 template <typename R, typename... P>
CallRuntimeHelper(R (* function)(P...),RuntimeCallType call_type)8831 void MacroAssembler::CallRuntimeHelper(R (*function)(P...),
8832                                        RuntimeCallType call_type) {
8833   if (generate_simulator_code_) {
8834 #ifdef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
8835     uintptr_t runtime_call_wrapper_address = reinterpret_cast<uintptr_t>(
8836         &(Simulator::RuntimeCallStructHelper<R, P...>::Wrapper));
8837     uintptr_t function_address = reinterpret_cast<uintptr_t>(function);
8838 
8839     EmissionCheckScope guard(this,
8840                              kRuntimeCallLength,
8841                              CodeBufferCheckScope::kExactSize);
8842     Label start;
8843     bind(&start);
8844     {
8845       ExactAssemblyScope scope(this, kInstructionSize);
8846       hlt(kRuntimeCallOpcode);
8847     }
8848     VIXL_ASSERT(GetSizeOfCodeGeneratedSince(&start) ==
8849                 kRuntimeCallWrapperOffset);
8850     dc(runtime_call_wrapper_address);
8851     VIXL_ASSERT(GetSizeOfCodeGeneratedSince(&start) ==
8852                 kRuntimeCallFunctionOffset);
8853     dc(function_address);
8854     VIXL_ASSERT(GetSizeOfCodeGeneratedSince(&start) == kRuntimeCallTypeOffset);
8855     dc32(call_type);
8856     VIXL_ASSERT(GetSizeOfCodeGeneratedSince(&start) == kRuntimeCallLength);
8857 #else
8858     VIXL_UNREACHABLE();
8859 #endif  // #ifdef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
8860   } else {
8861     UseScratchRegisterScope temps(this);
8862     Register temp = temps.AcquireX();
8863     Mov(temp, reinterpret_cast<uint64_t>(function));
8864     if (call_type == kTailCallRuntime) {
8865       Br(temp);
8866     } else {
8867       VIXL_ASSERT(call_type == kCallRuntime);
8868       Blr(temp);
8869     }
8870   }
8871 }
8872 
8873 #endif  // #ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT
8874 
8875 }  // namespace aarch64
8876 
8877 // Required InvalSet template specialisations.
8878 // TODO: These template specialisations should not live in this file.  Move
8879 // VeneerPool out of the aarch64 namespace in order to share its implementation
8880 // later.
8881 template <>
8882 inline ptrdiff_t InvalSet<aarch64::VeneerPool::BranchInfo,
8883                           aarch64::VeneerPool::kNPreallocatedInfos,
8884                           ptrdiff_t,
8885                           aarch64::VeneerPool::kInvalidOffset,
8886                           aarch64::VeneerPool::kReclaimFrom,
8887                           aarch64::VeneerPool::kReclaimFactor>::
GetKey(const aarch64::VeneerPool::BranchInfo & branch_info)8888     GetKey(const aarch64::VeneerPool::BranchInfo& branch_info) {
8889   return branch_info.first_unreacheable_pc_;
8890 }
8891 template <>
8892 inline void InvalSet<aarch64::VeneerPool::BranchInfo,
8893                      aarch64::VeneerPool::kNPreallocatedInfos,
8894                      ptrdiff_t,
8895                      aarch64::VeneerPool::kInvalidOffset,
8896                      aarch64::VeneerPool::kReclaimFrom,
8897                      aarch64::VeneerPool::kReclaimFactor>::
SetKey(aarch64::VeneerPool::BranchInfo * branch_info,ptrdiff_t key)8898     SetKey(aarch64::VeneerPool::BranchInfo* branch_info, ptrdiff_t key) {
8899   branch_info->first_unreacheable_pc_ = key;
8900 }
8901 
8902 }  // namespace vixl
8903 
8904 #endif  // VIXL_AARCH64_MACRO_ASSEMBLER_AARCH64_H_
8905