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#include "debugger-aarch64.h"
39#include "instrument-aarch64.h"
40// Required in order to generate debugging instructions for the simulator. This
41// is needed regardless of whether the simulator is included or not, since
42// generating simulator specific instructions is controlled at runtime.
43#include "simulator-constants-aarch64.h"
44
45
46#define LS_MACRO_LIST(V)                                     \
47  V(Ldrb, Register&, rt, LDRB_w)                             \
48  V(Strb, Register&, rt, STRB_w)                             \
49  V(Ldrsb, Register&, rt, rt.Is64Bits() ? LDRSB_x : LDRSB_w) \
50  V(Ldrh, Register&, rt, LDRH_w)                             \
51  V(Strh, Register&, rt, STRH_w)                             \
52  V(Ldrsh, Register&, rt, rt.Is64Bits() ? LDRSH_x : LDRSH_w) \
53  V(Ldr, CPURegister&, rt, LoadOpFor(rt))                    \
54  V(Str, CPURegister&, rt, StoreOpFor(rt))                   \
55  V(Ldrsw, Register&, rt, LDRSW_x)
56
57
58#define LSPAIR_MACRO_LIST(V)                             \
59  V(Ldp, CPURegister&, rt, rt2, LoadPairOpFor(rt, rt2))  \
60  V(Stp, CPURegister&, rt, rt2, StorePairOpFor(rt, rt2)) \
61  V(Ldpsw, CPURegister&, rt, rt2, LDPSW_x)
62
63namespace vixl {
64namespace aarch64 {
65
66// Forward declaration
67class MacroAssembler;
68class UseScratchRegisterScope;
69
70class Pool {
71 public:
72  explicit Pool(MacroAssembler* masm)
73      : checkpoint_(kNoCheckpointRequired), masm_(masm) {
74    Reset();
75  }
76
77  void Reset() {
78    checkpoint_ = kNoCheckpointRequired;
79    monitor_ = 0;
80  }
81
82  void Block() { monitor_++; }
83  void Release();
84  bool IsBlocked() const { return monitor_ != 0; }
85
86  static const ptrdiff_t kNoCheckpointRequired = PTRDIFF_MAX;
87
88  void SetNextCheckpoint(ptrdiff_t checkpoint);
89  ptrdiff_t GetCheckpoint() const { return checkpoint_; }
90  VIXL_DEPRECATED("GetCheckpoint", ptrdiff_t checkpoint() const) {
91    return GetCheckpoint();
92  }
93
94  enum EmitOption { kBranchRequired, kNoBranchRequired };
95
96 protected:
97  // Next buffer offset at which a check is required for this pool.
98  ptrdiff_t checkpoint_;
99  // Indicates whether the emission of this pool is blocked.
100  int monitor_;
101  // The MacroAssembler using this pool.
102  MacroAssembler* masm_;
103};
104
105
106class LiteralPool : public Pool {
107 public:
108  explicit LiteralPool(MacroAssembler* masm);
109  ~LiteralPool();
110  void Reset();
111
112  void AddEntry(RawLiteral* literal);
113  bool IsEmpty() const { return entries_.empty(); }
114  size_t GetSize() const;
115  VIXL_DEPRECATED("GetSize", size_t Size() const) { return GetSize(); }
116
117  size_t GetMaxSize() const;
118  VIXL_DEPRECATED("GetMaxSize", size_t MaxSize() const) { return GetMaxSize(); }
119
120  size_t GetOtherPoolsMaxSize() const;
121  VIXL_DEPRECATED("GetOtherPoolsMaxSize", size_t OtherPoolsMaxSize() const) {
122    return GetOtherPoolsMaxSize();
123  }
124
125  void CheckEmitFor(size_t amount, EmitOption option = kBranchRequired);
126  // Check whether we need to emit the literal pool in order to be able to
127  // safely emit a branch with a given range.
128  void CheckEmitForBranch(size_t range);
129  void Emit(EmitOption option = kNoBranchRequired);
130
131  void SetNextRecommendedCheckpoint(ptrdiff_t offset);
132  ptrdiff_t GetNextRecommendedCheckpoint();
133  VIXL_DEPRECATED("GetNextRecommendedCheckpoint",
134                  ptrdiff_t NextRecommendedCheckpoint()) {
135    return GetNextRecommendedCheckpoint();
136  }
137
138  void UpdateFirstUse(ptrdiff_t use_position);
139
140  void DeleteOnDestruction(RawLiteral* literal) {
141    deleted_on_destruction_.push_back(literal);
142  }
143
144  // Recommended not exact since the pool can be blocked for short periods.
145  static const ptrdiff_t kRecommendedLiteralPoolRange = 128 * KBytes;
146
147 private:
148  std::vector<RawLiteral*> entries_;
149  size_t size_;
150  ptrdiff_t first_use_;
151  // The parent class `Pool` provides a `checkpoint_`, which is the buffer
152  // offset before which a check *must* occur. This recommended checkpoint
153  // indicates when we would like to start emitting the constant pool. The
154  // MacroAssembler can, but does not have to, check the buffer when the
155  // checkpoint is reached.
156  ptrdiff_t recommended_checkpoint_;
157
158  std::vector<RawLiteral*> deleted_on_destruction_;
159};
160
161
162inline size_t LiteralPool::GetSize() const {
163  // Account for the pool header.
164  return size_ + kInstructionSize;
165}
166
167
168inline size_t LiteralPool::GetMaxSize() const {
169  // Account for the potential branch over the pool.
170  return GetSize() + kInstructionSize;
171}
172
173
174inline ptrdiff_t LiteralPool::GetNextRecommendedCheckpoint() {
175  return first_use_ + kRecommendedLiteralPoolRange;
176}
177
178
179class VeneerPool : public Pool {
180 public:
181  explicit VeneerPool(MacroAssembler* masm) : Pool(masm) {}
182
183  void Reset();
184
185  void Block() { monitor_++; }
186  void Release();
187  bool IsBlocked() const { return monitor_ != 0; }
188  bool IsEmpty() const { return unresolved_branches_.IsEmpty(); }
189
190  class BranchInfo {
191   public:
192    BranchInfo()
193        : first_unreacheable_pc_(0),
194          pc_offset_(0),
195          label_(NULL),
196          branch_type_(UnknownBranchType) {}
197    BranchInfo(ptrdiff_t offset, Label* label, ImmBranchType branch_type)
198        : pc_offset_(offset), label_(label), branch_type_(branch_type) {
199      first_unreacheable_pc_ =
200          pc_offset_ + Instruction::GetImmBranchForwardRange(branch_type_);
201    }
202
203    static bool IsValidComparison(const BranchInfo& branch_1,
204                                  const BranchInfo& branch_2) {
205      // BranchInfo are always compared against against other objects with
206      // the same branch type.
207      if (branch_1.branch_type_ != branch_2.branch_type_) {
208        return false;
209      }
210      // Since we should never have two branch infos with the same offsets, it
211      // first looks like we should check that offsets are different. However
212      // the operators may also be used to *search* for a branch info in the
213      // set.
214      bool same_offsets = (branch_1.pc_offset_ == branch_2.pc_offset_);
215      return (!same_offsets || ((branch_1.label_ == branch_2.label_) &&
216                                (branch_1.first_unreacheable_pc_ ==
217                                 branch_2.first_unreacheable_pc_)));
218    }
219
220    // We must provide comparison operators to work with InvalSet.
221    bool operator==(const BranchInfo& other) const {
222      VIXL_ASSERT(IsValidComparison(*this, other));
223      return pc_offset_ == other.pc_offset_;
224    }
225    bool operator<(const BranchInfo& other) const {
226      VIXL_ASSERT(IsValidComparison(*this, other));
227      return pc_offset_ < other.pc_offset_;
228    }
229    bool operator<=(const BranchInfo& other) const {
230      VIXL_ASSERT(IsValidComparison(*this, other));
231      return pc_offset_ <= other.pc_offset_;
232    }
233    bool operator>(const BranchInfo& other) const {
234      VIXL_ASSERT(IsValidComparison(*this, other));
235      return pc_offset_ > other.pc_offset_;
236    }
237
238    // First instruction position that is not reachable by the branch using a
239    // positive branch offset.
240    ptrdiff_t first_unreacheable_pc_;
241    // Offset of the branch in the code generation buffer.
242    ptrdiff_t pc_offset_;
243    // The label branched to.
244    Label* label_;
245    ImmBranchType branch_type_;
246  };
247
248  bool BranchTypeUsesVeneers(ImmBranchType type) {
249    return (type != UnknownBranchType) && (type != UncondBranchType);
250  }
251
252  void RegisterUnresolvedBranch(ptrdiff_t branch_pos,
253                                Label* label,
254                                ImmBranchType branch_type);
255  void DeleteUnresolvedBranchInfoForLabel(Label* label);
256
257  bool ShouldEmitVeneer(int64_t first_unreacheable_pc, size_t amount);
258  bool ShouldEmitVeneers(size_t amount) {
259    return ShouldEmitVeneer(unresolved_branches_.GetFirstLimit(), amount);
260  }
261
262  void CheckEmitFor(size_t amount, EmitOption option = kBranchRequired);
263  void Emit(EmitOption option, size_t margin);
264
265  // The code size generated for a veneer. Currently one branch instruction.
266  // This is for code size checking purposes, and can be extended in the future
267  // for example if we decide to add nops between the veneers.
268  static const int kVeneerCodeSize = 1 * kInstructionSize;
269  // The maximum size of code other than veneers that can be generated when
270  // emitting a veneer pool. Currently there can be an additional branch to jump
271  // over the pool.
272  static const int kPoolNonVeneerCodeSize = 1 * kInstructionSize;
273
274  void UpdateNextCheckPoint() { SetNextCheckpoint(GetNextCheckPoint()); }
275
276  int GetNumberOfPotentialVeneers() const {
277    return static_cast<int>(unresolved_branches_.GetSize());
278  }
279  VIXL_DEPRECATED("GetNumberOfPotentialVeneers",
280                  int NumberOfPotentialVeneers() const) {
281    return GetNumberOfPotentialVeneers();
282  }
283
284  size_t GetMaxSize() const {
285    return kPoolNonVeneerCodeSize +
286           unresolved_branches_.GetSize() * kVeneerCodeSize;
287  }
288  VIXL_DEPRECATED("GetMaxSize", size_t MaxSize() const) { return GetMaxSize(); }
289
290  size_t GetOtherPoolsMaxSize() const;
291  VIXL_DEPRECATED("GetOtherPoolsMaxSize", size_t OtherPoolsMaxSize() const) {
292    return GetOtherPoolsMaxSize();
293  }
294
295  static const int kNPreallocatedInfos = 4;
296  static const ptrdiff_t kInvalidOffset = PTRDIFF_MAX;
297  static const size_t kReclaimFrom = 128;
298  static const size_t kReclaimFactor = 16;
299
300 private:
301  typedef InvalSet<BranchInfo,
302                   kNPreallocatedInfos,
303                   ptrdiff_t,
304                   kInvalidOffset,
305                   kReclaimFrom,
306                   kReclaimFactor>
307      BranchInfoTypedSetBase;
308  typedef InvalSetIterator<BranchInfoTypedSetBase> BranchInfoTypedSetIterBase;
309
310  class BranchInfoTypedSet : public BranchInfoTypedSetBase {
311   public:
312    BranchInfoTypedSet() : BranchInfoTypedSetBase() {}
313
314    ptrdiff_t GetFirstLimit() {
315      if (empty()) {
316        return kInvalidOffset;
317      }
318      return GetMinElementKey();
319    }
320    VIXL_DEPRECATED("GetFirstLimit", ptrdiff_t FirstLimit()) {
321      return GetFirstLimit();
322    }
323  };
324
325  class BranchInfoTypedSetIterator : public BranchInfoTypedSetIterBase {
326   public:
327    BranchInfoTypedSetIterator() : BranchInfoTypedSetIterBase(NULL) {}
328    explicit BranchInfoTypedSetIterator(BranchInfoTypedSet* typed_set)
329        : BranchInfoTypedSetIterBase(typed_set) {}
330
331    // TODO: Remove these and use the STL-like interface instead.
332    using BranchInfoTypedSetIterBase::Advance;
333    using BranchInfoTypedSetIterBase::Current;
334  };
335
336  class BranchInfoSet {
337   public:
338    void insert(BranchInfo branch_info) {
339      ImmBranchType type = branch_info.branch_type_;
340      VIXL_ASSERT(IsValidBranchType(type));
341      typed_set_[BranchIndexFromType(type)].insert(branch_info);
342    }
343
344    void erase(BranchInfo branch_info) {
345      if (IsValidBranchType(branch_info.branch_type_)) {
346        int index =
347            BranchInfoSet::BranchIndexFromType(branch_info.branch_type_);
348        typed_set_[index].erase(branch_info);
349      }
350    }
351
352    size_t GetSize() const {
353      size_t res = 0;
354      for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) {
355        res += typed_set_[i].size();
356      }
357      return res;
358    }
359    VIXL_DEPRECATED("GetSize", size_t size() const) { return GetSize(); }
360
361    bool IsEmpty() const {
362      for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) {
363        if (!typed_set_[i].empty()) {
364          return false;
365        }
366      }
367      return true;
368    }
369    VIXL_DEPRECATED("IsEmpty", bool empty() const) { return IsEmpty(); }
370
371    ptrdiff_t GetFirstLimit() {
372      ptrdiff_t res = kInvalidOffset;
373      for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) {
374        res = std::min(res, typed_set_[i].GetFirstLimit());
375      }
376      return res;
377    }
378    VIXL_DEPRECATED("GetFirstLimit", ptrdiff_t FirstLimit()) {
379      return GetFirstLimit();
380    }
381
382    void Reset() {
383      for (int i = 0; i < kNumberOfTrackedBranchTypes; i++) {
384        typed_set_[i].clear();
385      }
386    }
387
388    static ImmBranchType BranchTypeFromIndex(int index) {
389      switch (index) {
390        case 0:
391          return CondBranchType;
392        case 1:
393          return CompareBranchType;
394        case 2:
395          return TestBranchType;
396        default:
397          VIXL_UNREACHABLE();
398          return UnknownBranchType;
399      }
400    }
401    static int BranchIndexFromType(ImmBranchType branch_type) {
402      switch (branch_type) {
403        case CondBranchType:
404          return 0;
405        case CompareBranchType:
406          return 1;
407        case TestBranchType:
408          return 2;
409        default:
410          VIXL_UNREACHABLE();
411          return 0;
412      }
413    }
414
415    bool IsValidBranchType(ImmBranchType branch_type) {
416      return (branch_type != UnknownBranchType) &&
417             (branch_type != UncondBranchType);
418    }
419
420   private:
421    static const int kNumberOfTrackedBranchTypes = 3;
422    BranchInfoTypedSet typed_set_[kNumberOfTrackedBranchTypes];
423
424    friend class VeneerPool;
425    friend class BranchInfoSetIterator;
426  };
427
428  class BranchInfoSetIterator {
429   public:
430    explicit BranchInfoSetIterator(BranchInfoSet* set) : set_(set) {
431      for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) {
432        new (&sub_iterator_[i])
433            BranchInfoTypedSetIterator(&(set_->typed_set_[i]));
434      }
435    }
436
437    VeneerPool::BranchInfo* Current() {
438      for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) {
439        if (!sub_iterator_[i].Done()) {
440          return sub_iterator_[i].Current();
441        }
442      }
443      VIXL_UNREACHABLE();
444      return NULL;
445    }
446
447    void Advance() {
448      VIXL_ASSERT(!Done());
449      for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) {
450        if (!sub_iterator_[i].Done()) {
451          sub_iterator_[i].Advance();
452          return;
453        }
454      }
455      VIXL_UNREACHABLE();
456    }
457
458    bool Done() const {
459      for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) {
460        if (!sub_iterator_[i].Done()) return false;
461      }
462      return true;
463    }
464
465    void AdvanceToNextType() {
466      VIXL_ASSERT(!Done());
467      for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) {
468        if (!sub_iterator_[i].Done()) {
469          sub_iterator_[i].Finish();
470          return;
471        }
472      }
473      VIXL_UNREACHABLE();
474    }
475
476    void DeleteCurrentAndAdvance() {
477      for (int i = 0; i < BranchInfoSet::kNumberOfTrackedBranchTypes; i++) {
478        if (!sub_iterator_[i].Done()) {
479          sub_iterator_[i].DeleteCurrentAndAdvance();
480          return;
481        }
482      }
483    }
484
485   private:
486    BranchInfoSet* set_;
487    BranchInfoTypedSetIterator
488        sub_iterator_[BranchInfoSet::kNumberOfTrackedBranchTypes];
489  };
490
491  ptrdiff_t GetNextCheckPoint() {
492    if (unresolved_branches_.IsEmpty()) {
493      return kNoCheckpointRequired;
494    } else {
495      return unresolved_branches_.GetFirstLimit();
496    }
497  }
498  VIXL_DEPRECATED("GetNextCheckPoint", ptrdiff_t NextCheckPoint()) {
499    return GetNextCheckPoint();
500  }
501
502  // Information about unresolved (forward) branches.
503  BranchInfoSet unresolved_branches_;
504};
505
506
507// Helper for common Emission checks.
508// The macro-instruction maps to a single instruction.
509class SingleEmissionCheckScope : public EmissionCheckScope {
510 public:
511  explicit SingleEmissionCheckScope(MacroAssemblerInterface* masm)
512      : EmissionCheckScope(masm, kInstructionSize) {}
513};
514
515
516// The macro instruction is a "typical" macro-instruction. Typical macro-
517// instruction only emit a few instructions, a few being defined as 8 here.
518class MacroEmissionCheckScope : public EmissionCheckScope {
519 public:
520  explicit MacroEmissionCheckScope(MacroAssemblerInterface* masm)
521      : EmissionCheckScope(masm, kTypicalMacroInstructionMaxSize) {}
522
523 private:
524  static const size_t kTypicalMacroInstructionMaxSize = 8 * kInstructionSize;
525};
526
527
528enum BranchType {
529  // Copies of architectural conditions.
530  // The associated conditions can be used in place of those, the code will
531  // take care of reinterpreting them with the correct type.
532  integer_eq = eq,
533  integer_ne = ne,
534  integer_hs = hs,
535  integer_lo = lo,
536  integer_mi = mi,
537  integer_pl = pl,
538  integer_vs = vs,
539  integer_vc = vc,
540  integer_hi = hi,
541  integer_ls = ls,
542  integer_ge = ge,
543  integer_lt = lt,
544  integer_gt = gt,
545  integer_le = le,
546  integer_al = al,
547  integer_nv = nv,
548
549  // These two are *different* from the architectural codes al and nv.
550  // 'always' is used to generate unconditional branches.
551  // 'never' is used to not generate a branch (generally as the inverse
552  // branch type of 'always).
553  always,
554  never,
555  // cbz and cbnz
556  reg_zero,
557  reg_not_zero,
558  // tbz and tbnz
559  reg_bit_clear,
560  reg_bit_set,
561
562  // Aliases.
563  kBranchTypeFirstCondition = eq,
564  kBranchTypeLastCondition = nv,
565  kBranchTypeFirstUsingReg = reg_zero,
566  kBranchTypeFirstUsingBit = reg_bit_clear
567};
568
569
570enum DiscardMoveMode { kDontDiscardForSameWReg, kDiscardForSameWReg };
571
572// The macro assembler supports moving automatically pre-shifted immediates for
573// arithmetic and logical instructions, and then applying a post shift in the
574// instruction to undo the modification, in order to reduce the code emitted for
575// an operation. For example:
576//
577//  Add(x0, x0, 0x1f7de) => movz x16, 0xfbef; add x0, x0, x16, lsl #1.
578//
579// This optimisation can be only partially applied when the stack pointer is an
580// operand or destination, so this enumeration is used to control the shift.
581enum PreShiftImmMode {
582  kNoShift,          // Don't pre-shift.
583  kLimitShiftForSP,  // Limit pre-shift for add/sub extend use.
584  kAnyShift          // Allow any pre-shift.
585};
586
587
588class MacroAssembler : public Assembler, public MacroAssemblerInterface {
589 public:
590  explicit MacroAssembler(
591      PositionIndependentCodeOption pic = PositionIndependentCode);
592  MacroAssembler(size_t capacity,
593                 PositionIndependentCodeOption pic = PositionIndependentCode);
594  MacroAssembler(byte* buffer,
595                 size_t capacity,
596                 PositionIndependentCodeOption pic = PositionIndependentCode);
597  ~MacroAssembler();
598
599  enum FinalizeOption {
600    kFallThrough,  // There may be more code to execute after calling Finalize.
601    kUnreachable   // Anything generated after calling Finalize is unreachable.
602  };
603
604  virtual vixl::internal::AssemblerBase* AsAssemblerBase() VIXL_OVERRIDE {
605    return this;
606  }
607
608  // TODO(pools): implement these functions.
609  virtual void EmitPoolHeader() VIXL_OVERRIDE {}
610  virtual void EmitPoolFooter() VIXL_OVERRIDE {}
611  virtual void EmitPaddingBytes(int n) VIXL_OVERRIDE { USE(n); }
612  virtual void EmitNopBytes(int n) VIXL_OVERRIDE { USE(n); }
613
614  // Start generating code from the beginning of the buffer, discarding any code
615  // and data that has already been emitted into the buffer.
616  //
617  // In order to avoid any accidental transfer of state, Reset ASSERTs that the
618  // constant pool is not blocked.
619  void Reset();
620
621  // Finalize a code buffer of generated instructions. This function must be
622  // called before executing or copying code from the buffer. By default,
623  // anything generated after this should not be reachable (the last instruction
624  // generated is an unconditional branch). If you need to generate more code,
625  // then set `option` to kFallThrough.
626  void FinalizeCode(FinalizeOption option = kUnreachable);
627
628
629  // Constant generation helpers.
630  // These functions return the number of instructions required to move the
631  // immediate into the destination register. Also, if the masm pointer is
632  // non-null, it generates the code to do so.
633  // The two features are implemented using one function to avoid duplication of
634  // the logic.
635  // The function can be used to evaluate the cost of synthesizing an
636  // instruction using 'mov immediate' instructions. A user might prefer loading
637  // a constant using the literal pool instead of using multiple 'mov immediate'
638  // instructions.
639  static int MoveImmediateHelper(MacroAssembler* masm,
640                                 const Register& rd,
641                                 uint64_t imm);
642  static bool OneInstrMoveImmediateHelper(MacroAssembler* masm,
643                                          const Register& dst,
644                                          int64_t imm);
645
646
647  // Logical macros.
648  void And(const Register& rd, const Register& rn, const Operand& operand);
649  void Ands(const Register& rd, const Register& rn, const Operand& operand);
650  void Bic(const Register& rd, const Register& rn, const Operand& operand);
651  void Bics(const Register& rd, const Register& rn, const Operand& operand);
652  void Orr(const Register& rd, const Register& rn, const Operand& operand);
653  void Orn(const Register& rd, const Register& rn, const Operand& operand);
654  void Eor(const Register& rd, const Register& rn, const Operand& operand);
655  void Eon(const Register& rd, const Register& rn, const Operand& operand);
656  void Tst(const Register& rn, const Operand& operand);
657  void LogicalMacro(const Register& rd,
658                    const Register& rn,
659                    const Operand& operand,
660                    LogicalOp op);
661
662  // Add and sub macros.
663  void Add(const Register& rd,
664           const Register& rn,
665           const Operand& operand,
666           FlagsUpdate S = LeaveFlags);
667  void Adds(const Register& rd, const Register& rn, const Operand& operand);
668  void Sub(const Register& rd,
669           const Register& rn,
670           const Operand& operand,
671           FlagsUpdate S = LeaveFlags);
672  void Subs(const Register& rd, const Register& rn, const Operand& operand);
673  void Cmn(const Register& rn, const Operand& operand);
674  void Cmp(const Register& rn, const Operand& operand);
675  void Neg(const Register& rd, const Operand& operand);
676  void Negs(const Register& rd, const Operand& operand);
677
678  void AddSubMacro(const Register& rd,
679                   const Register& rn,
680                   const Operand& operand,
681                   FlagsUpdate S,
682                   AddSubOp op);
683
684  // Add/sub with carry macros.
685  void Adc(const Register& rd, const Register& rn, const Operand& operand);
686  void Adcs(const Register& rd, const Register& rn, const Operand& operand);
687  void Sbc(const Register& rd, const Register& rn, const Operand& operand);
688  void Sbcs(const Register& rd, const Register& rn, const Operand& operand);
689  void Ngc(const Register& rd, const Operand& operand);
690  void Ngcs(const Register& rd, const Operand& operand);
691  void AddSubWithCarryMacro(const Register& rd,
692                            const Register& rn,
693                            const Operand& operand,
694                            FlagsUpdate S,
695                            AddSubWithCarryOp op);
696
697  // Move macros.
698  void Mov(const Register& rd, uint64_t imm);
699  void Mov(const Register& rd,
700           const Operand& operand,
701           DiscardMoveMode discard_mode = kDontDiscardForSameWReg);
702  void Mvn(const Register& rd, uint64_t imm) {
703    Mov(rd, (rd.GetSizeInBits() == kXRegSize) ? ~imm : (~imm & kWRegMask));
704  }
705  void Mvn(const Register& rd, const Operand& operand);
706
707  // Try to move an immediate into the destination register in a single
708  // instruction. Returns true for success, and updates the contents of dst.
709  // Returns false, otherwise.
710  bool TryOneInstrMoveImmediate(const Register& dst, int64_t imm);
711
712  // Move an immediate into register dst, and return an Operand object for
713  // use with a subsequent instruction that accepts a shift. The value moved
714  // into dst is not necessarily equal to imm; it may have had a shifting
715  // operation applied to it that will be subsequently undone by the shift
716  // applied in the Operand.
717  Operand MoveImmediateForShiftedOp(const Register& dst,
718                                    int64_t imm,
719                                    PreShiftImmMode mode);
720
721  void Move(const GenericOperand& dst, const GenericOperand& src);
722
723  // Synthesises the address represented by a MemOperand into a register.
724  void ComputeAddress(const Register& dst, const MemOperand& mem_op);
725
726  // Conditional macros.
727  void Ccmp(const Register& rn,
728            const Operand& operand,
729            StatusFlags nzcv,
730            Condition cond);
731  void Ccmn(const Register& rn,
732            const Operand& operand,
733            StatusFlags nzcv,
734            Condition cond);
735  void ConditionalCompareMacro(const Register& rn,
736                               const Operand& operand,
737                               StatusFlags nzcv,
738                               Condition cond,
739                               ConditionalCompareOp op);
740
741  // On return, the boolean values pointed to will indicate whether `left` and
742  // `right` should be synthesised in a temporary register.
743  static void GetCselSynthesisInformation(const Register& rd,
744                                          const Operand& left,
745                                          const Operand& right,
746                                          bool* should_synthesise_left,
747                                          bool* should_synthesise_right) {
748    // Note that the helper does not need to look at the condition.
749    CselHelper(NULL,
750               rd,
751               left,
752               right,
753               eq,
754               should_synthesise_left,
755               should_synthesise_right);
756  }
757
758  void Csel(const Register& rd,
759            const Operand& left,
760            const Operand& right,
761            Condition cond) {
762    CselHelper(this, rd, left, right, cond);
763  }
764
765// Load/store macros.
766#define DECLARE_FUNCTION(FN, REGTYPE, REG, OP) \
767  void FN(const REGTYPE REG, const MemOperand& addr);
768  LS_MACRO_LIST(DECLARE_FUNCTION)
769#undef DECLARE_FUNCTION
770
771  void LoadStoreMacro(const CPURegister& rt,
772                      const MemOperand& addr,
773                      LoadStoreOp op);
774
775#define DECLARE_FUNCTION(FN, REGTYPE, REG, REG2, OP) \
776  void FN(const REGTYPE REG, const REGTYPE REG2, const MemOperand& addr);
777  LSPAIR_MACRO_LIST(DECLARE_FUNCTION)
778#undef DECLARE_FUNCTION
779
780  void LoadStorePairMacro(const CPURegister& rt,
781                          const CPURegister& rt2,
782                          const MemOperand& addr,
783                          LoadStorePairOp op);
784
785  void Prfm(PrefetchOperation op, const MemOperand& addr);
786
787  // Push or pop up to 4 registers of the same width to or from the stack,
788  // using the current stack pointer as set by SetStackPointer.
789  //
790  // If an argument register is 'NoReg', all further arguments are also assumed
791  // to be 'NoReg', and are thus not pushed or popped.
792  //
793  // Arguments are ordered such that "Push(a, b);" is functionally equivalent
794  // to "Push(a); Push(b);".
795  //
796  // It is valid to push the same register more than once, and there is no
797  // restriction on the order in which registers are specified.
798  //
799  // It is not valid to pop into the same register more than once in one
800  // operation, not even into the zero register.
801  //
802  // If the current stack pointer (as set by SetStackPointer) is sp, then it
803  // must be aligned to 16 bytes on entry and the total size of the specified
804  // registers must also be a multiple of 16 bytes.
805  //
806  // Even if the current stack pointer is not the system stack pointer (sp),
807  // Push (and derived methods) will still modify the system stack pointer in
808  // order to comply with ABI rules about accessing memory below the system
809  // stack pointer.
810  //
811  // Other than the registers passed into Pop, the stack pointer and (possibly)
812  // the system stack pointer, these methods do not modify any other registers.
813  void Push(const CPURegister& src0,
814            const CPURegister& src1 = NoReg,
815            const CPURegister& src2 = NoReg,
816            const CPURegister& src3 = NoReg);
817  void Pop(const CPURegister& dst0,
818           const CPURegister& dst1 = NoReg,
819           const CPURegister& dst2 = NoReg,
820           const CPURegister& dst3 = NoReg);
821
822  // Alternative forms of Push and Pop, taking a RegList or CPURegList that
823  // specifies the registers that are to be pushed or popped. Higher-numbered
824  // registers are associated with higher memory addresses (as in the A32 push
825  // and pop instructions).
826  //
827  // (Push|Pop)SizeRegList allow you to specify the register size as a
828  // parameter. Only kXRegSize, kWRegSize, kDRegSize and kSRegSize are
829  // supported.
830  //
831  // Otherwise, (Push|Pop)(CPU|X|W|D|S)RegList is preferred.
832  void PushCPURegList(CPURegList registers);
833  void PopCPURegList(CPURegList registers);
834
835  void PushSizeRegList(
836      RegList registers,
837      unsigned reg_size,
838      CPURegister::RegisterType type = CPURegister::kRegister) {
839    PushCPURegList(CPURegList(type, reg_size, registers));
840  }
841  void PopSizeRegList(RegList registers,
842                      unsigned reg_size,
843                      CPURegister::RegisterType type = CPURegister::kRegister) {
844    PopCPURegList(CPURegList(type, reg_size, registers));
845  }
846  void PushXRegList(RegList regs) { PushSizeRegList(regs, kXRegSize); }
847  void PopXRegList(RegList regs) { PopSizeRegList(regs, kXRegSize); }
848  void PushWRegList(RegList regs) { PushSizeRegList(regs, kWRegSize); }
849  void PopWRegList(RegList regs) { PopSizeRegList(regs, kWRegSize); }
850  void PushDRegList(RegList regs) {
851    PushSizeRegList(regs, kDRegSize, CPURegister::kVRegister);
852  }
853  void PopDRegList(RegList regs) {
854    PopSizeRegList(regs, kDRegSize, CPURegister::kVRegister);
855  }
856  void PushSRegList(RegList regs) {
857    PushSizeRegList(regs, kSRegSize, CPURegister::kVRegister);
858  }
859  void PopSRegList(RegList regs) {
860    PopSizeRegList(regs, kSRegSize, CPURegister::kVRegister);
861  }
862
863  // Push the specified register 'count' times.
864  void PushMultipleTimes(int count, Register src);
865
866  // Poke 'src' onto the stack. The offset is in bytes.
867  //
868  // If the current stack pointer (as set by SetStackPointer) is sp, then sp
869  // must be aligned to 16 bytes.
870  void Poke(const Register& src, const Operand& offset);
871
872  // Peek at a value on the stack, and put it in 'dst'. The offset is in bytes.
873  //
874  // If the current stack pointer (as set by SetStackPointer) is sp, then sp
875  // must be aligned to 16 bytes.
876  void Peek(const Register& dst, const Operand& offset);
877
878  // Alternative forms of Peek and Poke, taking a RegList or CPURegList that
879  // specifies the registers that are to be pushed or popped. Higher-numbered
880  // registers are associated with higher memory addresses.
881  //
882  // (Peek|Poke)SizeRegList allow you to specify the register size as a
883  // parameter. Only kXRegSize, kWRegSize, kDRegSize and kSRegSize are
884  // supported.
885  //
886  // Otherwise, (Peek|Poke)(CPU|X|W|D|S)RegList is preferred.
887  void PeekCPURegList(CPURegList registers, int64_t offset) {
888    LoadCPURegList(registers, MemOperand(StackPointer(), offset));
889  }
890  void PokeCPURegList(CPURegList registers, int64_t offset) {
891    StoreCPURegList(registers, MemOperand(StackPointer(), offset));
892  }
893
894  void PeekSizeRegList(
895      RegList registers,
896      int64_t offset,
897      unsigned reg_size,
898      CPURegister::RegisterType type = CPURegister::kRegister) {
899    PeekCPURegList(CPURegList(type, reg_size, registers), offset);
900  }
901  void PokeSizeRegList(
902      RegList registers,
903      int64_t offset,
904      unsigned reg_size,
905      CPURegister::RegisterType type = CPURegister::kRegister) {
906    PokeCPURegList(CPURegList(type, reg_size, registers), offset);
907  }
908  void PeekXRegList(RegList regs, int64_t offset) {
909    PeekSizeRegList(regs, offset, kXRegSize);
910  }
911  void PokeXRegList(RegList regs, int64_t offset) {
912    PokeSizeRegList(regs, offset, kXRegSize);
913  }
914  void PeekWRegList(RegList regs, int64_t offset) {
915    PeekSizeRegList(regs, offset, kWRegSize);
916  }
917  void PokeWRegList(RegList regs, int64_t offset) {
918    PokeSizeRegList(regs, offset, kWRegSize);
919  }
920  void PeekDRegList(RegList regs, int64_t offset) {
921    PeekSizeRegList(regs, offset, kDRegSize, CPURegister::kVRegister);
922  }
923  void PokeDRegList(RegList regs, int64_t offset) {
924    PokeSizeRegList(regs, offset, kDRegSize, CPURegister::kVRegister);
925  }
926  void PeekSRegList(RegList regs, int64_t offset) {
927    PeekSizeRegList(regs, offset, kSRegSize, CPURegister::kVRegister);
928  }
929  void PokeSRegList(RegList regs, int64_t offset) {
930    PokeSizeRegList(regs, offset, kSRegSize, CPURegister::kVRegister);
931  }
932
933
934  // Claim or drop stack space without actually accessing memory.
935  //
936  // If the current stack pointer (as set by SetStackPointer) is sp, then it
937  // must be aligned to 16 bytes and the size claimed or dropped must be a
938  // multiple of 16 bytes.
939  void Claim(const Operand& size);
940  void Drop(const Operand& size);
941
942  // Preserve the callee-saved registers (as defined by AAPCS64).
943  //
944  // Higher-numbered registers are pushed before lower-numbered registers, and
945  // thus get higher addresses.
946  // Floating-point registers are pushed before general-purpose registers, and
947  // thus get higher addresses.
948  //
949  // This method must not be called unless StackPointer() is sp, and it is
950  // aligned to 16 bytes.
951  void PushCalleeSavedRegisters();
952
953  // Restore the callee-saved registers (as defined by AAPCS64).
954  //
955  // Higher-numbered registers are popped after lower-numbered registers, and
956  // thus come from higher addresses.
957  // Floating-point registers are popped after general-purpose registers, and
958  // thus come from higher addresses.
959  //
960  // This method must not be called unless StackPointer() is sp, and it is
961  // aligned to 16 bytes.
962  void PopCalleeSavedRegisters();
963
964  void LoadCPURegList(CPURegList registers, const MemOperand& src);
965  void StoreCPURegList(CPURegList registers, const MemOperand& dst);
966
967  // Remaining instructions are simple pass-through calls to the assembler.
968  void Adr(const Register& rd, Label* label) {
969    VIXL_ASSERT(allow_macro_instructions_);
970    VIXL_ASSERT(!rd.IsZero());
971    SingleEmissionCheckScope guard(this);
972    adr(rd, label);
973  }
974  void Adrp(const Register& rd, Label* label) {
975    VIXL_ASSERT(allow_macro_instructions_);
976    VIXL_ASSERT(!rd.IsZero());
977    SingleEmissionCheckScope guard(this);
978    adrp(rd, label);
979  }
980  void Asr(const Register& rd, const Register& rn, unsigned shift) {
981    VIXL_ASSERT(allow_macro_instructions_);
982    VIXL_ASSERT(!rd.IsZero());
983    VIXL_ASSERT(!rn.IsZero());
984    SingleEmissionCheckScope guard(this);
985    asr(rd, rn, shift);
986  }
987  void Asr(const Register& rd, const Register& rn, const Register& rm) {
988    VIXL_ASSERT(allow_macro_instructions_);
989    VIXL_ASSERT(!rd.IsZero());
990    VIXL_ASSERT(!rn.IsZero());
991    VIXL_ASSERT(!rm.IsZero());
992    SingleEmissionCheckScope guard(this);
993    asrv(rd, rn, rm);
994  }
995
996  // Branch type inversion relies on these relations.
997  VIXL_STATIC_ASSERT((reg_zero == (reg_not_zero ^ 1)) &&
998                     (reg_bit_clear == (reg_bit_set ^ 1)) &&
999                     (always == (never ^ 1)));
1000
1001  BranchType InvertBranchType(BranchType type) {
1002    if (kBranchTypeFirstCondition <= type && type <= kBranchTypeLastCondition) {
1003      return static_cast<BranchType>(
1004          InvertCondition(static_cast<Condition>(type)));
1005    } else {
1006      return static_cast<BranchType>(type ^ 1);
1007    }
1008  }
1009
1010  void B(Label* label, BranchType type, Register reg = NoReg, int bit = -1);
1011
1012  void B(Label* label);
1013  void B(Label* label, Condition cond);
1014  void B(Condition cond, Label* label) { B(label, cond); }
1015  void Bfm(const Register& rd,
1016           const Register& rn,
1017           unsigned immr,
1018           unsigned imms) {
1019    VIXL_ASSERT(allow_macro_instructions_);
1020    VIXL_ASSERT(!rd.IsZero());
1021    VIXL_ASSERT(!rn.IsZero());
1022    SingleEmissionCheckScope guard(this);
1023    bfm(rd, rn, immr, imms);
1024  }
1025  void Bfi(const Register& rd,
1026           const Register& rn,
1027           unsigned lsb,
1028           unsigned width) {
1029    VIXL_ASSERT(allow_macro_instructions_);
1030    VIXL_ASSERT(!rd.IsZero());
1031    VIXL_ASSERT(!rn.IsZero());
1032    SingleEmissionCheckScope guard(this);
1033    bfi(rd, rn, lsb, width);
1034  }
1035  void Bfxil(const Register& rd,
1036             const Register& rn,
1037             unsigned lsb,
1038             unsigned width) {
1039    VIXL_ASSERT(allow_macro_instructions_);
1040    VIXL_ASSERT(!rd.IsZero());
1041    VIXL_ASSERT(!rn.IsZero());
1042    SingleEmissionCheckScope guard(this);
1043    bfxil(rd, rn, lsb, width);
1044  }
1045  void Bind(Label* label);
1046  // Bind a label to a specified offset from the start of the buffer.
1047  void BindToOffset(Label* label, ptrdiff_t offset);
1048  void Bl(Label* label) {
1049    VIXL_ASSERT(allow_macro_instructions_);
1050    SingleEmissionCheckScope guard(this);
1051    bl(label);
1052  }
1053  void Blr(const Register& xn) {
1054    VIXL_ASSERT(allow_macro_instructions_);
1055    VIXL_ASSERT(!xn.IsZero());
1056    SingleEmissionCheckScope guard(this);
1057    blr(xn);
1058  }
1059  void Br(const Register& xn) {
1060    VIXL_ASSERT(allow_macro_instructions_);
1061    VIXL_ASSERT(!xn.IsZero());
1062    SingleEmissionCheckScope guard(this);
1063    br(xn);
1064  }
1065  void Brk(int code = 0) {
1066    VIXL_ASSERT(allow_macro_instructions_);
1067    SingleEmissionCheckScope guard(this);
1068    brk(code);
1069  }
1070  void Cbnz(const Register& rt, Label* label);
1071  void Cbz(const Register& rt, Label* label);
1072  void Cinc(const Register& rd, const Register& rn, Condition cond) {
1073    VIXL_ASSERT(allow_macro_instructions_);
1074    VIXL_ASSERT(!rd.IsZero());
1075    VIXL_ASSERT(!rn.IsZero());
1076    SingleEmissionCheckScope guard(this);
1077    cinc(rd, rn, cond);
1078  }
1079  void Cinv(const Register& rd, const Register& rn, Condition cond) {
1080    VIXL_ASSERT(allow_macro_instructions_);
1081    VIXL_ASSERT(!rd.IsZero());
1082    VIXL_ASSERT(!rn.IsZero());
1083    SingleEmissionCheckScope guard(this);
1084    cinv(rd, rn, cond);
1085  }
1086  void Clrex() {
1087    VIXL_ASSERT(allow_macro_instructions_);
1088    SingleEmissionCheckScope guard(this);
1089    clrex();
1090  }
1091  void Cls(const Register& rd, const Register& rn) {
1092    VIXL_ASSERT(allow_macro_instructions_);
1093    VIXL_ASSERT(!rd.IsZero());
1094    VIXL_ASSERT(!rn.IsZero());
1095    SingleEmissionCheckScope guard(this);
1096    cls(rd, rn);
1097  }
1098  void Clz(const Register& rd, const Register& rn) {
1099    VIXL_ASSERT(allow_macro_instructions_);
1100    VIXL_ASSERT(!rd.IsZero());
1101    VIXL_ASSERT(!rn.IsZero());
1102    SingleEmissionCheckScope guard(this);
1103    clz(rd, rn);
1104  }
1105  void Cneg(const Register& rd, const Register& rn, Condition cond) {
1106    VIXL_ASSERT(allow_macro_instructions_);
1107    VIXL_ASSERT(!rd.IsZero());
1108    VIXL_ASSERT(!rn.IsZero());
1109    SingleEmissionCheckScope guard(this);
1110    cneg(rd, rn, cond);
1111  }
1112  void Cset(const Register& rd, Condition cond) {
1113    VIXL_ASSERT(allow_macro_instructions_);
1114    VIXL_ASSERT(!rd.IsZero());
1115    SingleEmissionCheckScope guard(this);
1116    cset(rd, cond);
1117  }
1118  void Csetm(const Register& rd, Condition cond) {
1119    VIXL_ASSERT(allow_macro_instructions_);
1120    VIXL_ASSERT(!rd.IsZero());
1121    SingleEmissionCheckScope guard(this);
1122    csetm(rd, cond);
1123  }
1124  void Csinc(const Register& rd,
1125             const Register& rn,
1126             const Register& rm,
1127             Condition cond) {
1128    VIXL_ASSERT(allow_macro_instructions_);
1129    VIXL_ASSERT(!rd.IsZero());
1130    VIXL_ASSERT(!rn.IsZero());
1131    VIXL_ASSERT(!rm.IsZero());
1132    VIXL_ASSERT((cond != al) && (cond != nv));
1133    SingleEmissionCheckScope guard(this);
1134    csinc(rd, rn, rm, cond);
1135  }
1136  void Csinv(const Register& rd,
1137             const Register& rn,
1138             const Register& rm,
1139             Condition cond) {
1140    VIXL_ASSERT(allow_macro_instructions_);
1141    VIXL_ASSERT(!rd.IsZero());
1142    VIXL_ASSERT(!rn.IsZero());
1143    VIXL_ASSERT(!rm.IsZero());
1144    VIXL_ASSERT((cond != al) && (cond != nv));
1145    SingleEmissionCheckScope guard(this);
1146    csinv(rd, rn, rm, cond);
1147  }
1148  void Csneg(const Register& rd,
1149             const Register& rn,
1150             const Register& rm,
1151             Condition cond) {
1152    VIXL_ASSERT(allow_macro_instructions_);
1153    VIXL_ASSERT(!rd.IsZero());
1154    VIXL_ASSERT(!rn.IsZero());
1155    VIXL_ASSERT(!rm.IsZero());
1156    VIXL_ASSERT((cond != al) && (cond != nv));
1157    SingleEmissionCheckScope guard(this);
1158    csneg(rd, rn, rm, cond);
1159  }
1160  void Dmb(BarrierDomain domain, BarrierType type) {
1161    VIXL_ASSERT(allow_macro_instructions_);
1162    SingleEmissionCheckScope guard(this);
1163    dmb(domain, type);
1164  }
1165  void Dsb(BarrierDomain domain, BarrierType type) {
1166    VIXL_ASSERT(allow_macro_instructions_);
1167    SingleEmissionCheckScope guard(this);
1168    dsb(domain, type);
1169  }
1170  void Extr(const Register& rd,
1171            const Register& rn,
1172            const Register& rm,
1173            unsigned lsb) {
1174    VIXL_ASSERT(allow_macro_instructions_);
1175    VIXL_ASSERT(!rd.IsZero());
1176    VIXL_ASSERT(!rn.IsZero());
1177    VIXL_ASSERT(!rm.IsZero());
1178    SingleEmissionCheckScope guard(this);
1179    extr(rd, rn, rm, lsb);
1180  }
1181  void Fadd(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1182    VIXL_ASSERT(allow_macro_instructions_);
1183    SingleEmissionCheckScope guard(this);
1184    fadd(vd, vn, vm);
1185  }
1186  void Fccmp(const VRegister& vn,
1187             const VRegister& vm,
1188             StatusFlags nzcv,
1189             Condition cond,
1190             FPTrapFlags trap = DisableTrap) {
1191    VIXL_ASSERT(allow_macro_instructions_);
1192    VIXL_ASSERT((cond != al) && (cond != nv));
1193    SingleEmissionCheckScope guard(this);
1194    FPCCompareMacro(vn, vm, nzcv, cond, trap);
1195  }
1196  void Fccmpe(const VRegister& vn,
1197              const VRegister& vm,
1198              StatusFlags nzcv,
1199              Condition cond) {
1200    Fccmp(vn, vm, nzcv, cond, EnableTrap);
1201  }
1202  void Fcmp(const VRegister& vn,
1203            const VRegister& vm,
1204            FPTrapFlags trap = DisableTrap) {
1205    VIXL_ASSERT(allow_macro_instructions_);
1206    SingleEmissionCheckScope guard(this);
1207    FPCompareMacro(vn, vm, trap);
1208  }
1209  void Fcmp(const VRegister& vn, double value, FPTrapFlags trap = DisableTrap);
1210  void Fcmpe(const VRegister& vn, double value);
1211  void Fcmpe(const VRegister& vn, const VRegister& vm) {
1212    Fcmp(vn, vm, EnableTrap);
1213  }
1214  void Fcsel(const VRegister& vd,
1215             const VRegister& vn,
1216             const VRegister& vm,
1217             Condition cond) {
1218    VIXL_ASSERT(allow_macro_instructions_);
1219    VIXL_ASSERT((cond != al) && (cond != nv));
1220    SingleEmissionCheckScope guard(this);
1221    fcsel(vd, vn, vm, cond);
1222  }
1223  void Fcvt(const VRegister& vd, const VRegister& vn) {
1224    VIXL_ASSERT(allow_macro_instructions_);
1225    SingleEmissionCheckScope guard(this);
1226    fcvt(vd, vn);
1227  }
1228  void Fcvtl(const VRegister& vd, const VRegister& vn) {
1229    VIXL_ASSERT(allow_macro_instructions_);
1230    SingleEmissionCheckScope guard(this);
1231    fcvtl(vd, vn);
1232  }
1233  void Fcvtl2(const VRegister& vd, const VRegister& vn) {
1234    VIXL_ASSERT(allow_macro_instructions_);
1235    SingleEmissionCheckScope guard(this);
1236    fcvtl2(vd, vn);
1237  }
1238  void Fcvtn(const VRegister& vd, const VRegister& vn) {
1239    VIXL_ASSERT(allow_macro_instructions_);
1240    SingleEmissionCheckScope guard(this);
1241    fcvtn(vd, vn);
1242  }
1243  void Fcvtn2(const VRegister& vd, const VRegister& vn) {
1244    VIXL_ASSERT(allow_macro_instructions_);
1245    SingleEmissionCheckScope guard(this);
1246    fcvtn2(vd, vn);
1247  }
1248  void Fcvtxn(const VRegister& vd, const VRegister& vn) {
1249    VIXL_ASSERT(allow_macro_instructions_);
1250    SingleEmissionCheckScope guard(this);
1251    fcvtxn(vd, vn);
1252  }
1253  void Fcvtxn2(const VRegister& vd, const VRegister& vn) {
1254    VIXL_ASSERT(allow_macro_instructions_);
1255    SingleEmissionCheckScope guard(this);
1256    fcvtxn2(vd, vn);
1257  }
1258  void Fcvtas(const Register& rd, const VRegister& vn) {
1259    VIXL_ASSERT(allow_macro_instructions_);
1260    VIXL_ASSERT(!rd.IsZero());
1261    SingleEmissionCheckScope guard(this);
1262    fcvtas(rd, vn);
1263  }
1264  void Fcvtau(const Register& rd, const VRegister& vn) {
1265    VIXL_ASSERT(allow_macro_instructions_);
1266    VIXL_ASSERT(!rd.IsZero());
1267    SingleEmissionCheckScope guard(this);
1268    fcvtau(rd, vn);
1269  }
1270  void Fcvtms(const Register& rd, const VRegister& vn) {
1271    VIXL_ASSERT(allow_macro_instructions_);
1272    VIXL_ASSERT(!rd.IsZero());
1273    SingleEmissionCheckScope guard(this);
1274    fcvtms(rd, vn);
1275  }
1276  void Fcvtmu(const Register& rd, const VRegister& vn) {
1277    VIXL_ASSERT(allow_macro_instructions_);
1278    VIXL_ASSERT(!rd.IsZero());
1279    SingleEmissionCheckScope guard(this);
1280    fcvtmu(rd, vn);
1281  }
1282  void Fcvtns(const Register& rd, const VRegister& vn) {
1283    VIXL_ASSERT(allow_macro_instructions_);
1284    VIXL_ASSERT(!rd.IsZero());
1285    SingleEmissionCheckScope guard(this);
1286    fcvtns(rd, vn);
1287  }
1288  void Fcvtnu(const Register& rd, const VRegister& vn) {
1289    VIXL_ASSERT(allow_macro_instructions_);
1290    VIXL_ASSERT(!rd.IsZero());
1291    SingleEmissionCheckScope guard(this);
1292    fcvtnu(rd, vn);
1293  }
1294  void Fcvtps(const Register& rd, const VRegister& vn) {
1295    VIXL_ASSERT(allow_macro_instructions_);
1296    VIXL_ASSERT(!rd.IsZero());
1297    SingleEmissionCheckScope guard(this);
1298    fcvtps(rd, vn);
1299  }
1300  void Fcvtpu(const Register& rd, const VRegister& vn) {
1301    VIXL_ASSERT(allow_macro_instructions_);
1302    VIXL_ASSERT(!rd.IsZero());
1303    SingleEmissionCheckScope guard(this);
1304    fcvtpu(rd, vn);
1305  }
1306  void Fcvtzs(const Register& rd, const VRegister& vn, int fbits = 0) {
1307    VIXL_ASSERT(allow_macro_instructions_);
1308    VIXL_ASSERT(!rd.IsZero());
1309    SingleEmissionCheckScope guard(this);
1310    fcvtzs(rd, vn, fbits);
1311  }
1312  void Fcvtzu(const Register& rd, const VRegister& vn, int fbits = 0) {
1313    VIXL_ASSERT(allow_macro_instructions_);
1314    VIXL_ASSERT(!rd.IsZero());
1315    SingleEmissionCheckScope guard(this);
1316    fcvtzu(rd, vn, fbits);
1317  }
1318  void Fdiv(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1319    VIXL_ASSERT(allow_macro_instructions_);
1320    SingleEmissionCheckScope guard(this);
1321    fdiv(vd, vn, vm);
1322  }
1323  void Fmax(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1324    VIXL_ASSERT(allow_macro_instructions_);
1325    SingleEmissionCheckScope guard(this);
1326    fmax(vd, vn, vm);
1327  }
1328  void Fmaxnm(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1329    VIXL_ASSERT(allow_macro_instructions_);
1330    SingleEmissionCheckScope guard(this);
1331    fmaxnm(vd, vn, vm);
1332  }
1333  void Fmin(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1334    VIXL_ASSERT(allow_macro_instructions_);
1335    SingleEmissionCheckScope guard(this);
1336    fmin(vd, vn, vm);
1337  }
1338  void Fminnm(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1339    VIXL_ASSERT(allow_macro_instructions_);
1340    SingleEmissionCheckScope guard(this);
1341    fminnm(vd, vn, vm);
1342  }
1343  void Fmov(const VRegister& vd, const VRegister& vn) {
1344    VIXL_ASSERT(allow_macro_instructions_);
1345    SingleEmissionCheckScope guard(this);
1346    // Only emit an instruction if vd and vn are different, and they are both D
1347    // registers. fmov(s0, s0) is not a no-op because it clears the top word of
1348    // d0. Technically, fmov(d0, d0) is not a no-op either because it clears
1349    // the top of q0, but VRegister does not currently support Q registers.
1350    if (!vd.Is(vn) || !vd.Is64Bits()) {
1351      fmov(vd, vn);
1352    }
1353  }
1354  void Fmov(const VRegister& vd, const Register& rn) {
1355    VIXL_ASSERT(allow_macro_instructions_);
1356    VIXL_ASSERT(!rn.IsZero());
1357    SingleEmissionCheckScope guard(this);
1358    fmov(vd, rn);
1359  }
1360  void Fmov(const VRegister& vd, const XRegister& xn) {
1361    Fmov(vd, Register(xn));
1362  }
1363  void Fmov(const VRegister& vd, const WRegister& wn) {
1364    Fmov(vd, Register(wn));
1365  }
1366  void Fmov(const VRegister& vd, int index, const Register& rn) {
1367    VIXL_ASSERT(allow_macro_instructions_);
1368    SingleEmissionCheckScope guard(this);
1369    fmov(vd, index, rn);
1370  }
1371  void Fmov(const Register& rd, const VRegister& vn, int index) {
1372    VIXL_ASSERT(allow_macro_instructions_);
1373    SingleEmissionCheckScope guard(this);
1374    fmov(rd, vn, index);
1375  }
1376
1377  // Provide explicit double and float interfaces for FP immediate moves, rather
1378  // than relying on implicit C++ casts. This allows signalling NaNs to be
1379  // preserved when the immediate matches the format of vd. Most systems convert
1380  // signalling NaNs to quiet NaNs when converting between float and double.
1381  void Fmov(VRegister vd, double imm);
1382  void Fmov(VRegister vd, float imm);
1383  // Provide a template to allow other types to be converted automatically.
1384  template <typename T>
1385  void Fmov(VRegister vd, T imm) {
1386    VIXL_ASSERT(allow_macro_instructions_);
1387    Fmov(vd, static_cast<double>(imm));
1388  }
1389  void Fmov(Register rd, VRegister vn) {
1390    VIXL_ASSERT(allow_macro_instructions_);
1391    VIXL_ASSERT(!rd.IsZero());
1392    SingleEmissionCheckScope guard(this);
1393    fmov(rd, vn);
1394  }
1395  void Fmul(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1396    VIXL_ASSERT(allow_macro_instructions_);
1397    SingleEmissionCheckScope guard(this);
1398    fmul(vd, vn, vm);
1399  }
1400  void Fnmul(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1401    VIXL_ASSERT(allow_macro_instructions_);
1402    SingleEmissionCheckScope guard(this);
1403    fnmul(vd, vn, vm);
1404  }
1405  void Fmadd(const VRegister& vd,
1406             const VRegister& vn,
1407             const VRegister& vm,
1408             const VRegister& va) {
1409    VIXL_ASSERT(allow_macro_instructions_);
1410    SingleEmissionCheckScope guard(this);
1411    fmadd(vd, vn, vm, va);
1412  }
1413  void Fmsub(const VRegister& vd,
1414             const VRegister& vn,
1415             const VRegister& vm,
1416             const VRegister& va) {
1417    VIXL_ASSERT(allow_macro_instructions_);
1418    SingleEmissionCheckScope guard(this);
1419    fmsub(vd, vn, vm, va);
1420  }
1421  void Fnmadd(const VRegister& vd,
1422              const VRegister& vn,
1423              const VRegister& vm,
1424              const VRegister& va) {
1425    VIXL_ASSERT(allow_macro_instructions_);
1426    SingleEmissionCheckScope guard(this);
1427    fnmadd(vd, vn, vm, va);
1428  }
1429  void Fnmsub(const VRegister& vd,
1430              const VRegister& vn,
1431              const VRegister& vm,
1432              const VRegister& va) {
1433    VIXL_ASSERT(allow_macro_instructions_);
1434    SingleEmissionCheckScope guard(this);
1435    fnmsub(vd, vn, vm, va);
1436  }
1437  void Fsub(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1438    VIXL_ASSERT(allow_macro_instructions_);
1439    SingleEmissionCheckScope guard(this);
1440    fsub(vd, vn, vm);
1441  }
1442  void Hint(SystemHint code) {
1443    VIXL_ASSERT(allow_macro_instructions_);
1444    SingleEmissionCheckScope guard(this);
1445    hint(code);
1446  }
1447  void Hlt(int code) {
1448    VIXL_ASSERT(allow_macro_instructions_);
1449    SingleEmissionCheckScope guard(this);
1450    hlt(code);
1451  }
1452  void Isb() {
1453    VIXL_ASSERT(allow_macro_instructions_);
1454    SingleEmissionCheckScope guard(this);
1455    isb();
1456  }
1457  void Ldar(const Register& rt, const MemOperand& src) {
1458    VIXL_ASSERT(allow_macro_instructions_);
1459    SingleEmissionCheckScope guard(this);
1460    ldar(rt, src);
1461  }
1462  void Ldarb(const Register& rt, const MemOperand& src) {
1463    VIXL_ASSERT(allow_macro_instructions_);
1464    SingleEmissionCheckScope guard(this);
1465    ldarb(rt, src);
1466  }
1467  void Ldarh(const Register& rt, const MemOperand& src) {
1468    VIXL_ASSERT(allow_macro_instructions_);
1469    SingleEmissionCheckScope guard(this);
1470    ldarh(rt, src);
1471  }
1472  void Ldaxp(const Register& rt, const Register& rt2, const MemOperand& src) {
1473    VIXL_ASSERT(allow_macro_instructions_);
1474    VIXL_ASSERT(!rt.Aliases(rt2));
1475    SingleEmissionCheckScope guard(this);
1476    ldaxp(rt, rt2, src);
1477  }
1478  void Ldaxr(const Register& rt, const MemOperand& src) {
1479    VIXL_ASSERT(allow_macro_instructions_);
1480    SingleEmissionCheckScope guard(this);
1481    ldaxr(rt, src);
1482  }
1483  void Ldaxrb(const Register& rt, const MemOperand& src) {
1484    VIXL_ASSERT(allow_macro_instructions_);
1485    SingleEmissionCheckScope guard(this);
1486    ldaxrb(rt, src);
1487  }
1488  void Ldaxrh(const Register& rt, const MemOperand& src) {
1489    VIXL_ASSERT(allow_macro_instructions_);
1490    SingleEmissionCheckScope guard(this);
1491    ldaxrh(rt, src);
1492  }
1493  void Ldnp(const CPURegister& rt,
1494            const CPURegister& rt2,
1495            const MemOperand& src) {
1496    VIXL_ASSERT(allow_macro_instructions_);
1497    SingleEmissionCheckScope guard(this);
1498    ldnp(rt, rt2, src);
1499  }
1500  // Provide both double and float interfaces for FP immediate loads, rather
1501  // than relying on implicit C++ casts. This allows signalling NaNs to be
1502  // preserved when the immediate matches the format of fd. Most systems convert
1503  // signalling NaNs to quiet NaNs when converting between float and double.
1504  void Ldr(const VRegister& vt, double imm) {
1505    VIXL_ASSERT(allow_macro_instructions_);
1506    SingleEmissionCheckScope guard(this);
1507    RawLiteral* literal;
1508    if (vt.IsD()) {
1509      literal = new Literal<double>(imm,
1510                                    &literal_pool_,
1511                                    RawLiteral::kDeletedOnPlacementByPool);
1512    } else {
1513      literal = new Literal<float>(static_cast<float>(imm),
1514                                   &literal_pool_,
1515                                   RawLiteral::kDeletedOnPlacementByPool);
1516    }
1517    ldr(vt, literal);
1518  }
1519  void Ldr(const VRegister& vt, float imm) {
1520    VIXL_ASSERT(allow_macro_instructions_);
1521    SingleEmissionCheckScope guard(this);
1522    RawLiteral* literal;
1523    if (vt.IsS()) {
1524      literal = new Literal<float>(imm,
1525                                   &literal_pool_,
1526                                   RawLiteral::kDeletedOnPlacementByPool);
1527    } else {
1528      literal = new Literal<double>(static_cast<double>(imm),
1529                                    &literal_pool_,
1530                                    RawLiteral::kDeletedOnPlacementByPool);
1531    }
1532    ldr(vt, literal);
1533  }
1534  void Ldr(const VRegister& vt, uint64_t high64, uint64_t low64) {
1535    VIXL_ASSERT(allow_macro_instructions_);
1536    VIXL_ASSERT(vt.IsQ());
1537    SingleEmissionCheckScope guard(this);
1538    ldr(vt,
1539        new Literal<uint64_t>(high64,
1540                              low64,
1541                              &literal_pool_,
1542                              RawLiteral::kDeletedOnPlacementByPool));
1543  }
1544  void Ldr(const Register& rt, uint64_t imm) {
1545    VIXL_ASSERT(allow_macro_instructions_);
1546    VIXL_ASSERT(!rt.IsZero());
1547    SingleEmissionCheckScope guard(this);
1548    RawLiteral* literal;
1549    if (rt.Is64Bits()) {
1550      literal = new Literal<uint64_t>(imm,
1551                                      &literal_pool_,
1552                                      RawLiteral::kDeletedOnPlacementByPool);
1553    } else {
1554      VIXL_ASSERT(rt.Is32Bits());
1555      VIXL_ASSERT(IsUint32(imm) || IsInt32(imm));
1556      literal = new Literal<uint32_t>(static_cast<uint32_t>(imm),
1557                                      &literal_pool_,
1558                                      RawLiteral::kDeletedOnPlacementByPool);
1559    }
1560    ldr(rt, literal);
1561  }
1562  void Ldrsw(const Register& rt, uint32_t imm) {
1563    VIXL_ASSERT(allow_macro_instructions_);
1564    VIXL_ASSERT(!rt.IsZero());
1565    SingleEmissionCheckScope guard(this);
1566    ldrsw(rt,
1567          new Literal<uint32_t>(imm,
1568                                &literal_pool_,
1569                                RawLiteral::kDeletedOnPlacementByPool));
1570  }
1571  void Ldr(const CPURegister& rt, RawLiteral* literal) {
1572    VIXL_ASSERT(allow_macro_instructions_);
1573    SingleEmissionCheckScope guard(this);
1574    ldr(rt, literal);
1575  }
1576  void Ldrsw(const Register& rt, RawLiteral* literal) {
1577    VIXL_ASSERT(allow_macro_instructions_);
1578    SingleEmissionCheckScope guard(this);
1579    ldrsw(rt, literal);
1580  }
1581  void Ldxp(const Register& rt, const Register& rt2, const MemOperand& src) {
1582    VIXL_ASSERT(allow_macro_instructions_);
1583    VIXL_ASSERT(!rt.Aliases(rt2));
1584    SingleEmissionCheckScope guard(this);
1585    ldxp(rt, rt2, src);
1586  }
1587  void Ldxr(const Register& rt, const MemOperand& src) {
1588    VIXL_ASSERT(allow_macro_instructions_);
1589    SingleEmissionCheckScope guard(this);
1590    ldxr(rt, src);
1591  }
1592  void Ldxrb(const Register& rt, const MemOperand& src) {
1593    VIXL_ASSERT(allow_macro_instructions_);
1594    SingleEmissionCheckScope guard(this);
1595    ldxrb(rt, src);
1596  }
1597  void Ldxrh(const Register& rt, const MemOperand& src) {
1598    VIXL_ASSERT(allow_macro_instructions_);
1599    SingleEmissionCheckScope guard(this);
1600    ldxrh(rt, src);
1601  }
1602  void Lsl(const Register& rd, const Register& rn, unsigned shift) {
1603    VIXL_ASSERT(allow_macro_instructions_);
1604    VIXL_ASSERT(!rd.IsZero());
1605    VIXL_ASSERT(!rn.IsZero());
1606    SingleEmissionCheckScope guard(this);
1607    lsl(rd, rn, shift);
1608  }
1609  void Lsl(const Register& rd, const Register& rn, const Register& rm) {
1610    VIXL_ASSERT(allow_macro_instructions_);
1611    VIXL_ASSERT(!rd.IsZero());
1612    VIXL_ASSERT(!rn.IsZero());
1613    VIXL_ASSERT(!rm.IsZero());
1614    SingleEmissionCheckScope guard(this);
1615    lslv(rd, rn, rm);
1616  }
1617  void Lsr(const Register& rd, const Register& rn, unsigned shift) {
1618    VIXL_ASSERT(allow_macro_instructions_);
1619    VIXL_ASSERT(!rd.IsZero());
1620    VIXL_ASSERT(!rn.IsZero());
1621    SingleEmissionCheckScope guard(this);
1622    lsr(rd, rn, shift);
1623  }
1624  void Lsr(const Register& rd, const Register& rn, const Register& rm) {
1625    VIXL_ASSERT(allow_macro_instructions_);
1626    VIXL_ASSERT(!rd.IsZero());
1627    VIXL_ASSERT(!rn.IsZero());
1628    VIXL_ASSERT(!rm.IsZero());
1629    SingleEmissionCheckScope guard(this);
1630    lsrv(rd, rn, rm);
1631  }
1632  void Madd(const Register& rd,
1633            const Register& rn,
1634            const Register& rm,
1635            const Register& ra) {
1636    VIXL_ASSERT(allow_macro_instructions_);
1637    VIXL_ASSERT(!rd.IsZero());
1638    VIXL_ASSERT(!rn.IsZero());
1639    VIXL_ASSERT(!rm.IsZero());
1640    VIXL_ASSERT(!ra.IsZero());
1641    SingleEmissionCheckScope guard(this);
1642    madd(rd, rn, rm, ra);
1643  }
1644  void Mneg(const Register& rd, const Register& rn, const Register& rm) {
1645    VIXL_ASSERT(allow_macro_instructions_);
1646    VIXL_ASSERT(!rd.IsZero());
1647    VIXL_ASSERT(!rn.IsZero());
1648    VIXL_ASSERT(!rm.IsZero());
1649    SingleEmissionCheckScope guard(this);
1650    mneg(rd, rn, rm);
1651  }
1652  void Mov(const Register& rd,
1653           const Register& rn,
1654           DiscardMoveMode discard_mode = kDontDiscardForSameWReg) {
1655    VIXL_ASSERT(allow_macro_instructions_);
1656    // Emit a register move only if the registers are distinct, or if they are
1657    // not X registers.
1658    //
1659    // Note that mov(w0, w0) is not a no-op because it clears the top word of
1660    // x0. A flag is provided (kDiscardForSameWReg) if a move between the same W
1661    // registers is not required to clear the top word of the X register. In
1662    // this case, the instruction is discarded.
1663    //
1664    // If the sp is an operand, add #0 is emitted, otherwise, orr #0.
1665    if (!rd.Is(rn) ||
1666        (rd.Is32Bits() && (discard_mode == kDontDiscardForSameWReg))) {
1667      SingleEmissionCheckScope guard(this);
1668      mov(rd, rn);
1669    }
1670  }
1671  void Movk(const Register& rd, uint64_t imm, int shift = -1) {
1672    VIXL_ASSERT(allow_macro_instructions_);
1673    VIXL_ASSERT(!rd.IsZero());
1674    SingleEmissionCheckScope guard(this);
1675    movk(rd, imm, shift);
1676  }
1677  void Mrs(const Register& rt, SystemRegister sysreg) {
1678    VIXL_ASSERT(allow_macro_instructions_);
1679    VIXL_ASSERT(!rt.IsZero());
1680    SingleEmissionCheckScope guard(this);
1681    mrs(rt, sysreg);
1682  }
1683  void Msr(SystemRegister sysreg, const Register& rt) {
1684    VIXL_ASSERT(allow_macro_instructions_);
1685    VIXL_ASSERT(!rt.IsZero());
1686    SingleEmissionCheckScope guard(this);
1687    msr(sysreg, rt);
1688  }
1689  void Sys(int op1, int crn, int crm, int op2, const Register& rt = xzr) {
1690    VIXL_ASSERT(allow_macro_instructions_);
1691    SingleEmissionCheckScope guard(this);
1692    sys(op1, crn, crm, op2, rt);
1693  }
1694  void Dc(DataCacheOp op, const Register& rt) {
1695    VIXL_ASSERT(allow_macro_instructions_);
1696    SingleEmissionCheckScope guard(this);
1697    dc(op, rt);
1698  }
1699  void Ic(InstructionCacheOp op, const Register& rt) {
1700    VIXL_ASSERT(allow_macro_instructions_);
1701    SingleEmissionCheckScope guard(this);
1702    ic(op, rt);
1703  }
1704  void Msub(const Register& rd,
1705            const Register& rn,
1706            const Register& rm,
1707            const Register& ra) {
1708    VIXL_ASSERT(allow_macro_instructions_);
1709    VIXL_ASSERT(!rd.IsZero());
1710    VIXL_ASSERT(!rn.IsZero());
1711    VIXL_ASSERT(!rm.IsZero());
1712    VIXL_ASSERT(!ra.IsZero());
1713    SingleEmissionCheckScope guard(this);
1714    msub(rd, rn, rm, ra);
1715  }
1716  void Mul(const Register& rd, const Register& rn, const Register& rm) {
1717    VIXL_ASSERT(allow_macro_instructions_);
1718    VIXL_ASSERT(!rd.IsZero());
1719    VIXL_ASSERT(!rn.IsZero());
1720    VIXL_ASSERT(!rm.IsZero());
1721    SingleEmissionCheckScope guard(this);
1722    mul(rd, rn, rm);
1723  }
1724  void Nop() {
1725    VIXL_ASSERT(allow_macro_instructions_);
1726    SingleEmissionCheckScope guard(this);
1727    nop();
1728  }
1729  void Rbit(const Register& rd, const Register& rn) {
1730    VIXL_ASSERT(allow_macro_instructions_);
1731    VIXL_ASSERT(!rd.IsZero());
1732    VIXL_ASSERT(!rn.IsZero());
1733    SingleEmissionCheckScope guard(this);
1734    rbit(rd, rn);
1735  }
1736  void Ret(const Register& xn = lr) {
1737    VIXL_ASSERT(allow_macro_instructions_);
1738    VIXL_ASSERT(!xn.IsZero());
1739    SingleEmissionCheckScope guard(this);
1740    ret(xn);
1741  }
1742  void Rev(const Register& rd, const Register& rn) {
1743    VIXL_ASSERT(allow_macro_instructions_);
1744    VIXL_ASSERT(!rd.IsZero());
1745    VIXL_ASSERT(!rn.IsZero());
1746    SingleEmissionCheckScope guard(this);
1747    rev(rd, rn);
1748  }
1749  void Rev16(const Register& rd, const Register& rn) {
1750    VIXL_ASSERT(allow_macro_instructions_);
1751    VIXL_ASSERT(!rd.IsZero());
1752    VIXL_ASSERT(!rn.IsZero());
1753    SingleEmissionCheckScope guard(this);
1754    rev16(rd, rn);
1755  }
1756  void Rev32(const Register& rd, const Register& rn) {
1757    VIXL_ASSERT(allow_macro_instructions_);
1758    VIXL_ASSERT(!rd.IsZero());
1759    VIXL_ASSERT(!rn.IsZero());
1760    SingleEmissionCheckScope guard(this);
1761    rev32(rd, rn);
1762  }
1763  void Ror(const Register& rd, const Register& rs, unsigned shift) {
1764    VIXL_ASSERT(allow_macro_instructions_);
1765    VIXL_ASSERT(!rd.IsZero());
1766    VIXL_ASSERT(!rs.IsZero());
1767    SingleEmissionCheckScope guard(this);
1768    ror(rd, rs, shift);
1769  }
1770  void Ror(const Register& rd, const Register& rn, const Register& rm) {
1771    VIXL_ASSERT(allow_macro_instructions_);
1772    VIXL_ASSERT(!rd.IsZero());
1773    VIXL_ASSERT(!rn.IsZero());
1774    VIXL_ASSERT(!rm.IsZero());
1775    SingleEmissionCheckScope guard(this);
1776    rorv(rd, rn, rm);
1777  }
1778  void Sbfiz(const Register& rd,
1779             const Register& rn,
1780             unsigned lsb,
1781             unsigned width) {
1782    VIXL_ASSERT(allow_macro_instructions_);
1783    VIXL_ASSERT(!rd.IsZero());
1784    VIXL_ASSERT(!rn.IsZero());
1785    SingleEmissionCheckScope guard(this);
1786    sbfiz(rd, rn, lsb, width);
1787  }
1788  void Sbfm(const Register& rd,
1789            const Register& rn,
1790            unsigned immr,
1791            unsigned imms) {
1792    VIXL_ASSERT(allow_macro_instructions_);
1793    VIXL_ASSERT(!rd.IsZero());
1794    VIXL_ASSERT(!rn.IsZero());
1795    SingleEmissionCheckScope guard(this);
1796    sbfm(rd, rn, immr, imms);
1797  }
1798  void Sbfx(const Register& rd,
1799            const Register& rn,
1800            unsigned lsb,
1801            unsigned width) {
1802    VIXL_ASSERT(allow_macro_instructions_);
1803    VIXL_ASSERT(!rd.IsZero());
1804    VIXL_ASSERT(!rn.IsZero());
1805    SingleEmissionCheckScope guard(this);
1806    sbfx(rd, rn, lsb, width);
1807  }
1808  void Scvtf(const VRegister& vd, const Register& rn, int fbits = 0) {
1809    VIXL_ASSERT(allow_macro_instructions_);
1810    VIXL_ASSERT(!rn.IsZero());
1811    SingleEmissionCheckScope guard(this);
1812    scvtf(vd, rn, fbits);
1813  }
1814  void Sdiv(const Register& rd, const Register& rn, const Register& rm) {
1815    VIXL_ASSERT(allow_macro_instructions_);
1816    VIXL_ASSERT(!rd.IsZero());
1817    VIXL_ASSERT(!rn.IsZero());
1818    VIXL_ASSERT(!rm.IsZero());
1819    SingleEmissionCheckScope guard(this);
1820    sdiv(rd, rn, rm);
1821  }
1822  void Smaddl(const Register& rd,
1823              const Register& rn,
1824              const Register& rm,
1825              const Register& ra) {
1826    VIXL_ASSERT(allow_macro_instructions_);
1827    VIXL_ASSERT(!rd.IsZero());
1828    VIXL_ASSERT(!rn.IsZero());
1829    VIXL_ASSERT(!rm.IsZero());
1830    VIXL_ASSERT(!ra.IsZero());
1831    SingleEmissionCheckScope guard(this);
1832    smaddl(rd, rn, rm, ra);
1833  }
1834  void Smsubl(const Register& rd,
1835              const Register& rn,
1836              const Register& rm,
1837              const Register& ra) {
1838    VIXL_ASSERT(allow_macro_instructions_);
1839    VIXL_ASSERT(!rd.IsZero());
1840    VIXL_ASSERT(!rn.IsZero());
1841    VIXL_ASSERT(!rm.IsZero());
1842    VIXL_ASSERT(!ra.IsZero());
1843    SingleEmissionCheckScope guard(this);
1844    smsubl(rd, rn, rm, ra);
1845  }
1846  void Smull(const Register& rd, const Register& rn, const Register& rm) {
1847    VIXL_ASSERT(allow_macro_instructions_);
1848    VIXL_ASSERT(!rd.IsZero());
1849    VIXL_ASSERT(!rn.IsZero());
1850    VIXL_ASSERT(!rm.IsZero());
1851    SingleEmissionCheckScope guard(this);
1852    smull(rd, rn, rm);
1853  }
1854  void Smulh(const Register& xd, const Register& xn, const Register& xm) {
1855    VIXL_ASSERT(allow_macro_instructions_);
1856    VIXL_ASSERT(!xd.IsZero());
1857    VIXL_ASSERT(!xn.IsZero());
1858    VIXL_ASSERT(!xm.IsZero());
1859    SingleEmissionCheckScope guard(this);
1860    smulh(xd, xn, xm);
1861  }
1862  void Stlr(const Register& rt, const MemOperand& dst) {
1863    VIXL_ASSERT(allow_macro_instructions_);
1864    SingleEmissionCheckScope guard(this);
1865    stlr(rt, dst);
1866  }
1867  void Stlrb(const Register& rt, const MemOperand& dst) {
1868    VIXL_ASSERT(allow_macro_instructions_);
1869    SingleEmissionCheckScope guard(this);
1870    stlrb(rt, dst);
1871  }
1872  void Stlrh(const Register& rt, const MemOperand& dst) {
1873    VIXL_ASSERT(allow_macro_instructions_);
1874    SingleEmissionCheckScope guard(this);
1875    stlrh(rt, dst);
1876  }
1877  void Stlxp(const Register& rs,
1878             const Register& rt,
1879             const Register& rt2,
1880             const MemOperand& dst) {
1881    VIXL_ASSERT(allow_macro_instructions_);
1882    VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
1883    VIXL_ASSERT(!rs.Aliases(rt));
1884    VIXL_ASSERT(!rs.Aliases(rt2));
1885    SingleEmissionCheckScope guard(this);
1886    stlxp(rs, rt, rt2, dst);
1887  }
1888  void Stlxr(const Register& rs, const Register& rt, const MemOperand& dst) {
1889    VIXL_ASSERT(allow_macro_instructions_);
1890    VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
1891    VIXL_ASSERT(!rs.Aliases(rt));
1892    SingleEmissionCheckScope guard(this);
1893    stlxr(rs, rt, dst);
1894  }
1895  void Stlxrb(const Register& rs, const Register& rt, const MemOperand& dst) {
1896    VIXL_ASSERT(allow_macro_instructions_);
1897    VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
1898    VIXL_ASSERT(!rs.Aliases(rt));
1899    SingleEmissionCheckScope guard(this);
1900    stlxrb(rs, rt, dst);
1901  }
1902  void Stlxrh(const Register& rs, const Register& rt, const MemOperand& dst) {
1903    VIXL_ASSERT(allow_macro_instructions_);
1904    VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
1905    VIXL_ASSERT(!rs.Aliases(rt));
1906    SingleEmissionCheckScope guard(this);
1907    stlxrh(rs, rt, dst);
1908  }
1909  void Stnp(const CPURegister& rt,
1910            const CPURegister& rt2,
1911            const MemOperand& dst) {
1912    VIXL_ASSERT(allow_macro_instructions_);
1913    SingleEmissionCheckScope guard(this);
1914    stnp(rt, rt2, dst);
1915  }
1916  void Stxp(const Register& rs,
1917            const Register& rt,
1918            const Register& rt2,
1919            const MemOperand& dst) {
1920    VIXL_ASSERT(allow_macro_instructions_);
1921    VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
1922    VIXL_ASSERT(!rs.Aliases(rt));
1923    VIXL_ASSERT(!rs.Aliases(rt2));
1924    SingleEmissionCheckScope guard(this);
1925    stxp(rs, rt, rt2, dst);
1926  }
1927  void Stxr(const Register& rs, const Register& rt, const MemOperand& dst) {
1928    VIXL_ASSERT(allow_macro_instructions_);
1929    VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
1930    VIXL_ASSERT(!rs.Aliases(rt));
1931    SingleEmissionCheckScope guard(this);
1932    stxr(rs, rt, dst);
1933  }
1934  void Stxrb(const Register& rs, const Register& rt, const MemOperand& dst) {
1935    VIXL_ASSERT(allow_macro_instructions_);
1936    VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
1937    VIXL_ASSERT(!rs.Aliases(rt));
1938    SingleEmissionCheckScope guard(this);
1939    stxrb(rs, rt, dst);
1940  }
1941  void Stxrh(const Register& rs, const Register& rt, const MemOperand& dst) {
1942    VIXL_ASSERT(allow_macro_instructions_);
1943    VIXL_ASSERT(!rs.Aliases(dst.GetBaseRegister()));
1944    VIXL_ASSERT(!rs.Aliases(rt));
1945    SingleEmissionCheckScope guard(this);
1946    stxrh(rs, rt, dst);
1947  }
1948  void Svc(int code) {
1949    VIXL_ASSERT(allow_macro_instructions_);
1950    SingleEmissionCheckScope guard(this);
1951    svc(code);
1952  }
1953  void Sxtb(const Register& rd, const Register& rn) {
1954    VIXL_ASSERT(allow_macro_instructions_);
1955    VIXL_ASSERT(!rd.IsZero());
1956    VIXL_ASSERT(!rn.IsZero());
1957    SingleEmissionCheckScope guard(this);
1958    sxtb(rd, rn);
1959  }
1960  void Sxth(const Register& rd, const Register& rn) {
1961    VIXL_ASSERT(allow_macro_instructions_);
1962    VIXL_ASSERT(!rd.IsZero());
1963    VIXL_ASSERT(!rn.IsZero());
1964    SingleEmissionCheckScope guard(this);
1965    sxth(rd, rn);
1966  }
1967  void Sxtw(const Register& rd, const Register& rn) {
1968    VIXL_ASSERT(allow_macro_instructions_);
1969    VIXL_ASSERT(!rd.IsZero());
1970    VIXL_ASSERT(!rn.IsZero());
1971    SingleEmissionCheckScope guard(this);
1972    sxtw(rd, rn);
1973  }
1974  void Tbl(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
1975    VIXL_ASSERT(allow_macro_instructions_);
1976    SingleEmissionCheckScope guard(this);
1977    tbl(vd, vn, vm);
1978  }
1979  void Tbl(const VRegister& vd,
1980           const VRegister& vn,
1981           const VRegister& vn2,
1982           const VRegister& vm) {
1983    VIXL_ASSERT(allow_macro_instructions_);
1984    SingleEmissionCheckScope guard(this);
1985    tbl(vd, vn, vn2, vm);
1986  }
1987  void Tbl(const VRegister& vd,
1988           const VRegister& vn,
1989           const VRegister& vn2,
1990           const VRegister& vn3,
1991           const VRegister& vm) {
1992    VIXL_ASSERT(allow_macro_instructions_);
1993    SingleEmissionCheckScope guard(this);
1994    tbl(vd, vn, vn2, vn3, vm);
1995  }
1996  void Tbl(const VRegister& vd,
1997           const VRegister& vn,
1998           const VRegister& vn2,
1999           const VRegister& vn3,
2000           const VRegister& vn4,
2001           const VRegister& vm) {
2002    VIXL_ASSERT(allow_macro_instructions_);
2003    SingleEmissionCheckScope guard(this);
2004    tbl(vd, vn, vn2, vn3, vn4, vm);
2005  }
2006  void Tbx(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
2007    VIXL_ASSERT(allow_macro_instructions_);
2008    SingleEmissionCheckScope guard(this);
2009    tbx(vd, vn, vm);
2010  }
2011  void Tbx(const VRegister& vd,
2012           const VRegister& vn,
2013           const VRegister& vn2,
2014           const VRegister& vm) {
2015    VIXL_ASSERT(allow_macro_instructions_);
2016    SingleEmissionCheckScope guard(this);
2017    tbx(vd, vn, vn2, vm);
2018  }
2019  void Tbx(const VRegister& vd,
2020           const VRegister& vn,
2021           const VRegister& vn2,
2022           const VRegister& vn3,
2023           const VRegister& vm) {
2024    VIXL_ASSERT(allow_macro_instructions_);
2025    SingleEmissionCheckScope guard(this);
2026    tbx(vd, vn, vn2, vn3, vm);
2027  }
2028  void Tbx(const VRegister& vd,
2029           const VRegister& vn,
2030           const VRegister& vn2,
2031           const VRegister& vn3,
2032           const VRegister& vn4,
2033           const VRegister& vm) {
2034    VIXL_ASSERT(allow_macro_instructions_);
2035    SingleEmissionCheckScope guard(this);
2036    tbx(vd, vn, vn2, vn3, vn4, vm);
2037  }
2038  void Tbnz(const Register& rt, unsigned bit_pos, Label* label);
2039  void Tbz(const Register& rt, unsigned bit_pos, Label* label);
2040  void Ubfiz(const Register& rd,
2041             const Register& rn,
2042             unsigned lsb,
2043             unsigned width) {
2044    VIXL_ASSERT(allow_macro_instructions_);
2045    VIXL_ASSERT(!rd.IsZero());
2046    VIXL_ASSERT(!rn.IsZero());
2047    SingleEmissionCheckScope guard(this);
2048    ubfiz(rd, rn, lsb, width);
2049  }
2050  void Ubfm(const Register& rd,
2051            const Register& rn,
2052            unsigned immr,
2053            unsigned imms) {
2054    VIXL_ASSERT(allow_macro_instructions_);
2055    VIXL_ASSERT(!rd.IsZero());
2056    VIXL_ASSERT(!rn.IsZero());
2057    SingleEmissionCheckScope guard(this);
2058    ubfm(rd, rn, immr, imms);
2059  }
2060  void Ubfx(const Register& rd,
2061            const Register& rn,
2062            unsigned lsb,
2063            unsigned width) {
2064    VIXL_ASSERT(allow_macro_instructions_);
2065    VIXL_ASSERT(!rd.IsZero());
2066    VIXL_ASSERT(!rn.IsZero());
2067    SingleEmissionCheckScope guard(this);
2068    ubfx(rd, rn, lsb, width);
2069  }
2070  void Ucvtf(const VRegister& vd, const Register& rn, int fbits = 0) {
2071    VIXL_ASSERT(allow_macro_instructions_);
2072    VIXL_ASSERT(!rn.IsZero());
2073    SingleEmissionCheckScope guard(this);
2074    ucvtf(vd, rn, fbits);
2075  }
2076  void Udiv(const Register& rd, const Register& rn, const Register& rm) {
2077    VIXL_ASSERT(allow_macro_instructions_);
2078    VIXL_ASSERT(!rd.IsZero());
2079    VIXL_ASSERT(!rn.IsZero());
2080    VIXL_ASSERT(!rm.IsZero());
2081    SingleEmissionCheckScope guard(this);
2082    udiv(rd, rn, rm);
2083  }
2084  void Umaddl(const Register& rd,
2085              const Register& rn,
2086              const Register& rm,
2087              const Register& ra) {
2088    VIXL_ASSERT(allow_macro_instructions_);
2089    VIXL_ASSERT(!rd.IsZero());
2090    VIXL_ASSERT(!rn.IsZero());
2091    VIXL_ASSERT(!rm.IsZero());
2092    VIXL_ASSERT(!ra.IsZero());
2093    SingleEmissionCheckScope guard(this);
2094    umaddl(rd, rn, rm, ra);
2095  }
2096  void Umull(const Register& rd, const Register& rn, const Register& rm) {
2097    VIXL_ASSERT(allow_macro_instructions_);
2098    VIXL_ASSERT(!rd.IsZero());
2099    VIXL_ASSERT(!rn.IsZero());
2100    VIXL_ASSERT(!rm.IsZero());
2101    SingleEmissionCheckScope guard(this);
2102    umull(rd, rn, rm);
2103  }
2104  void Umulh(const Register& xd, const Register& xn, const Register& xm) {
2105    VIXL_ASSERT(allow_macro_instructions_);
2106    VIXL_ASSERT(!xd.IsZero());
2107    VIXL_ASSERT(!xn.IsZero());
2108    VIXL_ASSERT(!xm.IsZero());
2109    SingleEmissionCheckScope guard(this);
2110    umulh(xd, xn, xm);
2111  }
2112  void Umsubl(const Register& rd,
2113              const Register& rn,
2114              const Register& rm,
2115              const Register& ra) {
2116    VIXL_ASSERT(allow_macro_instructions_);
2117    VIXL_ASSERT(!rd.IsZero());
2118    VIXL_ASSERT(!rn.IsZero());
2119    VIXL_ASSERT(!rm.IsZero());
2120    VIXL_ASSERT(!ra.IsZero());
2121    SingleEmissionCheckScope guard(this);
2122    umsubl(rd, rn, rm, ra);
2123  }
2124  void Unreachable() {
2125    VIXL_ASSERT(allow_macro_instructions_);
2126    SingleEmissionCheckScope guard(this);
2127    if (generate_simulator_code_) {
2128      hlt(kUnreachableOpcode);
2129    } else {
2130      // Branch to 0 to generate a segfault.
2131      // lr - kInstructionSize is the address of the offending instruction.
2132      blr(xzr);
2133    }
2134  }
2135  void Uxtb(const Register& rd, const Register& rn) {
2136    VIXL_ASSERT(allow_macro_instructions_);
2137    VIXL_ASSERT(!rd.IsZero());
2138    VIXL_ASSERT(!rn.IsZero());
2139    SingleEmissionCheckScope guard(this);
2140    uxtb(rd, rn);
2141  }
2142  void Uxth(const Register& rd, const Register& rn) {
2143    VIXL_ASSERT(allow_macro_instructions_);
2144    VIXL_ASSERT(!rd.IsZero());
2145    VIXL_ASSERT(!rn.IsZero());
2146    SingleEmissionCheckScope guard(this);
2147    uxth(rd, rn);
2148  }
2149  void Uxtw(const Register& rd, const Register& rn) {
2150    VIXL_ASSERT(allow_macro_instructions_);
2151    VIXL_ASSERT(!rd.IsZero());
2152    VIXL_ASSERT(!rn.IsZero());
2153    SingleEmissionCheckScope guard(this);
2154    uxtw(rd, rn);
2155  }
2156
2157// NEON 3 vector register instructions.
2158#define NEON_3VREG_MACRO_LIST(V) \
2159  V(add, Add)                    \
2160  V(addhn, Addhn)                \
2161  V(addhn2, Addhn2)              \
2162  V(addp, Addp)                  \
2163  V(and_, And)                   \
2164  V(bic, Bic)                    \
2165  V(bif, Bif)                    \
2166  V(bit, Bit)                    \
2167  V(bsl, Bsl)                    \
2168  V(cmeq, Cmeq)                  \
2169  V(cmge, Cmge)                  \
2170  V(cmgt, Cmgt)                  \
2171  V(cmhi, Cmhi)                  \
2172  V(cmhs, Cmhs)                  \
2173  V(cmtst, Cmtst)                \
2174  V(eor, Eor)                    \
2175  V(fabd, Fabd)                  \
2176  V(facge, Facge)                \
2177  V(facgt, Facgt)                \
2178  V(faddp, Faddp)                \
2179  V(fcmeq, Fcmeq)                \
2180  V(fcmge, Fcmge)                \
2181  V(fcmgt, Fcmgt)                \
2182  V(fmaxnmp, Fmaxnmp)            \
2183  V(fmaxp, Fmaxp)                \
2184  V(fminnmp, Fminnmp)            \
2185  V(fminp, Fminp)                \
2186  V(fmla, Fmla)                  \
2187  V(fmls, Fmls)                  \
2188  V(fmulx, Fmulx)                \
2189  V(frecps, Frecps)              \
2190  V(frsqrts, Frsqrts)            \
2191  V(mla, Mla)                    \
2192  V(mls, Mls)                    \
2193  V(mul, Mul)                    \
2194  V(orn, Orn)                    \
2195  V(orr, Orr)                    \
2196  V(pmul, Pmul)                  \
2197  V(pmull, Pmull)                \
2198  V(pmull2, Pmull2)              \
2199  V(raddhn, Raddhn)              \
2200  V(raddhn2, Raddhn2)            \
2201  V(rsubhn, Rsubhn)              \
2202  V(rsubhn2, Rsubhn2)            \
2203  V(saba, Saba)                  \
2204  V(sabal, Sabal)                \
2205  V(sabal2, Sabal2)              \
2206  V(sabd, Sabd)                  \
2207  V(sabdl, Sabdl)                \
2208  V(sabdl2, Sabdl2)              \
2209  V(saddl, Saddl)                \
2210  V(saddl2, Saddl2)              \
2211  V(saddw, Saddw)                \
2212  V(saddw2, Saddw2)              \
2213  V(shadd, Shadd)                \
2214  V(shsub, Shsub)                \
2215  V(smax, Smax)                  \
2216  V(smaxp, Smaxp)                \
2217  V(smin, Smin)                  \
2218  V(sminp, Sminp)                \
2219  V(smlal, Smlal)                \
2220  V(smlal2, Smlal2)              \
2221  V(smlsl, Smlsl)                \
2222  V(smlsl2, Smlsl2)              \
2223  V(smull, Smull)                \
2224  V(smull2, Smull2)              \
2225  V(sqadd, Sqadd)                \
2226  V(sqdmlal, Sqdmlal)            \
2227  V(sqdmlal2, Sqdmlal2)          \
2228  V(sqdmlsl, Sqdmlsl)            \
2229  V(sqdmlsl2, Sqdmlsl2)          \
2230  V(sqdmulh, Sqdmulh)            \
2231  V(sqdmull, Sqdmull)            \
2232  V(sqdmull2, Sqdmull2)          \
2233  V(sqrdmulh, Sqrdmulh)          \
2234  V(sqrshl, Sqrshl)              \
2235  V(sqshl, Sqshl)                \
2236  V(sqsub, Sqsub)                \
2237  V(srhadd, Srhadd)              \
2238  V(srshl, Srshl)                \
2239  V(sshl, Sshl)                  \
2240  V(ssubl, Ssubl)                \
2241  V(ssubl2, Ssubl2)              \
2242  V(ssubw, Ssubw)                \
2243  V(ssubw2, Ssubw2)              \
2244  V(sub, Sub)                    \
2245  V(subhn, Subhn)                \
2246  V(subhn2, Subhn2)              \
2247  V(trn1, Trn1)                  \
2248  V(trn2, Trn2)                  \
2249  V(uaba, Uaba)                  \
2250  V(uabal, Uabal)                \
2251  V(uabal2, Uabal2)              \
2252  V(uabd, Uabd)                  \
2253  V(uabdl, Uabdl)                \
2254  V(uabdl2, Uabdl2)              \
2255  V(uaddl, Uaddl)                \
2256  V(uaddl2, Uaddl2)              \
2257  V(uaddw, Uaddw)                \
2258  V(uaddw2, Uaddw2)              \
2259  V(uhadd, Uhadd)                \
2260  V(uhsub, Uhsub)                \
2261  V(umax, Umax)                  \
2262  V(umaxp, Umaxp)                \
2263  V(umin, Umin)                  \
2264  V(uminp, Uminp)                \
2265  V(umlal, Umlal)                \
2266  V(umlal2, Umlal2)              \
2267  V(umlsl, Umlsl)                \
2268  V(umlsl2, Umlsl2)              \
2269  V(umull, Umull)                \
2270  V(umull2, Umull2)              \
2271  V(uqadd, Uqadd)                \
2272  V(uqrshl, Uqrshl)              \
2273  V(uqshl, Uqshl)                \
2274  V(uqsub, Uqsub)                \
2275  V(urhadd, Urhadd)              \
2276  V(urshl, Urshl)                \
2277  V(ushl, Ushl)                  \
2278  V(usubl, Usubl)                \
2279  V(usubl2, Usubl2)              \
2280  V(usubw, Usubw)                \
2281  V(usubw2, Usubw2)              \
2282  V(uzp1, Uzp1)                  \
2283  V(uzp2, Uzp2)                  \
2284  V(zip1, Zip1)                  \
2285  V(zip2, Zip2)
2286
2287#define DEFINE_MACRO_ASM_FUNC(ASM, MASM)                                     \
2288  void MASM(const VRegister& vd, const VRegister& vn, const VRegister& vm) { \
2289    VIXL_ASSERT(allow_macro_instructions_);                                  \
2290    SingleEmissionCheckScope guard(this);                                    \
2291    ASM(vd, vn, vm);                                                         \
2292  }
2293  NEON_3VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
2294#undef DEFINE_MACRO_ASM_FUNC
2295
2296// NEON 2 vector register instructions.
2297#define NEON_2VREG_MACRO_LIST(V) \
2298  V(abs, Abs)                    \
2299  V(addp, Addp)                  \
2300  V(addv, Addv)                  \
2301  V(cls, Cls)                    \
2302  V(clz, Clz)                    \
2303  V(cnt, Cnt)                    \
2304  V(fabs, Fabs)                  \
2305  V(faddp, Faddp)                \
2306  V(fcvtas, Fcvtas)              \
2307  V(fcvtau, Fcvtau)              \
2308  V(fcvtms, Fcvtms)              \
2309  V(fcvtmu, Fcvtmu)              \
2310  V(fcvtns, Fcvtns)              \
2311  V(fcvtnu, Fcvtnu)              \
2312  V(fcvtps, Fcvtps)              \
2313  V(fcvtpu, Fcvtpu)              \
2314  V(fmaxnmp, Fmaxnmp)            \
2315  V(fmaxnmv, Fmaxnmv)            \
2316  V(fmaxp, Fmaxp)                \
2317  V(fmaxv, Fmaxv)                \
2318  V(fminnmp, Fminnmp)            \
2319  V(fminnmv, Fminnmv)            \
2320  V(fminp, Fminp)                \
2321  V(fminv, Fminv)                \
2322  V(fneg, Fneg)                  \
2323  V(frecpe, Frecpe)              \
2324  V(frecpx, Frecpx)              \
2325  V(frinta, Frinta)              \
2326  V(frinti, Frinti)              \
2327  V(frintm, Frintm)              \
2328  V(frintn, Frintn)              \
2329  V(frintp, Frintp)              \
2330  V(frintx, Frintx)              \
2331  V(frintz, Frintz)              \
2332  V(frsqrte, Frsqrte)            \
2333  V(fsqrt, Fsqrt)                \
2334  V(mov, Mov)                    \
2335  V(mvn, Mvn)                    \
2336  V(neg, Neg)                    \
2337  V(not_, Not)                   \
2338  V(rbit, Rbit)                  \
2339  V(rev16, Rev16)                \
2340  V(rev32, Rev32)                \
2341  V(rev64, Rev64)                \
2342  V(sadalp, Sadalp)              \
2343  V(saddlp, Saddlp)              \
2344  V(saddlv, Saddlv)              \
2345  V(smaxv, Smaxv)                \
2346  V(sminv, Sminv)                \
2347  V(sqabs, Sqabs)                \
2348  V(sqneg, Sqneg)                \
2349  V(sqxtn, Sqxtn)                \
2350  V(sqxtn2, Sqxtn2)              \
2351  V(sqxtun, Sqxtun)              \
2352  V(sqxtun2, Sqxtun2)            \
2353  V(suqadd, Suqadd)              \
2354  V(sxtl, Sxtl)                  \
2355  V(sxtl2, Sxtl2)                \
2356  V(uadalp, Uadalp)              \
2357  V(uaddlp, Uaddlp)              \
2358  V(uaddlv, Uaddlv)              \
2359  V(umaxv, Umaxv)                \
2360  V(uminv, Uminv)                \
2361  V(uqxtn, Uqxtn)                \
2362  V(uqxtn2, Uqxtn2)              \
2363  V(urecpe, Urecpe)              \
2364  V(ursqrte, Ursqrte)            \
2365  V(usqadd, Usqadd)              \
2366  V(uxtl, Uxtl)                  \
2367  V(uxtl2, Uxtl2)                \
2368  V(xtn, Xtn)                    \
2369  V(xtn2, Xtn2)
2370
2371#define DEFINE_MACRO_ASM_FUNC(ASM, MASM)                \
2372  void MASM(const VRegister& vd, const VRegister& vn) { \
2373    VIXL_ASSERT(allow_macro_instructions_);             \
2374    SingleEmissionCheckScope guard(this);               \
2375    ASM(vd, vn);                                        \
2376  }
2377  NEON_2VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
2378#undef DEFINE_MACRO_ASM_FUNC
2379
2380// NEON 2 vector register with immediate instructions.
2381#define NEON_2VREG_FPIMM_MACRO_LIST(V) \
2382  V(fcmeq, Fcmeq)                      \
2383  V(fcmge, Fcmge)                      \
2384  V(fcmgt, Fcmgt)                      \
2385  V(fcmle, Fcmle)                      \
2386  V(fcmlt, Fcmlt)
2387
2388#define DEFINE_MACRO_ASM_FUNC(ASM, MASM)                            \
2389  void MASM(const VRegister& vd, const VRegister& vn, double imm) { \
2390    VIXL_ASSERT(allow_macro_instructions_);                         \
2391    SingleEmissionCheckScope guard(this);                           \
2392    ASM(vd, vn, imm);                                               \
2393  }
2394  NEON_2VREG_FPIMM_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
2395#undef DEFINE_MACRO_ASM_FUNC
2396
2397// NEON by element instructions.
2398#define NEON_BYELEMENT_MACRO_LIST(V) \
2399  V(fmul, Fmul)                      \
2400  V(fmla, Fmla)                      \
2401  V(fmls, Fmls)                      \
2402  V(fmulx, Fmulx)                    \
2403  V(mul, Mul)                        \
2404  V(mla, Mla)                        \
2405  V(mls, Mls)                        \
2406  V(sqdmulh, Sqdmulh)                \
2407  V(sqrdmulh, Sqrdmulh)              \
2408  V(sqdmull, Sqdmull)                \
2409  V(sqdmull2, Sqdmull2)              \
2410  V(sqdmlal, Sqdmlal)                \
2411  V(sqdmlal2, Sqdmlal2)              \
2412  V(sqdmlsl, Sqdmlsl)                \
2413  V(sqdmlsl2, Sqdmlsl2)              \
2414  V(smull, Smull)                    \
2415  V(smull2, Smull2)                  \
2416  V(smlal, Smlal)                    \
2417  V(smlal2, Smlal2)                  \
2418  V(smlsl, Smlsl)                    \
2419  V(smlsl2, Smlsl2)                  \
2420  V(umull, Umull)                    \
2421  V(umull2, Umull2)                  \
2422  V(umlal, Umlal)                    \
2423  V(umlal2, Umlal2)                  \
2424  V(umlsl, Umlsl)                    \
2425  V(umlsl2, Umlsl2)
2426
2427#define DEFINE_MACRO_ASM_FUNC(ASM, MASM)    \
2428  void MASM(const VRegister& vd,            \
2429            const VRegister& vn,            \
2430            const VRegister& vm,            \
2431            int vm_index) {                 \
2432    VIXL_ASSERT(allow_macro_instructions_); \
2433    SingleEmissionCheckScope guard(this);   \
2434    ASM(vd, vn, vm, vm_index);              \
2435  }
2436  NEON_BYELEMENT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
2437#undef DEFINE_MACRO_ASM_FUNC
2438
2439#define NEON_2VREG_SHIFT_MACRO_LIST(V) \
2440  V(rshrn, Rshrn)                      \
2441  V(rshrn2, Rshrn2)                    \
2442  V(shl, Shl)                          \
2443  V(shll, Shll)                        \
2444  V(shll2, Shll2)                      \
2445  V(shrn, Shrn)                        \
2446  V(shrn2, Shrn2)                      \
2447  V(sli, Sli)                          \
2448  V(sqrshrn, Sqrshrn)                  \
2449  V(sqrshrn2, Sqrshrn2)                \
2450  V(sqrshrun, Sqrshrun)                \
2451  V(sqrshrun2, Sqrshrun2)              \
2452  V(sqshl, Sqshl)                      \
2453  V(sqshlu, Sqshlu)                    \
2454  V(sqshrn, Sqshrn)                    \
2455  V(sqshrn2, Sqshrn2)                  \
2456  V(sqshrun, Sqshrun)                  \
2457  V(sqshrun2, Sqshrun2)                \
2458  V(sri, Sri)                          \
2459  V(srshr, Srshr)                      \
2460  V(srsra, Srsra)                      \
2461  V(sshll, Sshll)                      \
2462  V(sshll2, Sshll2)                    \
2463  V(sshr, Sshr)                        \
2464  V(ssra, Ssra)                        \
2465  V(uqrshrn, Uqrshrn)                  \
2466  V(uqrshrn2, Uqrshrn2)                \
2467  V(uqshl, Uqshl)                      \
2468  V(uqshrn, Uqshrn)                    \
2469  V(uqshrn2, Uqshrn2)                  \
2470  V(urshr, Urshr)                      \
2471  V(ursra, Ursra)                      \
2472  V(ushll, Ushll)                      \
2473  V(ushll2, Ushll2)                    \
2474  V(ushr, Ushr)                        \
2475  V(usra, Usra)
2476
2477#define DEFINE_MACRO_ASM_FUNC(ASM, MASM)                           \
2478  void MASM(const VRegister& vd, const VRegister& vn, int shift) { \
2479    VIXL_ASSERT(allow_macro_instructions_);                        \
2480    SingleEmissionCheckScope guard(this);                          \
2481    ASM(vd, vn, shift);                                            \
2482  }
2483  NEON_2VREG_SHIFT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
2484#undef DEFINE_MACRO_ASM_FUNC
2485
2486  void Bic(const VRegister& vd, const int imm8, const int left_shift = 0) {
2487    VIXL_ASSERT(allow_macro_instructions_);
2488    SingleEmissionCheckScope guard(this);
2489    bic(vd, imm8, left_shift);
2490  }
2491  void Cmeq(const VRegister& vd, const VRegister& vn, int imm) {
2492    VIXL_ASSERT(allow_macro_instructions_);
2493    SingleEmissionCheckScope guard(this);
2494    cmeq(vd, vn, imm);
2495  }
2496  void Cmge(const VRegister& vd, const VRegister& vn, int imm) {
2497    VIXL_ASSERT(allow_macro_instructions_);
2498    SingleEmissionCheckScope guard(this);
2499    cmge(vd, vn, imm);
2500  }
2501  void Cmgt(const VRegister& vd, const VRegister& vn, int imm) {
2502    VIXL_ASSERT(allow_macro_instructions_);
2503    SingleEmissionCheckScope guard(this);
2504    cmgt(vd, vn, imm);
2505  }
2506  void Cmle(const VRegister& vd, const VRegister& vn, int imm) {
2507    VIXL_ASSERT(allow_macro_instructions_);
2508    SingleEmissionCheckScope guard(this);
2509    cmle(vd, vn, imm);
2510  }
2511  void Cmlt(const VRegister& vd, const VRegister& vn, int imm) {
2512    VIXL_ASSERT(allow_macro_instructions_);
2513    SingleEmissionCheckScope guard(this);
2514    cmlt(vd, vn, imm);
2515  }
2516  void Dup(const VRegister& vd, const VRegister& vn, int index) {
2517    VIXL_ASSERT(allow_macro_instructions_);
2518    SingleEmissionCheckScope guard(this);
2519    dup(vd, vn, index);
2520  }
2521  void Dup(const VRegister& vd, const Register& rn) {
2522    VIXL_ASSERT(allow_macro_instructions_);
2523    SingleEmissionCheckScope guard(this);
2524    dup(vd, rn);
2525  }
2526  void Ext(const VRegister& vd,
2527           const VRegister& vn,
2528           const VRegister& vm,
2529           int index) {
2530    VIXL_ASSERT(allow_macro_instructions_);
2531    SingleEmissionCheckScope guard(this);
2532    ext(vd, vn, vm, index);
2533  }
2534  void Ins(const VRegister& vd,
2535           int vd_index,
2536           const VRegister& vn,
2537           int vn_index) {
2538    VIXL_ASSERT(allow_macro_instructions_);
2539    SingleEmissionCheckScope guard(this);
2540    ins(vd, vd_index, vn, vn_index);
2541  }
2542  void Ins(const VRegister& vd, int vd_index, const Register& rn) {
2543    VIXL_ASSERT(allow_macro_instructions_);
2544    SingleEmissionCheckScope guard(this);
2545    ins(vd, vd_index, rn);
2546  }
2547  void Ld1(const VRegister& vt, const MemOperand& src) {
2548    VIXL_ASSERT(allow_macro_instructions_);
2549    SingleEmissionCheckScope guard(this);
2550    ld1(vt, src);
2551  }
2552  void Ld1(const VRegister& vt, const VRegister& vt2, const MemOperand& src) {
2553    VIXL_ASSERT(allow_macro_instructions_);
2554    SingleEmissionCheckScope guard(this);
2555    ld1(vt, vt2, src);
2556  }
2557  void Ld1(const VRegister& vt,
2558           const VRegister& vt2,
2559           const VRegister& vt3,
2560           const MemOperand& src) {
2561    VIXL_ASSERT(allow_macro_instructions_);
2562    SingleEmissionCheckScope guard(this);
2563    ld1(vt, vt2, vt3, src);
2564  }
2565  void Ld1(const VRegister& vt,
2566           const VRegister& vt2,
2567           const VRegister& vt3,
2568           const VRegister& vt4,
2569           const MemOperand& src) {
2570    VIXL_ASSERT(allow_macro_instructions_);
2571    SingleEmissionCheckScope guard(this);
2572    ld1(vt, vt2, vt3, vt4, src);
2573  }
2574  void Ld1(const VRegister& vt, int lane, const MemOperand& src) {
2575    VIXL_ASSERT(allow_macro_instructions_);
2576    SingleEmissionCheckScope guard(this);
2577    ld1(vt, lane, src);
2578  }
2579  void Ld1r(const VRegister& vt, const MemOperand& src) {
2580    VIXL_ASSERT(allow_macro_instructions_);
2581    SingleEmissionCheckScope guard(this);
2582    ld1r(vt, src);
2583  }
2584  void Ld2(const VRegister& vt, const VRegister& vt2, const MemOperand& src) {
2585    VIXL_ASSERT(allow_macro_instructions_);
2586    SingleEmissionCheckScope guard(this);
2587    ld2(vt, vt2, src);
2588  }
2589  void Ld2(const VRegister& vt,
2590           const VRegister& vt2,
2591           int lane,
2592           const MemOperand& src) {
2593    VIXL_ASSERT(allow_macro_instructions_);
2594    SingleEmissionCheckScope guard(this);
2595    ld2(vt, vt2, lane, src);
2596  }
2597  void Ld2r(const VRegister& vt, const VRegister& vt2, const MemOperand& src) {
2598    VIXL_ASSERT(allow_macro_instructions_);
2599    SingleEmissionCheckScope guard(this);
2600    ld2r(vt, vt2, src);
2601  }
2602  void Ld3(const VRegister& vt,
2603           const VRegister& vt2,
2604           const VRegister& vt3,
2605           const MemOperand& src) {
2606    VIXL_ASSERT(allow_macro_instructions_);
2607    SingleEmissionCheckScope guard(this);
2608    ld3(vt, vt2, vt3, src);
2609  }
2610  void Ld3(const VRegister& vt,
2611           const VRegister& vt2,
2612           const VRegister& vt3,
2613           int lane,
2614           const MemOperand& src) {
2615    VIXL_ASSERT(allow_macro_instructions_);
2616    SingleEmissionCheckScope guard(this);
2617    ld3(vt, vt2, vt3, lane, src);
2618  }
2619  void Ld3r(const VRegister& vt,
2620            const VRegister& vt2,
2621            const VRegister& vt3,
2622            const MemOperand& src) {
2623    VIXL_ASSERT(allow_macro_instructions_);
2624    SingleEmissionCheckScope guard(this);
2625    ld3r(vt, vt2, vt3, src);
2626  }
2627  void Ld4(const VRegister& vt,
2628           const VRegister& vt2,
2629           const VRegister& vt3,
2630           const VRegister& vt4,
2631           const MemOperand& src) {
2632    VIXL_ASSERT(allow_macro_instructions_);
2633    SingleEmissionCheckScope guard(this);
2634    ld4(vt, vt2, vt3, vt4, src);
2635  }
2636  void Ld4(const VRegister& vt,
2637           const VRegister& vt2,
2638           const VRegister& vt3,
2639           const VRegister& vt4,
2640           int lane,
2641           const MemOperand& src) {
2642    VIXL_ASSERT(allow_macro_instructions_);
2643    SingleEmissionCheckScope guard(this);
2644    ld4(vt, vt2, vt3, vt4, lane, src);
2645  }
2646  void Ld4r(const VRegister& vt,
2647            const VRegister& vt2,
2648            const VRegister& vt3,
2649            const VRegister& vt4,
2650            const MemOperand& src) {
2651    VIXL_ASSERT(allow_macro_instructions_);
2652    SingleEmissionCheckScope guard(this);
2653    ld4r(vt, vt2, vt3, vt4, src);
2654  }
2655  void Mov(const VRegister& vd,
2656           int vd_index,
2657           const VRegister& vn,
2658           int vn_index) {
2659    VIXL_ASSERT(allow_macro_instructions_);
2660    SingleEmissionCheckScope guard(this);
2661    mov(vd, vd_index, vn, vn_index);
2662  }
2663  void Mov(const VRegister& vd, const VRegister& vn, int index) {
2664    VIXL_ASSERT(allow_macro_instructions_);
2665    SingleEmissionCheckScope guard(this);
2666    mov(vd, vn, index);
2667  }
2668  void Mov(const VRegister& vd, int vd_index, const Register& rn) {
2669    VIXL_ASSERT(allow_macro_instructions_);
2670    SingleEmissionCheckScope guard(this);
2671    mov(vd, vd_index, rn);
2672  }
2673  void Mov(const Register& rd, const VRegister& vn, int vn_index) {
2674    VIXL_ASSERT(allow_macro_instructions_);
2675    SingleEmissionCheckScope guard(this);
2676    mov(rd, vn, vn_index);
2677  }
2678  void Movi(const VRegister& vd,
2679            uint64_t imm,
2680            Shift shift = LSL,
2681            int shift_amount = 0);
2682  void Movi(const VRegister& vd, uint64_t hi, uint64_t lo);
2683  void Mvni(const VRegister& vd,
2684            const int imm8,
2685            Shift shift = LSL,
2686            const int shift_amount = 0) {
2687    VIXL_ASSERT(allow_macro_instructions_);
2688    SingleEmissionCheckScope guard(this);
2689    mvni(vd, imm8, shift, shift_amount);
2690  }
2691  void Orr(const VRegister& vd, const int imm8, const int left_shift = 0) {
2692    VIXL_ASSERT(allow_macro_instructions_);
2693    SingleEmissionCheckScope guard(this);
2694    orr(vd, imm8, left_shift);
2695  }
2696  void Scvtf(const VRegister& vd, const VRegister& vn, int fbits = 0) {
2697    VIXL_ASSERT(allow_macro_instructions_);
2698    SingleEmissionCheckScope guard(this);
2699    scvtf(vd, vn, fbits);
2700  }
2701  void Ucvtf(const VRegister& vd, const VRegister& vn, int fbits = 0) {
2702    VIXL_ASSERT(allow_macro_instructions_);
2703    SingleEmissionCheckScope guard(this);
2704    ucvtf(vd, vn, fbits);
2705  }
2706  void Fcvtzs(const VRegister& vd, const VRegister& vn, int fbits = 0) {
2707    VIXL_ASSERT(allow_macro_instructions_);
2708    SingleEmissionCheckScope guard(this);
2709    fcvtzs(vd, vn, fbits);
2710  }
2711  void Fcvtzu(const VRegister& vd, const VRegister& vn, int fbits = 0) {
2712    VIXL_ASSERT(allow_macro_instructions_);
2713    SingleEmissionCheckScope guard(this);
2714    fcvtzu(vd, vn, fbits);
2715  }
2716  void St1(const VRegister& vt, const MemOperand& dst) {
2717    VIXL_ASSERT(allow_macro_instructions_);
2718    SingleEmissionCheckScope guard(this);
2719    st1(vt, dst);
2720  }
2721  void St1(const VRegister& vt, const VRegister& vt2, const MemOperand& dst) {
2722    VIXL_ASSERT(allow_macro_instructions_);
2723    SingleEmissionCheckScope guard(this);
2724    st1(vt, vt2, dst);
2725  }
2726  void St1(const VRegister& vt,
2727           const VRegister& vt2,
2728           const VRegister& vt3,
2729           const MemOperand& dst) {
2730    VIXL_ASSERT(allow_macro_instructions_);
2731    SingleEmissionCheckScope guard(this);
2732    st1(vt, vt2, vt3, dst);
2733  }
2734  void St1(const VRegister& vt,
2735           const VRegister& vt2,
2736           const VRegister& vt3,
2737           const VRegister& vt4,
2738           const MemOperand& dst) {
2739    VIXL_ASSERT(allow_macro_instructions_);
2740    SingleEmissionCheckScope guard(this);
2741    st1(vt, vt2, vt3, vt4, dst);
2742  }
2743  void St1(const VRegister& vt, int lane, const MemOperand& dst) {
2744    VIXL_ASSERT(allow_macro_instructions_);
2745    SingleEmissionCheckScope guard(this);
2746    st1(vt, lane, dst);
2747  }
2748  void St2(const VRegister& vt, const VRegister& vt2, const MemOperand& dst) {
2749    VIXL_ASSERT(allow_macro_instructions_);
2750    SingleEmissionCheckScope guard(this);
2751    st2(vt, vt2, dst);
2752  }
2753  void St3(const VRegister& vt,
2754           const VRegister& vt2,
2755           const VRegister& vt3,
2756           const MemOperand& dst) {
2757    VIXL_ASSERT(allow_macro_instructions_);
2758    SingleEmissionCheckScope guard(this);
2759    st3(vt, vt2, vt3, dst);
2760  }
2761  void St4(const VRegister& vt,
2762           const VRegister& vt2,
2763           const VRegister& vt3,
2764           const VRegister& vt4,
2765           const MemOperand& dst) {
2766    VIXL_ASSERT(allow_macro_instructions_);
2767    SingleEmissionCheckScope guard(this);
2768    st4(vt, vt2, vt3, vt4, dst);
2769  }
2770  void St2(const VRegister& vt,
2771           const VRegister& vt2,
2772           int lane,
2773           const MemOperand& dst) {
2774    VIXL_ASSERT(allow_macro_instructions_);
2775    SingleEmissionCheckScope guard(this);
2776    st2(vt, vt2, lane, dst);
2777  }
2778  void St3(const VRegister& vt,
2779           const VRegister& vt2,
2780           const VRegister& vt3,
2781           int lane,
2782           const MemOperand& dst) {
2783    VIXL_ASSERT(allow_macro_instructions_);
2784    SingleEmissionCheckScope guard(this);
2785    st3(vt, vt2, vt3, lane, dst);
2786  }
2787  void St4(const VRegister& vt,
2788           const VRegister& vt2,
2789           const VRegister& vt3,
2790           const VRegister& vt4,
2791           int lane,
2792           const MemOperand& dst) {
2793    VIXL_ASSERT(allow_macro_instructions_);
2794    SingleEmissionCheckScope guard(this);
2795    st4(vt, vt2, vt3, vt4, lane, dst);
2796  }
2797  void Smov(const Register& rd, const VRegister& vn, int vn_index) {
2798    VIXL_ASSERT(allow_macro_instructions_);
2799    SingleEmissionCheckScope guard(this);
2800    smov(rd, vn, vn_index);
2801  }
2802  void Umov(const Register& rd, const VRegister& vn, int vn_index) {
2803    VIXL_ASSERT(allow_macro_instructions_);
2804    SingleEmissionCheckScope guard(this);
2805    umov(rd, vn, vn_index);
2806  }
2807  void Crc32b(const Register& rd, const Register& rn, const Register& rm) {
2808    VIXL_ASSERT(allow_macro_instructions_);
2809    SingleEmissionCheckScope guard(this);
2810    crc32b(rd, rn, rm);
2811  }
2812  void Crc32h(const Register& rd, const Register& rn, const Register& rm) {
2813    VIXL_ASSERT(allow_macro_instructions_);
2814    SingleEmissionCheckScope guard(this);
2815    crc32h(rd, rn, rm);
2816  }
2817  void Crc32w(const Register& rd, const Register& rn, const Register& rm) {
2818    VIXL_ASSERT(allow_macro_instructions_);
2819    SingleEmissionCheckScope guard(this);
2820    crc32w(rd, rn, rm);
2821  }
2822  void Crc32x(const Register& rd, const Register& rn, const Register& rm) {
2823    VIXL_ASSERT(allow_macro_instructions_);
2824    SingleEmissionCheckScope guard(this);
2825    crc32x(rd, rn, rm);
2826  }
2827  void Crc32cb(const Register& rd, const Register& rn, const Register& rm) {
2828    VIXL_ASSERT(allow_macro_instructions_);
2829    SingleEmissionCheckScope guard(this);
2830    crc32cb(rd, rn, rm);
2831  }
2832  void Crc32ch(const Register& rd, const Register& rn, const Register& rm) {
2833    VIXL_ASSERT(allow_macro_instructions_);
2834    SingleEmissionCheckScope guard(this);
2835    crc32ch(rd, rn, rm);
2836  }
2837  void Crc32cw(const Register& rd, const Register& rn, const Register& rm) {
2838    VIXL_ASSERT(allow_macro_instructions_);
2839    SingleEmissionCheckScope guard(this);
2840    crc32cw(rd, rn, rm);
2841  }
2842  void Crc32cx(const Register& rd, const Register& rn, const Register& rm) {
2843    VIXL_ASSERT(allow_macro_instructions_);
2844    SingleEmissionCheckScope guard(this);
2845    crc32cx(rd, rn, rm);
2846  }
2847
2848  template <typename T>
2849  Literal<T>* CreateLiteralDestroyedWithPool(T value) {
2850    return new Literal<T>(value,
2851                          &literal_pool_,
2852                          RawLiteral::kDeletedOnPoolDestruction);
2853  }
2854
2855  template <typename T>
2856  Literal<T>* CreateLiteralDestroyedWithPool(T high64, T low64) {
2857    return new Literal<T>(high64,
2858                          low64,
2859                          &literal_pool_,
2860                          RawLiteral::kDeletedOnPoolDestruction);
2861  }
2862
2863  // Push the system stack pointer (sp) down to allow the same to be done to
2864  // the current stack pointer (according to StackPointer()). This must be
2865  // called _before_ accessing the memory.
2866  //
2867  // This is necessary when pushing or otherwise adding things to the stack, to
2868  // satisfy the AAPCS64 constraint that the memory below the system stack
2869  // pointer is not accessed.
2870  //
2871  // This method asserts that StackPointer() is not sp, since the call does
2872  // not make sense in that context.
2873  //
2874  // TODO: This method can only accept values of 'space' that can be encoded in
2875  // one instruction. Refer to the implementation for details.
2876  void BumpSystemStackPointer(const Operand& space);
2877
2878  virtual bool AllowMacroInstructions() const VIXL_OVERRIDE {
2879    return allow_macro_instructions_;
2880  }
2881
2882  virtual bool ArePoolsBlocked() const VIXL_OVERRIDE {
2883    return IsLiteralPoolBlocked() && IsVeneerPoolBlocked();
2884  }
2885
2886  void SetGenerateSimulatorCode(bool value) {
2887    generate_simulator_code_ = value;
2888  }
2889
2890  bool GenerateSimulatorCode() const { return generate_simulator_code_; }
2891
2892  size_t GetLiteralPoolSize() const { return literal_pool_.GetSize(); }
2893  VIXL_DEPRECATED("GetLiteralPoolSize", size_t LiteralPoolSize() const) {
2894    return GetLiteralPoolSize();
2895  }
2896
2897  size_t GetLiteralPoolMaxSize() const { return literal_pool_.GetMaxSize(); }
2898  VIXL_DEPRECATED("GetLiteralPoolMaxSize", size_t LiteralPoolMaxSize() const) {
2899    return GetLiteralPoolMaxSize();
2900  }
2901
2902  size_t GetVeneerPoolMaxSize() const { return veneer_pool_.GetMaxSize(); }
2903  VIXL_DEPRECATED("GetVeneerPoolMaxSize", size_t VeneerPoolMaxSize() const) {
2904    return GetVeneerPoolMaxSize();
2905  }
2906
2907  // The number of unresolved branches that may require a veneer.
2908  int GetNumberOfPotentialVeneers() const {
2909    return veneer_pool_.GetNumberOfPotentialVeneers();
2910  }
2911  VIXL_DEPRECATED("GetNumberOfPotentialVeneers",
2912                  int NumberOfPotentialVeneers() const) {
2913    return GetNumberOfPotentialVeneers();
2914  }
2915
2916  ptrdiff_t GetNextCheckPoint() const {
2917    ptrdiff_t next_checkpoint_for_pools =
2918        std::min(literal_pool_.GetCheckpoint(), veneer_pool_.GetCheckpoint());
2919    return std::min(next_checkpoint_for_pools,
2920                    static_cast<ptrdiff_t>(GetBuffer().GetCapacity()));
2921  }
2922  VIXL_DEPRECATED("GetNextCheckPoint", ptrdiff_t NextCheckPoint()) {
2923    return GetNextCheckPoint();
2924  }
2925
2926  void EmitLiteralPool(LiteralPool::EmitOption option) {
2927    if (!literal_pool_.IsEmpty()) literal_pool_.Emit(option);
2928
2929    checkpoint_ = GetNextCheckPoint();
2930    recommended_checkpoint_ = literal_pool_.GetNextRecommendedCheckpoint();
2931  }
2932
2933  void CheckEmitFor(size_t amount);
2934  void EnsureEmitFor(size_t amount) {
2935    ptrdiff_t offset = amount;
2936    ptrdiff_t max_pools_size =
2937        literal_pool_.GetMaxSize() + veneer_pool_.GetMaxSize();
2938    ptrdiff_t cursor = GetCursorOffset();
2939    if ((cursor >= recommended_checkpoint_) ||
2940        ((cursor + offset + max_pools_size) >= checkpoint_)) {
2941      CheckEmitFor(amount);
2942    }
2943  }
2944
2945  void CheckEmitPoolsFor(size_t amount);
2946  virtual void EnsureEmitPoolsFor(size_t amount) VIXL_OVERRIDE {
2947    ptrdiff_t offset = amount;
2948    ptrdiff_t max_pools_size =
2949        literal_pool_.GetMaxSize() + veneer_pool_.GetMaxSize();
2950    ptrdiff_t cursor = GetCursorOffset();
2951    if ((cursor >= recommended_checkpoint_) ||
2952        ((cursor + offset + max_pools_size) >= checkpoint_)) {
2953      CheckEmitPoolsFor(amount);
2954    }
2955  }
2956
2957  // Set the current stack pointer, but don't generate any code.
2958  void SetStackPointer(const Register& stack_pointer) {
2959    VIXL_ASSERT(!GetScratchRegisterList()->IncludesAliasOf(stack_pointer));
2960    sp_ = stack_pointer;
2961  }
2962
2963  // Return the current stack pointer, as set by SetStackPointer.
2964  const Register& StackPointer() const { return sp_; }
2965
2966  CPURegList* GetScratchRegisterList() { return &tmp_list_; }
2967  VIXL_DEPRECATED("GetScratchRegisterList", CPURegList* TmpList()) {
2968    return GetScratchRegisterList();
2969  }
2970
2971  CPURegList* GetScratchFPRegisterList() { return &fptmp_list_; }
2972  VIXL_DEPRECATED("GetScratchFPRegisterList", CPURegList* FPTmpList()) {
2973    return GetScratchFPRegisterList();
2974  }
2975
2976  // Get or set the current (most-deeply-nested) UseScratchRegisterScope.
2977  void SetCurrentScratchRegisterScope(UseScratchRegisterScope* scope) {
2978    current_scratch_scope_ = scope;
2979  }
2980  UseScratchRegisterScope* GetCurrentScratchRegisterScope() {
2981    return current_scratch_scope_;
2982  }
2983
2984  // Like printf, but print at run-time from generated code.
2985  //
2986  // The caller must ensure that arguments for floating-point placeholders
2987  // (such as %e, %f or %g) are VRegisters in format 1S or 1D, and that
2988  // arguments for integer placeholders are Registers.
2989  //
2990  // At the moment it is only possible to print the value of sp if it is the
2991  // current stack pointer. Otherwise, the MacroAssembler will automatically
2992  // update sp on every push (using BumpSystemStackPointer), so determining its
2993  // value is difficult.
2994  //
2995  // Format placeholders that refer to more than one argument, or to a specific
2996  // argument, are not supported. This includes formats like "%1$d" or "%.*d".
2997  //
2998  // This function automatically preserves caller-saved registers so that
2999  // calling code can use Printf at any point without having to worry about
3000  // corruption. The preservation mechanism generates a lot of code. If this is
3001  // a problem, preserve the important registers manually and then call
3002  // PrintfNoPreserve. Callee-saved registers are not used by Printf, and are
3003  // implicitly preserved.
3004  void Printf(const char* format,
3005              CPURegister arg0 = NoCPUReg,
3006              CPURegister arg1 = NoCPUReg,
3007              CPURegister arg2 = NoCPUReg,
3008              CPURegister arg3 = NoCPUReg);
3009
3010  // Like Printf, but don't preserve any caller-saved registers, not even 'lr'.
3011  //
3012  // The return code from the system printf call will be returned in x0.
3013  void PrintfNoPreserve(const char* format,
3014                        const CPURegister& arg0 = NoCPUReg,
3015                        const CPURegister& arg1 = NoCPUReg,
3016                        const CPURegister& arg2 = NoCPUReg,
3017                        const CPURegister& arg3 = NoCPUReg);
3018
3019  // Trace control when running the debug simulator.
3020  //
3021  // For example:
3022  //
3023  // __ Trace(LOG_REGS, TRACE_ENABLE);
3024  // Will add registers to the trace if it wasn't already the case.
3025  //
3026  // __ Trace(LOG_DISASM, TRACE_DISABLE);
3027  // Will stop logging disassembly. It has no effect if the disassembly wasn't
3028  // already being logged.
3029  void Trace(TraceParameters parameters, TraceCommand command);
3030
3031  // Log the requested data independently of what is being traced.
3032  //
3033  // For example:
3034  //
3035  // __ Log(LOG_FLAGS)
3036  // Will output the flags.
3037  void Log(TraceParameters parameters);
3038
3039  // Enable or disable instrumentation when an Instrument visitor is attached to
3040  // the simulator.
3041  void EnableInstrumentation();
3042  void DisableInstrumentation();
3043
3044  // Add a marker to the instrumentation data produced by an Instrument visitor.
3045  // The name is a two character string that will be attached to the marker in
3046  // the output data.
3047  void AnnotateInstrumentation(const char* marker_name);
3048
3049  LiteralPool* GetLiteralPool() { return &literal_pool_; }
3050
3051// Support for simulated runtime calls.
3052
3053// `CallRuntime` requires variadic templating, that is only available from
3054// C++11.
3055#if __cplusplus >= 201103L
3056#define VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT
3057#endif  // #if __cplusplus >= 201103L
3058
3059#ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT
3060  template <typename R, typename... P>
3061  void CallRuntimeHelper(R (*function)(P...), RuntimeCallType call_type);
3062
3063  template <typename R, typename... P>
3064  void CallRuntime(R (*function)(P...)) {
3065    CallRuntimeHelper(function, kCallRuntime);
3066  }
3067
3068  template <typename R, typename... P>
3069  void TailCallRuntime(R (*function)(P...)) {
3070    CallRuntimeHelper(function, kTailCallRuntime);
3071  }
3072#endif  // #ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT
3073
3074 protected:
3075  void BlockLiteralPool() { literal_pool_.Block(); }
3076  void ReleaseLiteralPool() { literal_pool_.Release(); }
3077  bool IsLiteralPoolBlocked() const { return literal_pool_.IsBlocked(); }
3078  void BlockVeneerPool() { veneer_pool_.Block(); }
3079  void ReleaseVeneerPool() { veneer_pool_.Release(); }
3080  bool IsVeneerPoolBlocked() const { return veneer_pool_.IsBlocked(); }
3081
3082  virtual void BlockPools() VIXL_OVERRIDE {
3083    BlockLiteralPool();
3084    BlockVeneerPool();
3085  }
3086
3087  virtual void ReleasePools() VIXL_OVERRIDE {
3088    ReleaseLiteralPool();
3089    ReleaseVeneerPool();
3090  }
3091
3092  // The scopes below need to able to block and release a particular pool.
3093  // TODO: Consider removing those scopes or move them to
3094  // code-generation-scopes-vixl.h.
3095  friend class BlockPoolsScope;
3096  friend class BlockLiteralPoolScope;
3097  friend class BlockVeneerPoolScope;
3098
3099  virtual void SetAllowMacroInstructions(bool value) VIXL_OVERRIDE {
3100    allow_macro_instructions_ = value;
3101  }
3102
3103  // Helper used to query information about code generation and to generate
3104  // code for `csel`.
3105  // Here and for the related helpers below:
3106  // - Code is generated when `masm` is not `NULL`.
3107  // - On return and when set, `should_synthesise_left` and
3108  //   `should_synthesise_right` will indicate whether `left` and `right`
3109  //   should be synthesized in a temporary register.
3110  static void CselHelper(MacroAssembler* masm,
3111                         const Register& rd,
3112                         Operand left,
3113                         Operand right,
3114                         Condition cond,
3115                         bool* should_synthesise_left = NULL,
3116                         bool* should_synthesise_right = NULL);
3117
3118  // The helper returns `true` if it can handle the specified arguments.
3119  // Also see comments for `CselHelper()`.
3120  static bool CselSubHelperTwoImmediates(MacroAssembler* masm,
3121                                         const Register& rd,
3122                                         int64_t left,
3123                                         int64_t right,
3124                                         Condition cond,
3125                                         bool* should_synthesise_left,
3126                                         bool* should_synthesise_right);
3127
3128  // See comments for `CselHelper()`.
3129  static bool CselSubHelperTwoOrderedImmediates(MacroAssembler* masm,
3130                                                const Register& rd,
3131                                                int64_t left,
3132                                                int64_t right,
3133                                                Condition cond);
3134
3135  // See comments for `CselHelper()`.
3136  static void CselSubHelperRightSmallImmediate(MacroAssembler* masm,
3137                                               UseScratchRegisterScope* temps,
3138                                               const Register& rd,
3139                                               const Operand& left,
3140                                               const Operand& right,
3141                                               Condition cond,
3142                                               bool* should_synthesise_left);
3143
3144 private:
3145  // The actual Push and Pop implementations. These don't generate any code
3146  // other than that required for the push or pop. This allows
3147  // (Push|Pop)CPURegList to bundle together setup code for a large block of
3148  // registers.
3149  //
3150  // Note that size is per register, and is specified in bytes.
3151  void PushHelper(int count,
3152                  int size,
3153                  const CPURegister& src0,
3154                  const CPURegister& src1,
3155                  const CPURegister& src2,
3156                  const CPURegister& src3);
3157  void PopHelper(int count,
3158                 int size,
3159                 const CPURegister& dst0,
3160                 const CPURegister& dst1,
3161                 const CPURegister& dst2,
3162                 const CPURegister& dst3);
3163
3164  void Movi16bitHelper(const VRegister& vd, uint64_t imm);
3165  void Movi32bitHelper(const VRegister& vd, uint64_t imm);
3166  void Movi64bitHelper(const VRegister& vd, uint64_t imm);
3167
3168  // Perform necessary maintenance operations before a push or pop.
3169  //
3170  // Note that size is per register, and is specified in bytes.
3171  void PrepareForPush(int count, int size);
3172  void PrepareForPop(int count, int size);
3173
3174  // The actual implementation of load and store operations for CPURegList.
3175  enum LoadStoreCPURegListAction { kLoad, kStore };
3176  void LoadStoreCPURegListHelper(LoadStoreCPURegListAction operation,
3177                                 CPURegList registers,
3178                                 const MemOperand& mem);
3179  // Returns a MemOperand suitable for loading or storing a CPURegList at `dst`.
3180  // This helper may allocate registers from `scratch_scope` and generate code
3181  // to compute an intermediate address. The resulting MemOperand is only valid
3182  // as long as `scratch_scope` remains valid.
3183  MemOperand BaseMemOperandForLoadStoreCPURegList(
3184      const CPURegList& registers,
3185      const MemOperand& mem,
3186      UseScratchRegisterScope* scratch_scope);
3187
3188  bool LabelIsOutOfRange(Label* label, ImmBranchType branch_type) {
3189    return !Instruction::IsValidImmPCOffset(branch_type,
3190                                            label->GetLocation() -
3191                                                GetCursorOffset());
3192  }
3193
3194  // Tell whether any of the macro instruction can be used. When false the
3195  // MacroAssembler will assert if a method which can emit a variable number
3196  // of instructions is called.
3197  bool allow_macro_instructions_;
3198
3199  // Indicates whether we should generate simulator or native code.
3200  bool generate_simulator_code_;
3201
3202  // The register to use as a stack pointer for stack operations.
3203  Register sp_;
3204
3205  // Scratch registers available for use by the MacroAssembler.
3206  CPURegList tmp_list_;
3207  CPURegList fptmp_list_;
3208
3209  UseScratchRegisterScope* current_scratch_scope_;
3210
3211  LiteralPool literal_pool_;
3212  VeneerPool veneer_pool_;
3213
3214  ptrdiff_t checkpoint_;
3215  ptrdiff_t recommended_checkpoint_;
3216
3217  friend class Pool;
3218  friend class LiteralPool;
3219};
3220
3221
3222inline size_t VeneerPool::GetOtherPoolsMaxSize() const {
3223  return masm_->GetLiteralPoolMaxSize();
3224}
3225
3226
3227inline size_t LiteralPool::GetOtherPoolsMaxSize() const {
3228  return masm_->GetVeneerPoolMaxSize();
3229}
3230
3231
3232inline void LiteralPool::SetNextRecommendedCheckpoint(ptrdiff_t offset) {
3233  masm_->recommended_checkpoint_ =
3234      std::min(masm_->recommended_checkpoint_, offset);
3235  recommended_checkpoint_ = offset;
3236}
3237
3238class InstructionAccurateScope : public ExactAssemblyScope {
3239 public:
3240  VIXL_DEPRECATED("ExactAssemblyScope",
3241                  InstructionAccurateScope(MacroAssembler* masm,
3242                                           int64_t count,
3243                                           SizePolicy size_policy = kExactSize))
3244      : ExactAssemblyScope(masm, count * kInstructionSize, size_policy) {}
3245};
3246
3247class BlockLiteralPoolScope {
3248 public:
3249  explicit BlockLiteralPoolScope(MacroAssembler* masm) : masm_(masm) {
3250    masm_->BlockLiteralPool();
3251  }
3252
3253  ~BlockLiteralPoolScope() { masm_->ReleaseLiteralPool(); }
3254
3255 private:
3256  MacroAssembler* masm_;
3257};
3258
3259
3260class BlockVeneerPoolScope {
3261 public:
3262  explicit BlockVeneerPoolScope(MacroAssembler* masm) : masm_(masm) {
3263    masm_->BlockVeneerPool();
3264  }
3265
3266  ~BlockVeneerPoolScope() { masm_->ReleaseVeneerPool(); }
3267
3268 private:
3269  MacroAssembler* masm_;
3270};
3271
3272
3273class BlockPoolsScope {
3274 public:
3275  explicit BlockPoolsScope(MacroAssembler* masm) : masm_(masm) {
3276    masm_->BlockPools();
3277  }
3278
3279  ~BlockPoolsScope() { masm_->ReleasePools(); }
3280
3281 private:
3282  MacroAssembler* masm_;
3283};
3284
3285
3286// This scope utility allows scratch registers to be managed safely. The
3287// MacroAssembler's GetScratchRegisterList() (and GetScratchFPRegisterList()) is
3288// used as a pool of scratch registers. These registers can be allocated on
3289// demand, and will be returned at the end of the scope.
3290//
3291// When the scope ends, the MacroAssembler's lists will be restored to their
3292// original state, even if the lists were modified by some other means.
3293class UseScratchRegisterScope {
3294 public:
3295  // This constructor implicitly calls `Open` to initialise the scope (`masm`
3296  // must not be `NULL`), so it is ready to use immediately after it has been
3297  // constructed.
3298  explicit UseScratchRegisterScope(MacroAssembler* masm)
3299      : masm_(NULL), parent_(NULL), old_available_(0), old_availablefp_(0) {
3300    Open(masm);
3301  }
3302  // This constructor does not implicitly initialise the scope. Instead, the
3303  // user is required to explicitly call the `Open` function before using the
3304  // scope.
3305  UseScratchRegisterScope()
3306      : masm_(NULL), parent_(NULL), old_available_(0), old_availablefp_(0) {}
3307
3308  // This function performs the actual initialisation work.
3309  void Open(MacroAssembler* masm);
3310
3311  // The destructor always implicitly calls the `Close` function.
3312  ~UseScratchRegisterScope() { Close(); }
3313
3314  // This function performs the cleaning-up work. It must succeed even if the
3315  // scope has not been opened. It is safe to call multiple times.
3316  void Close();
3317
3318
3319  bool IsAvailable(const CPURegister& reg) const;
3320
3321
3322  // Take a register from the appropriate temps list. It will be returned
3323  // automatically when the scope ends.
3324  Register AcquireW() {
3325    return AcquireNextAvailable(masm_->GetScratchRegisterList()).W();
3326  }
3327  Register AcquireX() {
3328    return AcquireNextAvailable(masm_->GetScratchRegisterList()).X();
3329  }
3330  VRegister AcquireS() {
3331    return AcquireNextAvailable(masm_->GetScratchFPRegisterList()).S();
3332  }
3333  VRegister AcquireD() {
3334    return AcquireNextAvailable(masm_->GetScratchFPRegisterList()).D();
3335  }
3336
3337
3338  Register AcquireRegisterOfSize(int size_in_bits);
3339  Register AcquireSameSizeAs(const Register& reg) {
3340    return AcquireRegisterOfSize(reg.GetSizeInBits());
3341  }
3342  VRegister AcquireVRegisterOfSize(int size_in_bits);
3343  VRegister AcquireSameSizeAs(const VRegister& reg) {
3344    return AcquireVRegisterOfSize(reg.GetSizeInBits());
3345  }
3346  CPURegister AcquireCPURegisterOfSize(int size_in_bits) {
3347    return masm_->GetScratchRegisterList()->IsEmpty()
3348               ? CPURegister(AcquireVRegisterOfSize(size_in_bits))
3349               : CPURegister(AcquireRegisterOfSize(size_in_bits));
3350  }
3351
3352
3353  // Explicitly release an acquired (or excluded) register, putting it back in
3354  // the appropriate temps list.
3355  void Release(const CPURegister& reg);
3356
3357
3358  // Make the specified registers available as scratch registers for the
3359  // duration of this scope.
3360  void Include(const CPURegList& list);
3361  void Include(const Register& reg1,
3362               const Register& reg2 = NoReg,
3363               const Register& reg3 = NoReg,
3364               const Register& reg4 = NoReg);
3365  void Include(const VRegister& reg1,
3366               const VRegister& reg2 = NoVReg,
3367               const VRegister& reg3 = NoVReg,
3368               const VRegister& reg4 = NoVReg);
3369
3370
3371  // Make sure that the specified registers are not available in this scope.
3372  // This can be used to prevent helper functions from using sensitive
3373  // registers, for example.
3374  void Exclude(const CPURegList& list);
3375  void Exclude(const Register& reg1,
3376               const Register& reg2 = NoReg,
3377               const Register& reg3 = NoReg,
3378               const Register& reg4 = NoReg);
3379  void Exclude(const VRegister& reg1,
3380               const VRegister& reg2 = NoVReg,
3381               const VRegister& reg3 = NoVReg,
3382               const VRegister& reg4 = NoVReg);
3383  void Exclude(const CPURegister& reg1,
3384               const CPURegister& reg2 = NoCPUReg,
3385               const CPURegister& reg3 = NoCPUReg,
3386               const CPURegister& reg4 = NoCPUReg);
3387
3388
3389  // Prevent any scratch registers from being used in this scope.
3390  void ExcludeAll();
3391
3392 private:
3393  static CPURegister AcquireNextAvailable(CPURegList* available);
3394
3395  static void ReleaseByCode(CPURegList* available, int code);
3396
3397  static void ReleaseByRegList(CPURegList* available, RegList regs);
3398
3399  static void IncludeByRegList(CPURegList* available, RegList exclude);
3400
3401  static void ExcludeByRegList(CPURegList* available, RegList exclude);
3402
3403  // The MacroAssembler maintains a list of available scratch registers, and
3404  // also keeps track of the most recently-opened scope so that on destruction
3405  // we can check that scopes do not outlive their parents.
3406  MacroAssembler* masm_;
3407  UseScratchRegisterScope* parent_;
3408
3409  // The state of the available lists at the start of this scope.
3410  RegList old_available_;    // kRegister
3411  RegList old_availablefp_;  // kVRegister
3412
3413  // Disallow copy constructor and operator=.
3414  VIXL_DEBUG_NO_RETURN UseScratchRegisterScope(const UseScratchRegisterScope&) {
3415    VIXL_UNREACHABLE();
3416  }
3417  VIXL_DEBUG_NO_RETURN void operator=(const UseScratchRegisterScope&) {
3418    VIXL_UNREACHABLE();
3419  }
3420};
3421
3422// Variadic templating is only available from C++11.
3423#ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT
3424
3425// `R` stands for 'return type', and `P` for 'parameter types'.
3426template <typename R, typename... P>
3427void MacroAssembler::CallRuntimeHelper(R (*function)(P...),
3428                                       RuntimeCallType call_type) {
3429  if (generate_simulator_code_) {
3430#ifdef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
3431    uintptr_t runtime_call_wrapper_address = reinterpret_cast<uintptr_t>(
3432        &(Simulator::RuntimeCallStructHelper<R, P...>::Wrapper));
3433    uintptr_t function_address = reinterpret_cast<uintptr_t>(function);
3434
3435    EmissionCheckScope guard(this,
3436                             kRuntimeCallLength,
3437                             CodeBufferCheckScope::kExactSize);
3438    Label start;
3439    bind(&start);
3440    {
3441      ExactAssemblyScope scope(this, kInstructionSize);
3442      hlt(kRuntimeCallOpcode);
3443    }
3444    VIXL_ASSERT(GetSizeOfCodeGeneratedSince(&start) ==
3445                kRuntimeCallWrapperOffset);
3446    dc(runtime_call_wrapper_address);
3447    VIXL_ASSERT(GetSizeOfCodeGeneratedSince(&start) ==
3448                kRuntimeCallFunctionOffset);
3449    dc(function_address);
3450    VIXL_ASSERT(GetSizeOfCodeGeneratedSince(&start) == kRuntimeCallTypeOffset);
3451    dc32(call_type);
3452    VIXL_ASSERT(GetSizeOfCodeGeneratedSince(&start) == kRuntimeCallLength);
3453#else
3454    VIXL_UNREACHABLE();
3455#endif  // #ifdef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
3456  } else {
3457    UseScratchRegisterScope temps(this);
3458    Register temp = temps.AcquireX();
3459    Mov(temp, reinterpret_cast<uint64_t>(function));
3460    if (call_type == kTailCallRuntime) {
3461      Br(temp);
3462    } else {
3463      VIXL_ASSERT(call_type == kCallRuntime);
3464      Blr(temp);
3465    }
3466  }
3467}
3468
3469#endif  // #ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT
3470
3471}  // namespace aarch64
3472
3473// Required InvalSet template specialisations.
3474// TODO: These template specialisations should not live in this file.  Move
3475// VeneerPool out of the aarch64 namespace in order to share its implementation
3476// later.
3477template <>
3478inline ptrdiff_t InvalSet<aarch64::VeneerPool::BranchInfo,
3479                          aarch64::VeneerPool::kNPreallocatedInfos,
3480                          ptrdiff_t,
3481                          aarch64::VeneerPool::kInvalidOffset,
3482                          aarch64::VeneerPool::kReclaimFrom,
3483                          aarch64::VeneerPool::kReclaimFactor>::
3484    GetKey(const aarch64::VeneerPool::BranchInfo& branch_info) {
3485  return branch_info.first_unreacheable_pc_;
3486}
3487template <>
3488inline void InvalSet<aarch64::VeneerPool::BranchInfo,
3489                     aarch64::VeneerPool::kNPreallocatedInfos,
3490                     ptrdiff_t,
3491                     aarch64::VeneerPool::kInvalidOffset,
3492                     aarch64::VeneerPool::kReclaimFrom,
3493                     aarch64::VeneerPool::kReclaimFactor>::
3494    SetKey(aarch64::VeneerPool::BranchInfo* branch_info, ptrdiff_t key) {
3495  branch_info->first_unreacheable_pc_ = key;
3496}
3497
3498}  // namespace vixl
3499
3500#endif  // VIXL_AARCH64_MACRO_ASSEMBLER_AARCH64_H_
3501