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