1ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Copyright 2013, ARM Limited
2ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// All rights reserved.
3ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
4ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Redistribution and use in source and binary forms, with or without
5ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// modification, are permitted provided that the following conditions are met:
6ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
7ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Redistributions of source code must retain the above copyright notice,
8ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     this list of conditions and the following disclaimer.
9ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Redistributions in binary form must reproduce the above copyright notice,
10ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     this list of conditions and the following disclaimer in the documentation
11ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     and/or other materials provided with the distribution.
12ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Neither the name of ARM Limited nor the names of its contributors may be
13ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     used to endorse or promote products derived from this software without
14ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     specific prior written permission.
15ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
16ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
27ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifndef VIXL_A64_MACRO_ASSEMBLER_A64_H_
28ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define VIXL_A64_MACRO_ASSEMBLER_A64_H_
29ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
30bc4afbd2754e20d14114e4ba83f9035b26ab701dSerban Constantinescu#include "globals-vixl.h"
31ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "a64/assembler-a64.h"
32ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "a64/debugger-a64.h"
33ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
35ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define LS_MACRO_LIST(V)                                      \
36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  V(Ldrb, Register&, rt, LDRB_w)                              \
37ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  V(Strb, Register&, rt, STRB_w)                              \
38ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  V(Ldrsb, Register&, rt, rt.Is64Bits() ? LDRSB_x : LDRSB_w)  \
39ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  V(Ldrh, Register&, rt, LDRH_w)                              \
40ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  V(Strh, Register&, rt, STRH_w)                              \
41ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  V(Ldrsh, Register&, rt, rt.Is64Bits() ? LDRSH_x : LDRSH_w)  \
42ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  V(Ldr, CPURegister&, rt, LoadOpFor(rt))                     \
43ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  V(Str, CPURegister&, rt, StoreOpFor(rt))                    \
44ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  V(Ldrsw, Register&, rt, LDRSW_x)
45ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
46ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace vixl {
47ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixlenum BranchType {
491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // Copies of architectural conditions.
501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // The associated conditions can be used in place of those, the code will
511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // take care of reinterpreting them with the correct type.
521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_eq = eq,
531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_ne = ne,
541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_hs = hs,
551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_lo = lo,
561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_mi = mi,
571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_pl = pl,
581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_vs = vs,
591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_vc = vc,
601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_hi = hi,
611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_ls = ls,
621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_ge = ge,
631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_lt = lt,
641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_gt = gt,
651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_le = le,
661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_al = al,
671123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  integer_nv = nv,
681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // These two are *different* from the architectural codes al and nv.
701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // 'always' is used to generate unconditional branches.
711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // 'never' is used to not generate a branch (generally as the inverse
721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // branch type of 'always).
731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  always, never,
741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // cbz and cbnz
751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  reg_zero, reg_not_zero,
761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // tbz and tbnz
771123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  reg_bit_clear, reg_bit_set,
781123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // Aliases.
801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  kBranchTypeFirstCondition = eq,
811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  kBranchTypeLastCondition = nv,
821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  kBranchTypeFirstUsingReg = reg_zero,
831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  kBranchTypeFirstUsingBit = reg_bit_clear
841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl};
851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
87f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlenum DiscardMoveMode { kDontDiscardForSameWReg, kDiscardForSameWReg };
88f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
89ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass MacroAssembler : public Assembler {
90ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
91ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  MacroAssembler(byte * buffer, unsigned buffer_size)
92ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      : Assembler(buffer, buffer_size),
93ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifdef DEBUG
94ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        allow_macro_instructions_(true),
95ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif
961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl        sp_(sp), tmp_list_(ip0, ip1), fptmp_list_(d31) {}
97ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
98ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Logical macros.
99ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void And(const Register& rd,
100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Register& rn,
101f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl           const Operand& operand);
102f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Ands(const Register& rd,
103f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Register& rn,
104f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Operand& operand);
105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Bic(const Register& rd,
106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Register& rn,
107f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl           const Operand& operand);
108f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Bics(const Register& rd,
109f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Register& rn,
110f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Operand& operand);
111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Orr(const Register& rd,
112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Register& rn,
113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Operand& operand);
114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Orn(const Register& rd,
115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Register& rn,
116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Operand& operand);
117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Eor(const Register& rd,
118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Register& rn,
119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Operand& operand);
120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Eon(const Register& rd,
121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Register& rn,
122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Operand& operand);
123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Tst(const Register& rn, const Operand& operand);
124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void LogicalMacro(const Register& rd,
125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn,
126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Operand& operand,
127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    LogicalOp op);
128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Add and sub macros.
130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Add(const Register& rd,
131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Register& rn,
132f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl           const Operand& operand);
133f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Adds(const Register& rd,
134f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Register& rn,
135f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Operand& operand);
136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Sub(const Register& rd,
137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Register& rn,
138f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl           const Operand& operand);
139f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Subs(const Register& rd,
140f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Register& rn,
141f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Operand& operand);
142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Cmn(const Register& rn, const Operand& operand);
143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Cmp(const Register& rn, const Operand& operand);
144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Neg(const Register& rd,
145f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl           const Operand& operand);
146f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Negs(const Register& rd,
147f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Operand& operand);
148f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void AddSubMacro(const Register& rd,
150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                   const Register& rn,
151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                   const Operand& operand,
152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                   FlagsUpdate S,
153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                   AddSubOp op);
154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Add/sub with carry macros.
156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Adc(const Register& rd,
157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Register& rn,
158f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl           const Operand& operand);
159f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Adcs(const Register& rd,
160f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Register& rn,
161f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Operand& operand);
162ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Sbc(const Register& rd,
163ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Register& rn,
164f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl           const Operand& operand);
165f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Sbcs(const Register& rd,
166f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Register& rn,
167f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Operand& operand);
168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ngc(const Register& rd,
169f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl           const Operand& operand);
170f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Ngcs(const Register& rd,
171f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Operand& operand);
172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void AddSubWithCarryMacro(const Register& rd,
173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                            const Register& rn,
174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                            const Operand& operand,
175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                            FlagsUpdate S,
176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                            AddSubWithCarryOp op);
177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
178ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Move macros.
179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Mov(const Register& rd, uint64_t imm);
180f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Mov(const Register& rd,
181f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl           const Operand& operand,
182f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl           DiscardMoveMode discard_mode = kDontDiscardForSameWReg);
183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Mvn(const Register& rd, uint64_t imm) {
184f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    Mov(rd, (rd.size() == kXRegSize) ? ~imm : (~imm & kWRegMask));
185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  };
186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Mvn(const Register& rd, const Operand& operand);
187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bool IsImmMovz(uint64_t imm, unsigned reg_size);
188f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  bool IsImmMovn(uint64_t imm, unsigned reg_size);
189f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  unsigned CountClearHalfWords(uint64_t imm, unsigned reg_size);
190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
191f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  // Conditional macros.
192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ccmp(const Register& rn,
193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const Operand& operand,
194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            StatusFlags nzcv,
195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            Condition cond);
196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ccmn(const Register& rn,
197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const Operand& operand,
198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            StatusFlags nzcv,
199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            Condition cond);
200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void ConditionalCompareMacro(const Register& rn,
201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                               const Operand& operand,
202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                               StatusFlags nzcv,
203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                               Condition cond,
204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                               ConditionalCompareOp op);
205f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Csel(const Register& rd,
206f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Register& rn,
207f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            const Operand& operand,
208f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl            Condition cond);
209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Load/store macros.
211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define DECLARE_FUNCTION(FN, REGTYPE, REG, OP) \
212ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void FN(const REGTYPE REG, const MemOperand& addr);
213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LS_MACRO_LIST(DECLARE_FUNCTION)
214ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#undef DECLARE_FUNCTION
215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void LoadStoreMacro(const CPURegister& rt,
217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const MemOperand& addr,
218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      LoadStoreOp op);
219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Push or pop up to 4 registers of the same width to or from the stack,
221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // using the current stack pointer as set by SetStackPointer.
222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // If an argument register is 'NoReg', all further arguments are also assumed
224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // to be 'NoReg', and are thus not pushed or popped.
225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Arguments are ordered such that "Push(a, b);" is functionally equivalent
227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // to "Push(a); Push(b);".
228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // It is valid to push the same register more than once, and there is no
230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // restriction on the order in which registers are specified.
231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // It is not valid to pop into the same register more than once in one
233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // operation, not even into the zero register.
234ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // If the current stack pointer (as set by SetStackPointer) is sp, then it
236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // must be aligned to 16 bytes on entry and the total size of the specified
237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // registers must also be a multiple of 16 bytes.
238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Even if the current stack pointer is not the system stack pointer (sp),
240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Push (and derived methods) will still modify the system stack pointer in
241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // order to comply with ABI rules about accessing memory below the system
242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // stack pointer.
243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Other than the registers passed into Pop, the stack pointer and (possibly)
245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // the system stack pointer, these methods do not modify any other registers.
246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Push(const CPURegister& src0, const CPURegister& src1 = NoReg,
247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const CPURegister& src2 = NoReg, const CPURegister& src3 = NoReg);
248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Pop(const CPURegister& dst0, const CPURegister& dst1 = NoReg,
249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const CPURegister& dst2 = NoReg, const CPURegister& dst3 = NoReg);
250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Alternative forms of Push and Pop, taking a RegList or CPURegList that
252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // specifies the registers that are to be pushed or popped. Higher-numbered
253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // registers are associated with higher memory addresses (as in the A32 push
254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // and pop instructions).
255ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // (Push|Pop)SizeRegList allow you to specify the register size as a
257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // parameter. Only kXRegSize, kWRegSize, kDRegSize and kSRegSize are
258ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // supported.
259ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Otherwise, (Push|Pop)(CPU|X|W|D|S)RegList is preferred.
261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PushCPURegList(CPURegList registers);
262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PopCPURegList(CPURegList registers);
263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PushSizeRegList(RegList registers, unsigned reg_size,
265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      CPURegister::RegisterType type = CPURegister::kRegister) {
266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    PushCPURegList(CPURegList(type, reg_size, registers));
267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PopSizeRegList(RegList registers, unsigned reg_size,
269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      CPURegister::RegisterType type = CPURegister::kRegister) {
270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    PopCPURegList(CPURegList(type, reg_size, registers));
271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PushXRegList(RegList regs) {
273ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    PushSizeRegList(regs, kXRegSize);
274ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
275ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PopXRegList(RegList regs) {
276ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    PopSizeRegList(regs, kXRegSize);
277ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PushWRegList(RegList regs) {
279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    PushSizeRegList(regs, kWRegSize);
280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PopWRegList(RegList regs) {
282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    PopSizeRegList(regs, kWRegSize);
283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
284ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline void PushDRegList(RegList regs) {
285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    PushSizeRegList(regs, kDRegSize, CPURegister::kFPRegister);
286ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline void PopDRegList(RegList regs) {
288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    PopSizeRegList(regs, kDRegSize, CPURegister::kFPRegister);
289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline void PushSRegList(RegList regs) {
291ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    PushSizeRegList(regs, kSRegSize, CPURegister::kFPRegister);
292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
293ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline void PopSRegList(RegList regs) {
294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    PopSizeRegList(regs, kSRegSize, CPURegister::kFPRegister);
295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
296ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
297ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Push the specified register 'count' times.
298ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PushMultipleTimes(int count, Register src);
299ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
300ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Poke 'src' onto the stack. The offset is in bytes.
301ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
302ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // If the current stack pointer (as set by SetStackPointer) is sp, then sp
303ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // must be aligned to 16 bytes.
304ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Poke(const Register& src, const Operand& offset);
305ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
306ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Peek at a value on the stack, and put it in 'dst'. The offset is in bytes.
307ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
308ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // If the current stack pointer (as set by SetStackPointer) is sp, then sp
309ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // must be aligned to 16 bytes.
310ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Peek(const Register& dst, const Operand& offset);
311ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
312ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Claim or drop stack space without actually accessing memory.
313ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
314ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // If the current stack pointer (as set by SetStackPointer) is sp, then it
315ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // must be aligned to 16 bytes and the size claimed or dropped must be a
316ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // multiple of 16 bytes.
317ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Claim(const Operand& size);
318ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Drop(const Operand& size);
319ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
320ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Preserve the callee-saved registers (as defined by AAPCS64).
321ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
322ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Higher-numbered registers are pushed before lower-numbered registers, and
323ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // thus get higher addresses.
324ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Floating-point registers are pushed before general-purpose registers, and
325ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // thus get higher addresses.
326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
327ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // This method must not be called unless StackPointer() is sp, and it is
328ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // aligned to 16 bytes.
329ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PushCalleeSavedRegisters();
330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Restore the callee-saved registers (as defined by AAPCS64).
332ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
333ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Higher-numbered registers are popped after lower-numbered registers, and
334ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // thus come from higher addresses.
335ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Floating-point registers are popped after general-purpose registers, and
336ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // thus come from higher addresses.
337ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
338ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // This method must not be called unless StackPointer() is sp, and it is
339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // aligned to 16 bytes.
340ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PopCalleeSavedRegisters();
341ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
342ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Remaining instructions are simple pass-through calls to the assembler.
343ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Adr(const Register& rd, Label* label) {
3441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
3451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
346ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    adr(rd, label);
347ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
348ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Asr(const Register& rd, const Register& rn, unsigned shift) {
3491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
3501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
3511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
352ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    asr(rd, rn, shift);
353ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Asr(const Register& rd, const Register& rn, const Register& rm) {
3551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
3561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
3571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
3581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
359ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    asrv(rd, rn, rm);
360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
3611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
3621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // Branch type inversion relies on these relations.
3631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_STATIC_ASSERT((reg_zero      == (reg_not_zero ^ 1)) &&
3641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl                     (reg_bit_clear == (reg_bit_set ^ 1)) &&
3651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl                     (always        == (never ^ 1)));
3661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
3671123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  BranchType InvertBranchType(BranchType type) {
3681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    if (kBranchTypeFirstCondition <= type && type <= kBranchTypeLastCondition) {
3691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      return static_cast<BranchType>(
3701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl          InvertCondition(static_cast<Condition>(type)));
3711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    } else {
3721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      return static_cast<BranchType>(type ^ 1);
3731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    }
3741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  }
3751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
3761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void B(Label* label, BranchType type, Register reg = NoReg, int bit = -1);
3771123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
378578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  void B(Label* label) {
379578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    b(label);
380578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  }
381578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  void B(Label* label, Condition cond) {
3821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
3831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT((cond != al) && (cond != nv));
384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    b(label, cond);
385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
3861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void B(Condition cond, Label* label) {
3871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    B(label, cond);
3881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  }
389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Bfi(const Register& rd,
390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const Register& rn,
391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           unsigned lsb,
392ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           unsigned width) {
3931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
3941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
3951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    bfi(rd, rn, lsb, width);
397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Bfxil(const Register& rd,
399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const Register& rn,
400ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             unsigned lsb,
401ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             unsigned width) {
4021123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
4041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
405ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    bfxil(rd, rn, lsb, width);
406ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Bind(Label* label) {
4081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    bind(label);
410ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
411ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Bl(Label* label) {
4121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    bl(label);
414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Blr(const Register& xn) {
4161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!xn.IsZero());
418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    blr(xn);
419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
420ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Br(const Register& xn) {
4211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!xn.IsZero());
423ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    br(xn);
424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Brk(int code = 0) {
4261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
427ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    brk(code);
428ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
429ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Cbnz(const Register& rt, Label* label) {
4301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rt.IsZero());
432ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    cbnz(rt, label);
433ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
434ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Cbz(const Register& rt, Label* label) {
4351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rt.IsZero());
437ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    cbz(rt, label);
438ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
439ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Cinc(const Register& rd, const Register& rn, Condition cond) {
4401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
4421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
443ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    cinc(rd, rn, cond);
444ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
445ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Cinv(const Register& rd, const Register& rn, Condition cond) {
4461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
4481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
449ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    cinv(rd, rn, cond);
450ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
451ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Cls(const Register& rd, const Register& rn) {
4521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
4541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
455ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    cls(rd, rn);
456ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
457ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Clz(const Register& rd, const Register& rn) {
4581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
4601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
461ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    clz(rd, rn);
462ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
463ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Cneg(const Register& rd, const Register& rn, Condition cond) {
4641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
4661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
467ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    cneg(rd, rn, cond);
468ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
469ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Cset(const Register& rd, Condition cond) {
4701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
472ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    cset(rd, cond);
473ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Csetm(const Register& rd, Condition cond) {
4751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    csetm(rd, cond);
478ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
479ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Csinc(const Register& rd,
480ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const Register& rn,
481ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const Register& rm,
482ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             Condition cond) {
4831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
4851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
4861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
4871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT((cond != al) && (cond != nv));
488ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    csinc(rd, rn, rm, cond);
489ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
490ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Csinv(const Register& rd,
491ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const Register& rn,
492ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const Register& rm,
493ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             Condition cond) {
4941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
4951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
4961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
4971123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
4981123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT((cond != al) && (cond != nv));
499ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    csinv(rd, rn, rm, cond);
500ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
501ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Csneg(const Register& rd,
502ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const Register& rn,
503ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const Register& rm,
504ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             Condition cond) {
5051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
5061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
5071123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
5081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
5091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT((cond != al) && (cond != nv));
510ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    csneg(rd, rn, rm, cond);
511ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
512f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Dmb(BarrierDomain domain, BarrierType type) {
5131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
514f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    dmb(domain, type);
515f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
516f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Dsb(BarrierDomain domain, BarrierType type) {
5171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
518f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    dsb(domain, type);
519f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
520ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Extr(const Register& rd,
521ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const Register& rn,
522ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const Register& rm,
523ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            unsigned lsb) {
5241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
5251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
5261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
5271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
528ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    extr(rd, rn, rm, lsb);
529ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
530ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fabs(const FPRegister& fd, const FPRegister& fn) {
5311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
532ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fabs(fd, fn);
533ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
534ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fadd(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) {
5351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
536ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fadd(fd, fn, fm);
537ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
538ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fccmp(const FPRegister& fn,
539ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const FPRegister& fm,
540ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             StatusFlags nzcv,
541ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             Condition cond) {
5421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
5431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT((cond != al) && (cond != nv));
544ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fccmp(fn, fm, nzcv, cond);
545ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
546ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fcmp(const FPRegister& fn, const FPRegister& fm) {
5471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
548ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fcmp(fn, fm);
549ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
5501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void Fcmp(const FPRegister& fn, double value);
551ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fcsel(const FPRegister& fd,
552ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const FPRegister& fn,
553ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const FPRegister& fm,
554ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             Condition cond) {
5551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
5561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT((cond != al) && (cond != nv));
557ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fcsel(fd, fn, fm, cond);
558ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
559578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  void Fcvt(const FPRegister& fd, const FPRegister& fn) {
5601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
561578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    fcvt(fd, fn);
562578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  }
563f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Fcvtas(const Register& rd, const FPRegister& fn) {
5641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
5651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
566f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    fcvtas(rd, fn);
567f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
568f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Fcvtau(const Register& rd, const FPRegister& fn) {
5691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
5701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
571f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    fcvtau(rd, fn);
572f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
573ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fcvtms(const Register& rd, const FPRegister& fn) {
5741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
5751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
576ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fcvtms(rd, fn);
577ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
578ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fcvtmu(const Register& rd, const FPRegister& fn) {
5791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
5801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
581ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fcvtmu(rd, fn);
582ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
583ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fcvtns(const Register& rd, const FPRegister& fn) {
5841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
5851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
586ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fcvtns(rd, fn);
587ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
588ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fcvtnu(const Register& rd, const FPRegister& fn) {
5891123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
5901123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
591ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fcvtnu(rd, fn);
592ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
593ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fcvtzs(const Register& rd, const FPRegister& fn) {
5941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
5951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
596ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fcvtzs(rd, fn);
597ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
598ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fcvtzu(const Register& rd, const FPRegister& fn) {
5991123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
6001123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
601ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fcvtzu(rd, fn);
602ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
603ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fdiv(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) {
6041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
605ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fdiv(fd, fn, fm);
606ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
607ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fmax(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) {
6081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
609ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fmax(fd, fn, fm);
610ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
611f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Fmaxnm(const FPRegister& fd,
612f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl              const FPRegister& fn,
613f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl              const FPRegister& fm) {
6141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
615f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    fmaxnm(fd, fn, fm);
616f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
617ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fmin(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) {
6181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
619ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fmin(fd, fn, fm);
620ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
621f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Fminnm(const FPRegister& fd,
622f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl              const FPRegister& fn,
623f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl              const FPRegister& fm) {
6241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
625f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    fminnm(fd, fn, fm);
626f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
627ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fmov(FPRegister fd, FPRegister fn) {
6281123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
629ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Only emit an instruction if fd and fn are different, and they are both D
630ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // registers. fmov(s0, s0) is not a no-op because it clears the top word of
631ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // d0. Technically, fmov(d0, d0) is not a no-op either because it clears
632ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // the top of q0, but FPRegister does not currently support Q registers.
633ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (!fd.Is(fn) || !fd.Is64Bits()) {
634ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      fmov(fd, fn);
635ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
636ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
637ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fmov(FPRegister fd, Register rn) {
6381123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
6391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
640ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fmov(fd, rn);
641ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
6421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // Provide explicit double and float interfaces for FP immediate moves, rather
6431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // than relying on implicit C++ casts. This allows signalling NaNs to be
6441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // preserved when the immediate matches the format of fd. Most systems convert
6451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // signalling NaNs to quiet NaNs when converting between float and double.
6461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void Fmov(FPRegister fd, double imm);
6471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void Fmov(FPRegister fd, float imm);
6481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // Provide a template to allow other types to be converted automatically.
6491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  template<typename T>
6501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void Fmov(FPRegister fd, T imm) {
6511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
6521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    Fmov(fd, static_cast<double>(imm));
653ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
654ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fmov(Register rd, FPRegister fn) {
6551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
6561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
657ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fmov(rd, fn);
658ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
659ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fmul(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) {
6601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
661ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fmul(fd, fn, fm);
662ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
663f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Fmadd(const FPRegister& fd,
664f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl             const FPRegister& fn,
665f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl             const FPRegister& fm,
666f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl             const FPRegister& fa) {
6671123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
668f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    fmadd(fd, fn, fm, fa);
669f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
670ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fmsub(const FPRegister& fd,
671ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const FPRegister& fn,
672ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const FPRegister& fm,
673ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const FPRegister& fa) {
6741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
675ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fmsub(fd, fn, fm, fa);
676ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
677f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Fnmadd(const FPRegister& fd,
678f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl              const FPRegister& fn,
679f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl              const FPRegister& fm,
680f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl              const FPRegister& fa) {
6811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
682f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    fnmadd(fd, fn, fm, fa);
683f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
684f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Fnmsub(const FPRegister& fd,
685f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl              const FPRegister& fn,
686f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl              const FPRegister& fm,
687f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl              const FPRegister& fa) {
6881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
689f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    fnmsub(fd, fn, fm, fa);
690f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
691ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fneg(const FPRegister& fd, const FPRegister& fn) {
6921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
693ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fneg(fd, fn);
694ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
695f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Frinta(const FPRegister& fd, const FPRegister& fn) {
6961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
697f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    frinta(fd, fn);
698f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
699ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  void Frintm(const FPRegister& fd, const FPRegister& fn) {
700ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    VIXL_ASSERT(allow_macro_instructions_);
701ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    frintm(fd, fn);
702ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  }
703ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Frintn(const FPRegister& fd, const FPRegister& fn) {
7041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
705ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    frintn(fd, fn);
706ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
707ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Frintz(const FPRegister& fd, const FPRegister& fn) {
7081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
709ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    frintz(fd, fn);
710ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
711ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fsqrt(const FPRegister& fd, const FPRegister& fn) {
7121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
713ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fsqrt(fd, fn);
714ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
715ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Fsub(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) {
7161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
717ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fsub(fd, fn, fm);
718ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
719ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Hint(SystemHint code) {
7201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
721ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    hint(code);
722ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
723ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Hlt(int code) {
7241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
725ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    hlt(code);
726ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
727f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Isb() {
7281123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
729f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    isb();
730f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
731ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ldnp(const CPURegister& rt,
732ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const CPURegister& rt2,
733ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const MemOperand& src) {
7341123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
735ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ldnp(rt, rt2, src);
736ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
737ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ldp(const CPURegister& rt,
738ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const CPURegister& rt2,
739ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const MemOperand& src) {
7401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
741ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ldp(rt, rt2, src);
742ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
743ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ldpsw(const Register& rt, const Register& rt2, const MemOperand& src) {
7441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
745ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ldpsw(rt, rt2, src);
746ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
7471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // Provide both double and float interfaces for FP immediate loads, rather
7481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // than relying on implicit C++ casts. This allows signalling NaNs to be
7491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // preserved when the immediate matches the format of fd. Most systems convert
7501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // signalling NaNs to quiet NaNs when converting between float and double.
751ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ldr(const FPRegister& ft, double imm) {
7521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
7531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    if (ft.Is64Bits()) {
7541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      ldr(ft, imm);
7551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    } else {
7561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      ldr(ft, static_cast<float>(imm));
7571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    }
7581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  }
7591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void Ldr(const FPRegister& ft, float imm) {
7601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
7611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    if (ft.Is32Bits()) {
7621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      ldr(ft, imm);
7631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    } else {
7641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      ldr(ft, static_cast<double>(imm));
7651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    }
766ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
767ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ldr(const Register& rt, uint64_t imm) {
7681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
7691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rt.IsZero());
770ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ldr(rt, imm);
771ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
772ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Lsl(const Register& rd, const Register& rn, unsigned shift) {
7731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
7741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
7751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
776ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    lsl(rd, rn, shift);
777ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
778ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Lsl(const Register& rd, const Register& rn, const Register& rm) {
7791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
7801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
7811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
7821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
783ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    lslv(rd, rn, rm);
784ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
785ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Lsr(const Register& rd, const Register& rn, unsigned shift) {
7861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
7871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
7881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
789ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    lsr(rd, rn, shift);
790ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
791ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Lsr(const Register& rd, const Register& rn, const Register& rm) {
7921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
7931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
7941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
7951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
796ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    lsrv(rd, rn, rm);
797ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
798ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Madd(const Register& rd,
799ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const Register& rn,
800ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const Register& rm,
801ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const Register& ra) {
8021123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
8041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
8051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
8061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!ra.IsZero());
807ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    madd(rd, rn, rm, ra);
808ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
809ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Mneg(const Register& rd, const Register& rn, const Register& rm) {
8101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
8121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
8131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
814ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    mneg(rd, rn, rm);
815ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
816ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Mov(const Register& rd, const Register& rn) {
8171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
818ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    mov(rd, rn);
819ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
820f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  void Movk(const Register& rd, uint64_t imm, int shift = -1) {
8211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
823f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    movk(rd, imm, shift);
824f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
825ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Mrs(const Register& rt, SystemRegister sysreg) {
8261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rt.IsZero());
828ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    mrs(rt, sysreg);
829ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
830ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Msr(SystemRegister sysreg, const Register& rt) {
8311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rt.IsZero());
833ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    msr(sysreg, rt);
834ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
835ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Msub(const Register& rd,
836ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const Register& rn,
837ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const Register& rm,
838ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const Register& ra) {
8391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
8411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
8421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
8431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!ra.IsZero());
844ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    msub(rd, rn, rm, ra);
845ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
846ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Mul(const Register& rd, const Register& rn, const Register& rm) {
8471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
8491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
8501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
851ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    mul(rd, rn, rm);
852ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
853ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Nop() {
8541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
855ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    nop();
856ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
857ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Rbit(const Register& rd, const Register& rn) {
8581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
8601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
861ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    rbit(rd, rn);
862ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
863ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ret(const Register& xn = lr) {
8641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!xn.IsZero());
866ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ret(xn);
867ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
868ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Rev(const Register& rd, const Register& rn) {
8691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
8711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
872ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    rev(rd, rn);
873ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
874ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Rev16(const Register& rd, const Register& rn) {
8751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
8771123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
878ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    rev16(rd, rn);
879ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
880ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Rev32(const Register& rd, const Register& rn) {
8811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
8831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
884ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    rev32(rd, rn);
885ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
886ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ror(const Register& rd, const Register& rs, unsigned shift) {
8871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
8891123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rs.IsZero());
890ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ror(rd, rs, shift);
891ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
892ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ror(const Register& rd, const Register& rn, const Register& rm) {
8931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
8941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
8951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
8961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
897ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    rorv(rd, rn, rm);
898ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
899ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Sbfiz(const Register& rd,
900ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const Register& rn,
901ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             unsigned lsb,
902ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             unsigned width) {
9031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
9041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
9051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
906ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    sbfiz(rd, rn, lsb, width);
907ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
908ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Sbfx(const Register& rd,
909ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const Register& rn,
910ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            unsigned lsb,
911ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            unsigned width) {
9121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
9131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
9141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
915ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    sbfx(rd, rn, lsb, width);
916ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
917ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Scvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0) {
9181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
9191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
920ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    scvtf(fd, rn, fbits);
921ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
922ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Sdiv(const Register& rd, const Register& rn, const Register& rm) {
9231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
9241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
9251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
9261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
927ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    sdiv(rd, rn, rm);
928ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
929ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Smaddl(const Register& rd,
930ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl              const Register& rn,
931ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl              const Register& rm,
932ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl              const Register& ra) {
9331123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
9341123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
9351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
9361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
9371123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!ra.IsZero());
938ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    smaddl(rd, rn, rm, ra);
939ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
940ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Smsubl(const Register& rd,
941ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl              const Register& rn,
942ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl              const Register& rm,
943ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl              const Register& ra) {
9441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
9451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
9461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
9471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
9481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!ra.IsZero());
949ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    smsubl(rd, rn, rm, ra);
950ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
951ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Smull(const Register& rd, const Register& rn, const Register& rm) {
9521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
9531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
9541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
9551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
956ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    smull(rd, rn, rm);
957ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
958ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Smulh(const Register& xd, const Register& xn, const Register& xm) {
9591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
9601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!xd.IsZero());
9611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!xn.IsZero());
9621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!xm.IsZero());
963ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    smulh(xd, xn, xm);
964ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
965ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Stnp(const CPURegister& rt,
966ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const CPURegister& rt2,
967ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const MemOperand& dst) {
9681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
969ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    stnp(rt, rt2, dst);
970ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
971ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Stp(const CPURegister& rt,
972ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const CPURegister& rt2,
973ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           const MemOperand& dst) {
9741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
975ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    stp(rt, rt2, dst);
976ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
977ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Sxtb(const Register& rd, const Register& rn) {
9781123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
9791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
9801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
981ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    sxtb(rd, rn);
982ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
983ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Sxth(const Register& rd, const Register& rn) {
9841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
9851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
9861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
987ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    sxth(rd, rn);
988ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
989ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Sxtw(const Register& rd, const Register& rn) {
9901123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
9911123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
9921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
993ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    sxtw(rd, rn);
994ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
995ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Tbnz(const Register& rt, unsigned bit_pos, Label* label) {
9961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
9971123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rt.IsZero());
998ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    tbnz(rt, bit_pos, label);
999ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1000ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Tbz(const Register& rt, unsigned bit_pos, Label* label) {
10011123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
10021123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rt.IsZero());
1003ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    tbz(rt, bit_pos, label);
1004ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1005ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ubfiz(const Register& rd,
1006ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const Register& rn,
1007ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             unsigned lsb,
1008ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             unsigned width) {
10091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
10101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
10111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
1012ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ubfiz(rd, rn, lsb, width);
1013ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1014ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ubfx(const Register& rd,
1015ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            const Register& rn,
1016ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            unsigned lsb,
1017ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            unsigned width) {
10181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
10191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
10201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
1021ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ubfx(rd, rn, lsb, width);
1022ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1023ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Ucvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0) {
10241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
10251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
1026ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ucvtf(fd, rn, fbits);
1027ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1028ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Udiv(const Register& rd, const Register& rn, const Register& rm) {
10291123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
10301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
10311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
10321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
1033ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    udiv(rd, rn, rm);
1034ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1035ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Umaddl(const Register& rd,
1036ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl              const Register& rn,
1037ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl              const Register& rm,
1038ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl              const Register& ra) {
10391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
10401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
10411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
10421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
10431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!ra.IsZero());
1044ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    umaddl(rd, rn, rm, ra);
1045ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1046ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Umsubl(const Register& rd,
1047ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl              const Register& rn,
1048ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl              const Register& rm,
1049ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl              const Register& ra) {
10501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
10511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
10521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
10531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rm.IsZero());
10541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!ra.IsZero());
1055ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    umsubl(rd, rn, rm, ra);
1056ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1057ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Unreachable() {
10581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
1059ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifdef USE_SIMULATOR
1060ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    hlt(kUnreachableOpcode);
1061ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#else
1062ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Branch to 0 to generate a segfault.
1063ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // lr - kInstructionSize is the address of the offending instruction.
1064ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    blr(xzr);
1065ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif
1066ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1067ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Uxtb(const Register& rd, const Register& rn) {
10681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
10691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
10701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
1071ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    uxtb(rd, rn);
1072ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1073ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Uxth(const Register& rd, const Register& rn) {
10741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
10751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
10761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
1077ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    uxth(rd, rn);
1078ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1079ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Uxtw(const Register& rd, const Register& rn) {
10801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(allow_macro_instructions_);
10811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rd.IsZero());
10821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!rn.IsZero());
1083ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    uxtw(rd, rn);
1084ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1085ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1086ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Push the system stack pointer (sp) down to allow the same to be done to
1087ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // the current stack pointer (according to StackPointer()). This must be
1088ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // called _before_ accessing the memory.
1089ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1090ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // This is necessary when pushing or otherwise adding things to the stack, to
1091ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // satisfy the AAPCS64 constraint that the memory below the system stack
1092ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // pointer is not accessed.
1093ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1094ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // This method asserts that StackPointer() is not sp, since the call does
1095ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // not make sense in that context.
1096ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1097ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // TODO: This method can only accept values of 'space' that can be encoded in
1098ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // one instruction. Refer to the implementation for details.
1099ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void BumpSystemStackPointer(const Operand& space);
1100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#if DEBUG
1102ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void SetAllowMacroInstructions(bool value) {
1103ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    allow_macro_instructions_ = value;
1104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bool AllowMacroInstructions() const {
1107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return allow_macro_instructions_;
1108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif
1110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Set the current stack pointer, but don't generate any code.
1112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void SetStackPointer(const Register& stack_pointer) {
11131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!TmpList()->IncludesAliasOf(stack_pointer));
1114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    sp_ = stack_pointer;
1115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Return the current stack pointer, as set by SetStackPointer.
1118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  const Register& StackPointer() const {
1119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return sp_;
1120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
11221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  CPURegList* TmpList() { return &tmp_list_; }
11231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  CPURegList* FPTmpList() { return &fptmp_list_; }
1124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Like printf, but print at run-time from generated code.
1126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // The caller must ensure that arguments for floating-point placeholders
1128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // (such as %e, %f or %g) are FPRegisters, and that arguments for integer
1129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // placeholders are Registers.
1130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1131ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  // At the moment it is only possible to print the value of sp if it is the
1132ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  // current stack pointer. Otherwise, the MacroAssembler will automatically
1133ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  // update sp on every push (using BumpSystemStackPointer), so determining its
1134ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  // value is difficult.
11351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  //
1136ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  // Format placeholders that refer to more than one argument, or to a specific
1137ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  // argument, are not supported. This includes formats like "%1$d" or "%.*d".
1138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // This function automatically preserves caller-saved registers so that
1140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // calling code can use Printf at any point without having to worry about
1141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // corruption. The preservation mechanism generates a lot of code. If this is
1142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // a problem, preserve the important registers manually and then call
1143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // PrintfNoPreserve. Callee-saved registers are not used by Printf, and are
1144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // implicitly preserved.
1145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Printf(const char * format,
1146ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl              CPURegister arg0 = NoCPUReg,
1147ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl              CPURegister arg1 = NoCPUReg,
1148ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl              CPURegister arg2 = NoCPUReg,
1149ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl              CPURegister arg3 = NoCPUReg);
1150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Like Printf, but don't preserve any caller-saved registers, not even 'lr'.
1152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // The return code from the system printf call will be returned in x0.
1154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PrintfNoPreserve(const char * format,
1155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                        const CPURegister& arg0 = NoCPUReg,
1156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                        const CPURegister& arg1 = NoCPUReg,
1157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                        const CPURegister& arg2 = NoCPUReg,
1158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                        const CPURegister& arg3 = NoCPUReg);
1159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Trace control when running the debug simulator.
1161ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1162ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // For example:
1163ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1164ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // __ Trace(LOG_REGS, TRACE_ENABLE);
1165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Will add registers to the trace if it wasn't already the case.
1166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // __ Trace(LOG_DISASM, TRACE_DISABLE);
1168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Will stop logging disassembly. It has no effect if the disassembly wasn't
1169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // already being logged.
1170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Trace(TraceParameters parameters, TraceCommand command);
1171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Log the requested data independently of what is being traced.
1173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // For example:
1175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // __ Log(LOG_FLAGS)
1177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Will output the flags.
1178578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  void Log(TraceParameters parameters);
1179578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
1180578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // Enable or disable instrumentation when an Instrument visitor is attached to
1181578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // the simulator.
1182578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  void EnableInstrumentation();
1183578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  void DisableInstrumentation();
1184578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
1185578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // Add a marker to the instrumentation data produced by an Instrument visitor.
1186578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // The name is a two character string that will be attached to the marker in
1187578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // the output data.
1188578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  void AnnotateInstrumentation(const char* marker_name);
1189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private:
1191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // The actual Push and Pop implementations. These don't generate any code
1192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // other than that required for the push or pop. This allows
1193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // (Push|Pop)CPURegList to bundle together setup code for a large block of
1194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // registers.
1195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Note that size is per register, and is specified in bytes.
1197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PushHelper(int count, int size,
1198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                  const CPURegister& src0, const CPURegister& src1,
1199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                  const CPURegister& src2, const CPURegister& src3);
1200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PopHelper(int count, int size,
1201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                 const CPURegister& dst0, const CPURegister& dst1,
1202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                 const CPURegister& dst2, const CPURegister& dst3);
1203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Perform necessary maintenance operations before a push or pop.
1205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1206ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Note that size is per register, and is specified in bytes.
1207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PrepareForPush(int count, int size);
1208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void PrepareForPop(int count, int size);
1209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#if DEBUG
1211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Tell whether any of the macro instruction can be used. When false the
1212ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // MacroAssembler will assert if a method which can emit a variable number
1213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // of instructions is called.
1214ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bool allow_macro_instructions_;
1215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif
1216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // The register to use as a stack pointer for stack operations.
1218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Register sp_;
1219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
12201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // Scratch registers available for use by the MacroAssembler.
12211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  CPURegList tmp_list_;
12221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  CPURegList fptmp_list_;
1223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
1224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Use this scope when you need a one-to-one mapping between methods and
1227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// instructions. This scope prevents the MacroAssembler from being called and
1228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// literal pools from being emitted. It also asserts the number of instructions
1229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// emitted is what you specified when creating the scope.
1230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass InstructionAccurateScope {
1231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
1232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  explicit InstructionAccurateScope(MacroAssembler* masm)
12338fcae179b1449176c5780eb0ba57f75654ec4c80Serban Constantinescu      : masm_(masm) {
1234ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    masm_->BlockLiteralPool();
1235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifdef DEBUG
12368fcae179b1449176c5780eb0ba57f75654ec4c80Serban Constantinescu    size_ = 0;
1237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    old_allow_macro_instructions_ = masm_->AllowMacroInstructions();
1238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    masm_->SetAllowMacroInstructions(false);
1239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif
1240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  InstructionAccurateScope(MacroAssembler* masm, int count)
12438fcae179b1449176c5780eb0ba57f75654ec4c80Serban Constantinescu      : masm_(masm) {
12448fcae179b1449176c5780eb0ba57f75654ec4c80Serban Constantinescu    USE(count);
1245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    masm_->BlockLiteralPool();
1246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifdef DEBUG
12478fcae179b1449176c5780eb0ba57f75654ec4c80Serban Constantinescu    size_ = count * kInstructionSize;
1248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    masm_->bind(&start_);
1249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    old_allow_macro_instructions_ = masm_->AllowMacroInstructions();
1250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    masm_->SetAllowMacroInstructions(false);
1251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif
1252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ~InstructionAccurateScope() {
1255ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    masm_->ReleaseLiteralPool();
1256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifdef DEBUG
1257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (start_.IsBound()) {
12581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      VIXL_ASSERT(masm_->SizeOfCodeGeneratedSince(&start_) == size_);
1259ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    masm_->SetAllowMacroInstructions(old_allow_macro_instructions_);
1261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif
1262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private:
1265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  MacroAssembler* masm_;
12669b9674a6dd7b5f23d73a5432b74affe4bc380c31Serban Constantinescu#ifdef DEBUG
12678fcae179b1449176c5780eb0ba57f75654ec4c80Serban Constantinescu  uint64_t size_;
1268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Label start_;
1269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bool old_allow_macro_instructions_;
1270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif
1271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
1272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1273ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
12741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// This scope utility allows scratch registers to be managed safely. The
12751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// MacroAssembler's TmpList() (and FPTmpList()) is used as a pool of scratch
12761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// registers. These registers can be allocated on demand, and will be returned
12771123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// at the end of the scope.
12781123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl//
12791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// When the scope ends, the MacroAssembler's lists will be restored to their
12801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// original state, even if the lists were modified by some other means.
12811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixlclass UseScratchRegisterScope {
12821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl public:
12831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  explicit UseScratchRegisterScope(MacroAssembler* masm)
12841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      : available_(masm->TmpList()),
12851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl        availablefp_(masm->FPTmpList()),
12861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl        old_available_(available_->list()),
12871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl        old_availablefp_(availablefp_->list()) {
12881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(available_->type() == CPURegister::kRegister);
12891123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(availablefp_->type() == CPURegister::kFPRegister);
12901123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  }
12911123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
12921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
12931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  ~UseScratchRegisterScope();
12941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
12951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
1296ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  bool IsAvailable(const CPURegister& reg) const;
1297ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
1298ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
12991123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // Take a register from the appropriate temps list. It will be returned
13001123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // automatically when the scope ends.
13011123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  Register AcquireW() { return AcquireNextAvailable(available_).W(); }
13021123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  Register AcquireX() { return AcquireNextAvailable(available_).X(); }
13031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  FPRegister AcquireS() { return AcquireNextAvailable(availablefp_).S(); }
13041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  FPRegister AcquireD() { return AcquireNextAvailable(availablefp_).D(); }
13051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13071123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  Register AcquireSameSizeAs(const Register& reg);
13081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  FPRegister AcquireSameSizeAs(const FPRegister& reg);
13091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // Explicitly release an acquired (or excluded) register, putting it back in
13121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // the appropriate temps list.
13131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void Release(const CPURegister& reg);
13141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13151123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // Make the specified registers available as scratch registers for the
13171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // duration of this scope.
1318ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  void Include(const CPURegList& list);
13191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void Include(const Register& reg1,
13201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const Register& reg2 = NoReg,
13211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const Register& reg3 = NoReg,
13221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const Register& reg4 = NoReg);
13231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void Include(const FPRegister& reg1,
13241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const FPRegister& reg2 = NoFPReg,
13251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const FPRegister& reg3 = NoFPReg,
13261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const FPRegister& reg4 = NoFPReg);
13271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13281123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13291123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // Make sure that the specified registers are not available in this scope.
13301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // This can be used to prevent helper functions from using sensitive
13311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // registers, for example.
1332ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  void Exclude(const CPURegList& list);
13331123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void Exclude(const Register& reg1,
13341123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const Register& reg2 = NoReg,
13351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const Register& reg3 = NoReg,
13361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const Register& reg4 = NoReg);
13371123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void Exclude(const FPRegister& reg1,
13381123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const FPRegister& reg2 = NoFPReg,
13391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const FPRegister& reg3 = NoFPReg,
13401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const FPRegister& reg4 = NoFPReg);
13411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void Exclude(const CPURegister& reg1,
13421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const CPURegister& reg2 = NoCPUReg,
13431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const CPURegister& reg3 = NoCPUReg,
13441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl               const CPURegister& reg4 = NoCPUReg);
13451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // Prevent any scratch registers from being used in this scope.
13481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  void ExcludeAll();
13491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl private:
13521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  static CPURegister AcquireNextAvailable(CPURegList* available);
13531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  static void ReleaseByCode(CPURegList* available, int code);
13551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  static void ReleaseByRegList(CPURegList* available,
13571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl                               RegList regs);
13581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  static void IncludeByRegList(CPURegList* available,
13601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl                               RegList exclude);
13611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  static void ExcludeByRegList(CPURegList* available,
13631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl                               RegList exclude);
13641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // Available scratch registers.
13661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  CPURegList* available_;     // kRegister
13671123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  CPURegList* availablefp_;   // kFPRegister
13681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  // The state of the available lists at the start of this scope.
13701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  RegList old_available_;     // kRegister
13711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  RegList old_availablefp_;   // kFPRegister
13721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl};
13731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
13741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
1375ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}  // namespace vixl
1376ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1377ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif  // VIXL_A64_MACRO_ASSEMBLER_A64_H_
1378