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