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