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