1 // Copyright 2015, ARM Limited
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 //   * Redistributions of source code must retain the above copyright notice,
8 //     this list of conditions and the following disclaimer.
9 //   * Redistributions in binary form must reproduce the above copyright notice,
10 //     this list of conditions and the following disclaimer in the documentation
11 //     and/or other materials provided with the distribution.
12 //   * Neither the name of ARM Limited nor the names of its contributors may be
13 //     used to endorse or promote products derived from this software without
14 //     specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #ifndef VIXL_A64_MACRO_ASSEMBLER_A64_H_
28 #define VIXL_A64_MACRO_ASSEMBLER_A64_H_
29 
30 #include <algorithm>
31 #include <limits>
32 
33 #include "jit/arm64/Assembler-arm64.h"
34 #include "jit/arm64/vixl/Debugger-vixl.h"
35 #include "jit/arm64/vixl/Globals-vixl.h"
36 #include "jit/arm64/vixl/Instrument-vixl.h"
37 #include "jit/arm64/vixl/Simulator-Constants-vixl.h"
38 
39 #define LS_MACRO_LIST(V)                                      \
40   V(Ldrb, Register&, rt, LDRB_w)                              \
41   V(Strb, Register&, rt, STRB_w)                              \
42   V(Ldrsb, Register&, rt, rt.Is64Bits() ? LDRSB_x : LDRSB_w)  \
43   V(Ldrh, Register&, rt, LDRH_w)                              \
44   V(Strh, Register&, rt, STRH_w)                              \
45   V(Ldrsh, Register&, rt, rt.Is64Bits() ? LDRSH_x : LDRSH_w)  \
46   V(Ldr, CPURegister&, rt, LoadOpFor(rt))                     \
47   V(Str, CPURegister&, rt, StoreOpFor(rt))                    \
48   V(Ldrsw, Register&, rt, LDRSW_x)
49 
50 
51 #define LSPAIR_MACRO_LIST(V)                              \
52   V(Ldp, CPURegister&, rt, rt2, LoadPairOpFor(rt, rt2))   \
53   V(Stp, CPURegister&, rt, rt2, StorePairOpFor(rt, rt2))  \
54   V(Ldpsw, CPURegister&, rt, rt2, LDPSW_x)
55 
56 namespace vixl {
57 
58 // Forward declaration
59 class MacroAssembler;
60 class UseScratchRegisterScope;
61 
62 // This scope has the following purposes:
63 //  * Acquire/Release the underlying assembler's code buffer.
64 //     * This is mandatory before emitting.
65 //  * Emit the literal or veneer pools if necessary before emitting the
66 //    macro-instruction.
67 //  * Ensure there is enough space to emit the macro-instruction.
68 class EmissionCheckScope {
69  public:
EmissionCheckScope(MacroAssembler * masm,size_t size)70   EmissionCheckScope(MacroAssembler* masm, size_t size)
71     : masm_(masm)
72   { }
73 
74  protected:
75   MacroAssembler* masm_;
76 #ifdef DEBUG
77   Label start_;
78   size_t size_;
79 #endif
80 };
81 
82 
83 // Helper for common Emission checks.
84 // The macro-instruction maps to a single instruction.
85 class SingleEmissionCheckScope : public EmissionCheckScope {
86  public:
SingleEmissionCheckScope(MacroAssembler * masm)87   explicit SingleEmissionCheckScope(MacroAssembler* masm)
88       : EmissionCheckScope(masm, kInstructionSize) {}
89 };
90 
91 
92 // The macro instruction is a "typical" macro-instruction. Typical macro-
93 // instruction only emit a few instructions, a few being defined as 8 here.
94 class MacroEmissionCheckScope : public EmissionCheckScope {
95  public:
MacroEmissionCheckScope(MacroAssembler * masm)96   explicit MacroEmissionCheckScope(MacroAssembler* masm)
97       : EmissionCheckScope(masm, kTypicalMacroInstructionMaxSize) {}
98 
99  private:
100   static const size_t kTypicalMacroInstructionMaxSize = 8 * kInstructionSize;
101 };
102 
103 
104 enum BranchType {
105   // Copies of architectural conditions.
106   // The associated conditions can be used in place of those, the code will
107   // take care of reinterpreting them with the correct type.
108   integer_eq = eq,
109   integer_ne = ne,
110   integer_hs = hs,
111   integer_lo = lo,
112   integer_mi = mi,
113   integer_pl = pl,
114   integer_vs = vs,
115   integer_vc = vc,
116   integer_hi = hi,
117   integer_ls = ls,
118   integer_ge = ge,
119   integer_lt = lt,
120   integer_gt = gt,
121   integer_le = le,
122   integer_al = al,
123   integer_nv = nv,
124 
125   // These two are *different* from the architectural codes al and nv.
126   // 'always' is used to generate unconditional branches.
127   // 'never' is used to not generate a branch (generally as the inverse
128   // branch type of 'always).
129   always, never,
130   // cbz and cbnz
131   reg_zero, reg_not_zero,
132   // tbz and tbnz
133   reg_bit_clear, reg_bit_set,
134 
135   // Aliases.
136   kBranchTypeFirstCondition = eq,
137   kBranchTypeLastCondition = nv,
138   kBranchTypeFirstUsingReg = reg_zero,
139   kBranchTypeFirstUsingBit = reg_bit_clear
140 };
141 
142 
143 enum DiscardMoveMode { kDontDiscardForSameWReg, kDiscardForSameWReg };
144 
145 // The macro assembler supports moving automatically pre-shifted immediates for
146 // arithmetic and logical instructions, and then applying a post shift in the
147 // instruction to undo the modification, in order to reduce the code emitted for
148 // an operation. For example:
149 //
150 //  Add(x0, x0, 0x1f7de) => movz x16, 0xfbef; add x0, x0, x16, lsl #1.
151 //
152 // This optimisation can be only partially applied when the stack pointer is an
153 // operand or destination, so this enumeration is used to control the shift.
154 enum PreShiftImmMode {
155   kNoShift,          // Don't pre-shift.
156   kLimitShiftForSP,  // Limit pre-shift for add/sub extend use.
157   kAnyShift          // Allow any pre-shift.
158 };
159 
160 
161 class MacroAssembler : public js::jit::Assembler {
162  public:
163   MacroAssembler();
164 
165   // Finalize a code buffer of generated instructions. This function must be
166   // called before executing or copying code from the buffer.
167   void FinalizeCode();
168 
169 
170   // Constant generation helpers.
171   // These functions return the number of instructions required to move the
172   // immediate into the destination register. Also, if the masm pointer is
173   // non-null, it generates the code to do so.
174   // The two features are implemented using one function to avoid duplication of
175   // the logic.
176   // The function can be used to evaluate the cost of synthesizing an
177   // instruction using 'mov immediate' instructions. A user might prefer loading
178   // a constant using the literal pool instead of using multiple 'mov immediate'
179   // instructions.
180   static int MoveImmediateHelper(MacroAssembler* masm,
181                                  const Register &rd,
182                                  uint64_t imm);
183   static bool OneInstrMoveImmediateHelper(MacroAssembler* masm,
184                                           const Register& dst,
185                                           int64_t imm);
186 
187 
188   // Logical macros.
189   void And(const Register& rd,
190            const Register& rn,
191            const Operand& operand);
192   void Ands(const Register& rd,
193             const Register& rn,
194             const Operand& operand);
195   void Bic(const Register& rd,
196            const Register& rn,
197            const Operand& operand);
198   void Bics(const Register& rd,
199             const Register& rn,
200             const Operand& operand);
201   void Orr(const Register& rd,
202            const Register& rn,
203            const Operand& operand);
204   void Orn(const Register& rd,
205            const Register& rn,
206            const Operand& operand);
207   void Eor(const Register& rd,
208            const Register& rn,
209            const Operand& operand);
210   void Eon(const Register& rd,
211            const Register& rn,
212            const Operand& operand);
213   void Tst(const Register& rn, const Operand& operand);
214   void LogicalMacro(const Register& rd,
215                     const Register& rn,
216                     const Operand& operand,
217                     LogicalOp op);
218 
219   // Add and sub macros.
220   void Add(const Register& rd,
221            const Register& rn,
222            const Operand& operand,
223            FlagsUpdate S = LeaveFlags);
224   void Adds(const Register& rd,
225             const Register& rn,
226             const Operand& operand);
227   void Sub(const Register& rd,
228            const Register& rn,
229            const Operand& operand,
230            FlagsUpdate S = LeaveFlags);
231   void Subs(const Register& rd,
232             const Register& rn,
233             const Operand& operand);
234   void Cmn(const Register& rn, const Operand& operand);
235   void Cmp(const Register& rn, const Operand& operand);
236   void Neg(const Register& rd,
237            const Operand& operand);
238   void Negs(const Register& rd,
239             const Operand& operand);
240 
241   void AddSubMacro(const Register& rd,
242                    const Register& rn,
243                    const Operand& operand,
244                    FlagsUpdate S,
245                    AddSubOp op);
246 
247   // Add/sub with carry macros.
248   void Adc(const Register& rd,
249            const Register& rn,
250            const Operand& operand);
251   void Adcs(const Register& rd,
252             const Register& rn,
253             const Operand& operand);
254   void Sbc(const Register& rd,
255            const Register& rn,
256            const Operand& operand);
257   void Sbcs(const Register& rd,
258             const Register& rn,
259             const Operand& operand);
260   void Ngc(const Register& rd,
261            const Operand& operand);
262   void Ngcs(const Register& rd,
263             const Operand& operand);
264   void AddSubWithCarryMacro(const Register& rd,
265                             const Register& rn,
266                             const Operand& operand,
267                             FlagsUpdate S,
268                             AddSubWithCarryOp op);
269 
270   // Move macros.
271   void Mov(const Register& rd, uint64_t imm);
272   void Mov(const Register& rd,
273            const Operand& operand,
274            DiscardMoveMode discard_mode = kDontDiscardForSameWReg);
Mvn(const Register & rd,uint64_t imm)275   void Mvn(const Register& rd, uint64_t imm) {
276     Mov(rd, (rd.size() == kXRegSize) ? ~imm : (~imm & kWRegMask));
277   }
278   void Mvn(const Register& rd, const Operand& operand);
279 
280   // Try to move an immediate into the destination register in a single
281   // instruction. Returns true for success, and updates the contents of dst.
282   // Returns false, otherwise.
283   bool TryOneInstrMoveImmediate(const Register& dst, int64_t imm);
284 
285   // Move an immediate into register dst, and return an Operand object for
286   // use with a subsequent instruction that accepts a shift. The value moved
287   // into dst is not necessarily equal to imm; it may have had a shifting
288   // operation applied to it that will be subsequently undone by the shift
289   // applied in the Operand.
290   Operand MoveImmediateForShiftedOp(const Register& dst,
291 		                    int64_t imm,
292 				    PreShiftImmMode mode);
293 
294   // Synthesises the address represented by a MemOperand into a register.
295   void ComputeAddress(const Register& dst, const MemOperand& mem_op);
296 
297   // Conditional macros.
298   void Ccmp(const Register& rn,
299             const Operand& operand,
300             StatusFlags nzcv,
301             Condition cond);
302   void Ccmn(const Register& rn,
303             const Operand& operand,
304             StatusFlags nzcv,
305             Condition cond);
306   void ConditionalCompareMacro(const Register& rn,
307                                const Operand& operand,
308                                StatusFlags nzcv,
309                                Condition cond,
310                                ConditionalCompareOp op);
311   void Csel(const Register& rd,
312             const Register& rn,
313             const Operand& operand,
314             Condition cond);
315 
316   // Load/store macros.
317 #define DECLARE_FUNCTION(FN, REGTYPE, REG, OP) \
318   void FN(const REGTYPE REG, const MemOperand& addr);
319   LS_MACRO_LIST(DECLARE_FUNCTION)
320 #undef DECLARE_FUNCTION
321 
322   void LoadStoreMacro(const CPURegister& rt,
323                       const MemOperand& addr,
324                       LoadStoreOp op);
325 
326 #define DECLARE_FUNCTION(FN, REGTYPE, REG, REG2, OP) \
327   void FN(const REGTYPE REG, const REGTYPE REG2, const MemOperand& addr);
328   LSPAIR_MACRO_LIST(DECLARE_FUNCTION)
329 #undef DECLARE_FUNCTION
330 
331   void LoadStorePairMacro(const CPURegister& rt,
332                           const CPURegister& rt2,
333                           const MemOperand& addr,
334                           LoadStorePairOp op);
335 
336   void Prfm(PrefetchOperation op, const MemOperand& addr);
337 
338   // Push or pop up to 4 registers of the same width to or from the stack,
339   // using the current stack pointer as set by SetStackPointer.
340   //
341   // If an argument register is 'NoReg', all further arguments are also assumed
342   // to be 'NoReg', and are thus not pushed or popped.
343   //
344   // Arguments are ordered such that "Push(a, b);" is functionally equivalent
345   // to "Push(a); Push(b);".
346   //
347   // It is valid to push the same register more than once, and there is no
348   // restriction on the order in which registers are specified.
349   //
350   // It is not valid to pop into the same register more than once in one
351   // operation, not even into the zero register.
352   //
353   // If the current stack pointer (as set by SetStackPointer) is sp, then it
354   // must be aligned to 16 bytes on entry and the total size of the specified
355   // registers must also be a multiple of 16 bytes.
356   //
357   // Even if the current stack pointer is not the system stack pointer (sp),
358   // Push (and derived methods) will still modify the system stack pointer in
359   // order to comply with ABI rules about accessing memory below the system
360   // stack pointer.
361   //
362   // Other than the registers passed into Pop, the stack pointer and (possibly)
363   // the system stack pointer, these methods do not modify any other registers.
364   void Push(const CPURegister& src0, const CPURegister& src1 = NoReg,
365             const CPURegister& src2 = NoReg, const CPURegister& src3 = NoReg);
366   void Pop(const CPURegister& dst0, const CPURegister& dst1 = NoReg,
367            const CPURegister& dst2 = NoReg, const CPURegister& dst3 = NoReg);
368   void PushStackPointer();
369 
370   // Alternative forms of Push and Pop, taking a RegList or CPURegList that
371   // specifies the registers that are to be pushed or popped. Higher-numbered
372   // registers are associated with higher memory addresses (as in the A32 push
373   // and pop instructions).
374   //
375   // (Push|Pop)SizeRegList allow you to specify the register size as a
376   // parameter. Only kXRegSize, kWRegSize, kDRegSize and kSRegSize are
377   // supported.
378   //
379   // Otherwise, (Push|Pop)(CPU|X|W|D|S)RegList is preferred.
380   void PushCPURegList(CPURegList registers);
381   void PopCPURegList(CPURegList registers);
382 
383   void PushSizeRegList(RegList registers, unsigned reg_size,
384       CPURegister::RegisterType type = CPURegister::kRegister) {
385     PushCPURegList(CPURegList(type, reg_size, registers));
386   }
387   void PopSizeRegList(RegList registers, unsigned reg_size,
388       CPURegister::RegisterType type = CPURegister::kRegister) {
389     PopCPURegList(CPURegList(type, reg_size, registers));
390   }
PushXRegList(RegList regs)391   void PushXRegList(RegList regs) {
392     PushSizeRegList(regs, kXRegSize);
393   }
PopXRegList(RegList regs)394   void PopXRegList(RegList regs) {
395     PopSizeRegList(regs, kXRegSize);
396   }
PushWRegList(RegList regs)397   void PushWRegList(RegList regs) {
398     PushSizeRegList(regs, kWRegSize);
399   }
PopWRegList(RegList regs)400   void PopWRegList(RegList regs) {
401     PopSizeRegList(regs, kWRegSize);
402   }
PushDRegList(RegList regs)403   void PushDRegList(RegList regs) {
404     PushSizeRegList(regs, kDRegSize, CPURegister::kVRegister);
405   }
PopDRegList(RegList regs)406   void PopDRegList(RegList regs) {
407     PopSizeRegList(regs, kDRegSize, CPURegister::kVRegister);
408   }
PushSRegList(RegList regs)409   void PushSRegList(RegList regs) {
410     PushSizeRegList(regs, kSRegSize, CPURegister::kVRegister);
411   }
PopSRegList(RegList regs)412   void PopSRegList(RegList regs) {
413     PopSizeRegList(regs, kSRegSize, CPURegister::kVRegister);
414   }
415 
416   // Push the specified register 'count' times.
417   void PushMultipleTimes(int count, Register src);
418 
419   // Poke 'src' onto the stack. The offset is in bytes.
420   //
421   // If the current stack pointer (as set by SetStackPointer) is sp, then sp
422   // must be aligned to 16 bytes.
423   void Poke(const Register& src, const Operand& offset);
424 
425   // Peek at a value on the stack, and put it in 'dst'. The offset is in bytes.
426   //
427   // If the current stack pointer (as set by SetStackPointer) is sp, then sp
428   // must be aligned to 16 bytes.
429   void Peek(const Register& dst, const Operand& offset);
430 
431   // Alternative forms of Peek and Poke, taking a RegList or CPURegList that
432   // specifies the registers that are to be pushed or popped. Higher-numbered
433   // registers are associated with higher memory addresses.
434   //
435   // (Peek|Poke)SizeRegList allow you to specify the register size as a
436   // parameter. Only kXRegSize, kWRegSize, kDRegSize and kSRegSize are
437   // supported.
438   //
439   // Otherwise, (Peek|Poke)(CPU|X|W|D|S)RegList is preferred.
PeekCPURegList(CPURegList registers,int64_t offset)440   void PeekCPURegList(CPURegList registers, int64_t offset) {
441     LoadCPURegList(registers, MemOperand(StackPointer(), offset));
442   }
PokeCPURegList(CPURegList registers,int64_t offset)443   void PokeCPURegList(CPURegList registers, int64_t offset) {
444     StoreCPURegList(registers, MemOperand(StackPointer(), offset));
445   }
446 
447   void PeekSizeRegList(RegList registers, int64_t offset, unsigned reg_size,
448       CPURegister::RegisterType type = CPURegister::kRegister) {
449     PeekCPURegList(CPURegList(type, reg_size, registers), offset);
450   }
451   void PokeSizeRegList(RegList registers, int64_t offset, unsigned reg_size,
452       CPURegister::RegisterType type = CPURegister::kRegister) {
453     PokeCPURegList(CPURegList(type, reg_size, registers), offset);
454   }
PeekXRegList(RegList regs,int64_t offset)455   void PeekXRegList(RegList regs, int64_t offset) {
456     PeekSizeRegList(regs, offset, kXRegSize);
457   }
PokeXRegList(RegList regs,int64_t offset)458   void PokeXRegList(RegList regs, int64_t offset) {
459     PokeSizeRegList(regs, offset, kXRegSize);
460   }
PeekWRegList(RegList regs,int64_t offset)461   void PeekWRegList(RegList regs, int64_t offset) {
462     PeekSizeRegList(regs, offset, kWRegSize);
463   }
PokeWRegList(RegList regs,int64_t offset)464   void PokeWRegList(RegList regs, int64_t offset) {
465     PokeSizeRegList(regs, offset, kWRegSize);
466   }
PeekDRegList(RegList regs,int64_t offset)467   void PeekDRegList(RegList regs, int64_t offset) {
468     PeekSizeRegList(regs, offset, kDRegSize, CPURegister::kVRegister);
469   }
PokeDRegList(RegList regs,int64_t offset)470   void PokeDRegList(RegList regs, int64_t offset) {
471     PokeSizeRegList(regs, offset, kDRegSize, CPURegister::kVRegister);
472   }
PeekSRegList(RegList regs,int64_t offset)473   void PeekSRegList(RegList regs, int64_t offset) {
474     PeekSizeRegList(regs, offset, kSRegSize, CPURegister::kVRegister);
475   }
PokeSRegList(RegList regs,int64_t offset)476   void PokeSRegList(RegList regs, int64_t offset) {
477     PokeSizeRegList(regs, offset, kSRegSize, CPURegister::kVRegister);
478   }
479 
480 
481   // Claim or drop stack space without actually accessing memory.
482   //
483   // If the current stack pointer (as set by SetStackPointer) is sp, then it
484   // must be aligned to 16 bytes and the size claimed or dropped must be a
485   // multiple of 16 bytes.
486   void Claim(const Operand& size);
487   void Drop(const Operand& size);
488 
489   // Preserve the callee-saved registers (as defined by AAPCS64).
490   //
491   // Higher-numbered registers are pushed before lower-numbered registers, and
492   // thus get higher addresses.
493   // Floating-point registers are pushed before general-purpose registers, and
494   // thus get higher addresses.
495   //
496   // This method must not be called unless StackPointer() is sp, and it is
497   // aligned to 16 bytes.
498   void PushCalleeSavedRegisters();
499 
500   // Restore the callee-saved registers (as defined by AAPCS64).
501   //
502   // Higher-numbered registers are popped after lower-numbered registers, and
503   // thus come from higher addresses.
504   // Floating-point registers are popped after general-purpose registers, and
505   // thus come from higher addresses.
506   //
507   // This method must not be called unless StackPointer() is sp, and it is
508   // aligned to 16 bytes.
509   void PopCalleeSavedRegisters();
510 
511   void LoadCPURegList(CPURegList registers, const MemOperand& src);
512   void StoreCPURegList(CPURegList registers, const MemOperand& dst);
513 
514   // Remaining instructions are simple pass-through calls to the assembler.
Adr(const Register & rd,Label * label)515   void Adr(const Register& rd, Label* label) {
516     VIXL_ASSERT(!rd.IsZero());
517     SingleEmissionCheckScope guard(this);
518     adr(rd, label);
519   }
Adrp(const Register & rd,Label * label)520   void Adrp(const Register& rd, Label* label) {
521     VIXL_ASSERT(!rd.IsZero());
522     SingleEmissionCheckScope guard(this);
523     adrp(rd, label);
524   }
Asr(const Register & rd,const Register & rn,unsigned shift)525   void Asr(const Register& rd, const Register& rn, unsigned shift) {
526     VIXL_ASSERT(!rd.IsZero());
527     VIXL_ASSERT(!rn.IsZero());
528     SingleEmissionCheckScope guard(this);
529     asr(rd, rn, shift);
530   }
Asr(const Register & rd,const Register & rn,const Register & rm)531   void Asr(const Register& rd, const Register& rn, const Register& rm) {
532     VIXL_ASSERT(!rd.IsZero());
533     VIXL_ASSERT(!rn.IsZero());
534     VIXL_ASSERT(!rm.IsZero());
535     SingleEmissionCheckScope guard(this);
536     asrv(rd, rn, rm);
537   }
538 
539   // Branch type inversion relies on these relations.
540   VIXL_STATIC_ASSERT((reg_zero      == (reg_not_zero ^ 1)) &&
541                      (reg_bit_clear == (reg_bit_set ^ 1)) &&
542                      (always        == (never ^ 1)));
543 
InvertBranchType(BranchType type)544   BranchType InvertBranchType(BranchType type) {
545     if (kBranchTypeFirstCondition <= type && type <= kBranchTypeLastCondition) {
546       return static_cast<BranchType>(
547           InvertCondition(static_cast<Condition>(type)));
548     } else {
549       return static_cast<BranchType>(type ^ 1);
550     }
551   }
552 
553   void B(Label* label, BranchType type, Register reg = NoReg, int bit = -1);
554 
555   void B(Label* label);
556   void B(Label* label, Condition cond);
B(Condition cond,Label * label)557   void B(Condition cond, Label* label) {
558     B(label, cond);
559   }
Bfm(const Register & rd,const Register & rn,unsigned immr,unsigned imms)560   void Bfm(const Register& rd,
561            const Register& rn,
562            unsigned immr,
563            unsigned imms) {
564     VIXL_ASSERT(!rd.IsZero());
565     VIXL_ASSERT(!rn.IsZero());
566     SingleEmissionCheckScope guard(this);
567     bfm(rd, rn, immr, imms);
568   }
Bfi(const Register & rd,const Register & rn,unsigned lsb,unsigned width)569   void Bfi(const Register& rd,
570            const Register& rn,
571            unsigned lsb,
572            unsigned width) {
573     VIXL_ASSERT(!rd.IsZero());
574     VIXL_ASSERT(!rn.IsZero());
575     SingleEmissionCheckScope guard(this);
576     bfi(rd, rn, lsb, width);
577   }
Bfxil(const Register & rd,const Register & rn,unsigned lsb,unsigned width)578   void Bfxil(const Register& rd,
579              const Register& rn,
580              unsigned lsb,
581              unsigned width) {
582     VIXL_ASSERT(!rd.IsZero());
583     VIXL_ASSERT(!rn.IsZero());
584     SingleEmissionCheckScope guard(this);
585     bfxil(rd, rn, lsb, width);
586   }
587   void Bind(Label* label);
588   // Bind a label to a specified offset from the start of the buffer.
589   void BindToOffset(Label* label, ptrdiff_t offset);
Bl(Label * label)590   void Bl(Label* label) {
591     SingleEmissionCheckScope guard(this);
592     bl(label);
593   }
Blr(const Register & xn)594   void Blr(const Register& xn) {
595     VIXL_ASSERT(!xn.IsZero());
596     SingleEmissionCheckScope guard(this);
597     blr(xn);
598   }
Br(const Register & xn)599   void Br(const Register& xn) {
600     VIXL_ASSERT(!xn.IsZero());
601     SingleEmissionCheckScope guard(this);
602     br(xn);
603   }
604   void Brk(int code = 0) {
605     SingleEmissionCheckScope guard(this);
606     brk(code);
607   }
608   void Cbnz(const Register& rt, Label* label);
609   void Cbz(const Register& rt, Label* label);
Cinc(const Register & rd,const Register & rn,Condition cond)610   void Cinc(const Register& rd, const Register& rn, Condition cond) {
611     VIXL_ASSERT(!rd.IsZero());
612     VIXL_ASSERT(!rn.IsZero());
613     SingleEmissionCheckScope guard(this);
614     cinc(rd, rn, cond);
615   }
Cinv(const Register & rd,const Register & rn,Condition cond)616   void Cinv(const Register& rd, const Register& rn, Condition cond) {
617     VIXL_ASSERT(!rd.IsZero());
618     VIXL_ASSERT(!rn.IsZero());
619     SingleEmissionCheckScope guard(this);
620     cinv(rd, rn, cond);
621   }
Clrex()622   void Clrex() {
623     SingleEmissionCheckScope guard(this);
624     clrex();
625   }
Cls(const Register & rd,const Register & rn)626   void Cls(const Register& rd, const Register& rn) {
627     VIXL_ASSERT(!rd.IsZero());
628     VIXL_ASSERT(!rn.IsZero());
629     SingleEmissionCheckScope guard(this);
630     cls(rd, rn);
631   }
Clz(const Register & rd,const Register & rn)632   void Clz(const Register& rd, const Register& rn) {
633     VIXL_ASSERT(!rd.IsZero());
634     VIXL_ASSERT(!rn.IsZero());
635     SingleEmissionCheckScope guard(this);
636     clz(rd, rn);
637   }
Cneg(const Register & rd,const Register & rn,Condition cond)638   void Cneg(const Register& rd, const Register& rn, Condition cond) {
639     VIXL_ASSERT(!rd.IsZero());
640     VIXL_ASSERT(!rn.IsZero());
641     SingleEmissionCheckScope guard(this);
642     cneg(rd, rn, cond);
643   }
Cset(const Register & rd,Condition cond)644   void Cset(const Register& rd, Condition cond) {
645     VIXL_ASSERT(!rd.IsZero());
646     SingleEmissionCheckScope guard(this);
647     cset(rd, cond);
648   }
Csetm(const Register & rd,Condition cond)649   void Csetm(const Register& rd, Condition cond) {
650     VIXL_ASSERT(!rd.IsZero());
651     SingleEmissionCheckScope guard(this);
652     csetm(rd, cond);
653   }
Csinc(const Register & rd,const Register & rn,const Register & rm,Condition cond)654   void Csinc(const Register& rd,
655              const Register& rn,
656              const Register& rm,
657              Condition cond) {
658     VIXL_ASSERT(!rd.IsZero());
659     // The VIXL source code contains these assertions, but the AArch64 ISR
660     // explicitly permits the use of zero registers. CSET itself is defined
661     // in terms of CSINC with WZR/XZR.
662     //
663     // VIXL_ASSERT(!rn.IsZero());
664     // VIXL_ASSERT(!rm.IsZero());
665     VIXL_ASSERT((cond != al) && (cond != nv));
666     SingleEmissionCheckScope guard(this);
667     csinc(rd, rn, rm, cond);
668   }
Csinv(const Register & rd,const Register & rn,const Register & rm,Condition cond)669   void Csinv(const Register& rd,
670              const Register& rn,
671              const Register& rm,
672              Condition cond) {
673     VIXL_ASSERT(!rd.IsZero());
674     VIXL_ASSERT(!rn.IsZero());
675     VIXL_ASSERT(!rm.IsZero());
676     VIXL_ASSERT((cond != al) && (cond != nv));
677     SingleEmissionCheckScope guard(this);
678     csinv(rd, rn, rm, cond);
679   }
Csneg(const Register & rd,const Register & rn,const Register & rm,Condition cond)680   void Csneg(const Register& rd,
681              const Register& rn,
682              const Register& rm,
683              Condition cond) {
684     VIXL_ASSERT(!rd.IsZero());
685     VIXL_ASSERT(!rn.IsZero());
686     VIXL_ASSERT(!rm.IsZero());
687     VIXL_ASSERT((cond != al) && (cond != nv));
688     SingleEmissionCheckScope guard(this);
689     csneg(rd, rn, rm, cond);
690   }
Dmb(BarrierDomain domain,BarrierType type)691   void Dmb(BarrierDomain domain, BarrierType type) {
692     SingleEmissionCheckScope guard(this);
693     dmb(domain, type);
694   }
Dsb(BarrierDomain domain,BarrierType type)695   void Dsb(BarrierDomain domain, BarrierType type) {
696     SingleEmissionCheckScope guard(this);
697     dsb(domain, type);
698   }
Extr(const Register & rd,const Register & rn,const Register & rm,unsigned lsb)699   void Extr(const Register& rd,
700             const Register& rn,
701             const Register& rm,
702             unsigned lsb) {
703     VIXL_ASSERT(!rd.IsZero());
704     VIXL_ASSERT(!rn.IsZero());
705     VIXL_ASSERT(!rm.IsZero());
706     SingleEmissionCheckScope guard(this);
707     extr(rd, rn, rm, lsb);
708   }
Fadd(const VRegister & vd,const VRegister & vn,const VRegister & vm)709   void Fadd(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
710     SingleEmissionCheckScope guard(this);
711     fadd(vd, vn, vm);
712   }
713   void Fccmp(const VRegister& vn,
714              const VRegister& vm,
715              StatusFlags nzcv,
716              Condition cond,
717              FPTrapFlags trap = DisableTrap) {
718     VIXL_ASSERT((cond != al) && (cond != nv));
719     SingleEmissionCheckScope guard(this);
720     FPCCompareMacro(vn, vm, nzcv, cond, trap);
721   }
Fccmpe(const VRegister & vn,const VRegister & vm,StatusFlags nzcv,Condition cond)722   void Fccmpe(const VRegister& vn,
723               const VRegister& vm,
724               StatusFlags nzcv,
725               Condition cond) {
726     Fccmp(vn, vm, nzcv, cond, EnableTrap);
727   }
728   void Fcmp(const VRegister& vn, const VRegister& vm,
729             FPTrapFlags trap = DisableTrap) {
730     SingleEmissionCheckScope guard(this);
731     FPCompareMacro(vn, vm, trap);
732   }
733   void Fcmp(const VRegister& vn, double value,
734             FPTrapFlags trap = DisableTrap);
735   void Fcmpe(const VRegister& vn, double value);
Fcmpe(const VRegister & vn,const VRegister & vm)736   void Fcmpe(const VRegister& vn, const VRegister& vm) {
737     Fcmp(vn, vm, EnableTrap);
738   }
Fcsel(const VRegister & vd,const VRegister & vn,const VRegister & vm,Condition cond)739   void Fcsel(const VRegister& vd,
740              const VRegister& vn,
741              const VRegister& vm,
742              Condition cond) {
743     VIXL_ASSERT((cond != al) && (cond != nv));
744     SingleEmissionCheckScope guard(this);
745     fcsel(vd, vn, vm, cond);
746   }
Fcvt(const VRegister & vd,const VRegister & vn)747   void Fcvt(const VRegister& vd, const VRegister& vn) {
748     SingleEmissionCheckScope guard(this);
749     fcvt(vd, vn);
750   }
Fcvtl(const VRegister & vd,const VRegister & vn)751   void Fcvtl(const VRegister& vd, const VRegister& vn) {
752     SingleEmissionCheckScope guard(this);
753     fcvtl(vd, vn);
754   }
Fcvtl2(const VRegister & vd,const VRegister & vn)755   void Fcvtl2(const VRegister& vd, const VRegister& vn) {
756     SingleEmissionCheckScope guard(this);
757     fcvtl2(vd, vn);
758   }
Fcvtn(const VRegister & vd,const VRegister & vn)759   void Fcvtn(const VRegister& vd, const VRegister& vn) {
760     SingleEmissionCheckScope guard(this);
761     fcvtn(vd, vn);
762   }
Fcvtn2(const VRegister & vd,const VRegister & vn)763   void Fcvtn2(const VRegister& vd, const VRegister& vn) {
764     SingleEmissionCheckScope guard(this);
765     fcvtn2(vd, vn);
766   }
Fcvtxn(const VRegister & vd,const VRegister & vn)767   void Fcvtxn(const VRegister& vd, const VRegister& vn) {
768     SingleEmissionCheckScope guard(this);
769     fcvtxn(vd, vn);
770   }
Fcvtxn2(const VRegister & vd,const VRegister & vn)771   void Fcvtxn2(const VRegister& vd, const VRegister& vn) {
772     SingleEmissionCheckScope guard(this);
773     fcvtxn2(vd, vn);
774   }
Fcvtas(const Register & rd,const VRegister & vn)775   void Fcvtas(const Register& rd, const VRegister& vn) {
776     VIXL_ASSERT(!rd.IsZero());
777     SingleEmissionCheckScope guard(this);
778     fcvtas(rd, vn);
779   }
Fcvtau(const Register & rd,const VRegister & vn)780   void Fcvtau(const Register& rd, const VRegister& vn) {
781     VIXL_ASSERT(!rd.IsZero());
782     SingleEmissionCheckScope guard(this);
783     fcvtau(rd, vn);
784   }
Fcvtms(const Register & rd,const VRegister & vn)785   void Fcvtms(const Register& rd, const VRegister& vn) {
786     VIXL_ASSERT(!rd.IsZero());
787     SingleEmissionCheckScope guard(this);
788     fcvtms(rd, vn);
789   }
Fcvtmu(const Register & rd,const VRegister & vn)790   void Fcvtmu(const Register& rd, const VRegister& vn) {
791     VIXL_ASSERT(!rd.IsZero());
792     SingleEmissionCheckScope guard(this);
793     fcvtmu(rd, vn);
794   }
Fcvtns(const Register & rd,const VRegister & vn)795   void Fcvtns(const Register& rd, const VRegister& vn) {
796     VIXL_ASSERT(!rd.IsZero());
797     SingleEmissionCheckScope guard(this);
798     fcvtns(rd, vn);
799   }
Fcvtnu(const Register & rd,const VRegister & vn)800   void Fcvtnu(const Register& rd, const VRegister& vn) {
801     VIXL_ASSERT(!rd.IsZero());
802     SingleEmissionCheckScope guard(this);
803     fcvtnu(rd, vn);
804   }
Fcvtps(const Register & rd,const VRegister & vn)805   void Fcvtps(const Register& rd, const VRegister& vn) {
806     VIXL_ASSERT(!rd.IsZero());
807     SingleEmissionCheckScope guard(this);
808     fcvtps(rd, vn);
809   }
Fcvtpu(const Register & rd,const VRegister & vn)810   void Fcvtpu(const Register& rd, const VRegister& vn) {
811     VIXL_ASSERT(!rd.IsZero());
812     SingleEmissionCheckScope guard(this);
813     fcvtpu(rd, vn);
814   }
815   void Fcvtzs(const Register& rd, const VRegister& vn, int fbits = 0) {
816     VIXL_ASSERT(!rd.IsZero());
817     SingleEmissionCheckScope guard(this);
818     fcvtzs(rd, vn, fbits);
819   }
Fjcvtzs(const Register & rd,const VRegister & vn)820   void Fjcvtzs(const Register& rd, const VRegister& vn) {
821     VIXL_ASSERT(!rd.IsZero());
822     SingleEmissionCheckScope guard(this);
823     fjcvtzs(rd, vn);
824   }
825   void Fcvtzu(const Register& rd, const VRegister& vn, int fbits = 0) {
826     VIXL_ASSERT(!rd.IsZero());
827     SingleEmissionCheckScope guard(this);
828     fcvtzu(rd, vn, fbits);
829   }
Fdiv(const VRegister & vd,const VRegister & vn,const VRegister & vm)830   void Fdiv(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
831     SingleEmissionCheckScope guard(this);
832     fdiv(vd, vn, vm);
833   }
Fmax(const VRegister & vd,const VRegister & vn,const VRegister & vm)834   void Fmax(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
835     SingleEmissionCheckScope guard(this);
836     fmax(vd, vn, vm);
837   }
Fmaxnm(const VRegister & vd,const VRegister & vn,const VRegister & vm)838   void Fmaxnm(const VRegister& vd,
839               const VRegister& vn,
840               const VRegister& vm) {
841     SingleEmissionCheckScope guard(this);
842     fmaxnm(vd, vn, vm);
843   }
Fmin(const VRegister & vd,const VRegister & vn,const VRegister & vm)844   void Fmin(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
845     SingleEmissionCheckScope guard(this);
846     fmin(vd, vn, vm);
847   }
Fminnm(const VRegister & vd,const VRegister & vn,const VRegister & vm)848   void Fminnm(const VRegister& vd,
849               const VRegister& vn,
850               const VRegister& vm) {
851     SingleEmissionCheckScope guard(this);
852     fminnm(vd, vn, vm);
853   }
Fmov(VRegister vd,VRegister vn)854   void Fmov(VRegister vd, VRegister vn) {
855     SingleEmissionCheckScope guard(this);
856     // Only emit an instruction if vd and vn are different, and they are both D
857     // registers. fmov(s0, s0) is not a no-op because it clears the top word of
858     // d0. Technically, fmov(d0, d0) is not a no-op either because it clears
859     // the top of q0, but VRegister does not currently support Q registers.
860     if (!vd.Is(vn) || !vd.Is64Bits()) {
861       fmov(vd, vn);
862     }
863   }
Fmov(VRegister vd,Register rn)864   void Fmov(VRegister vd, Register rn) {
865     SingleEmissionCheckScope guard(this);
866     fmov(vd, rn);
867   }
Fmov(const VRegister & vd,int index,const Register & rn)868   void Fmov(const VRegister& vd, int index, const Register& rn) {
869     SingleEmissionCheckScope guard(this);
870     fmov(vd, index, rn);
871   }
Fmov(const Register & rd,const VRegister & vn,int index)872   void Fmov(const Register& rd, const VRegister& vn, int index) {
873     SingleEmissionCheckScope guard(this);
874     fmov(rd, vn, index);
875   }
876 
877   // Provide explicit double and float interfaces for FP immediate moves, rather
878   // than relying on implicit C++ casts. This allows signalling NaNs to be
879   // preserved when the immediate matches the format of vd. Most systems convert
880   // signalling NaNs to quiet NaNs when converting between float and double.
881   void Fmov(VRegister vd, double imm);
882   void Fmov(VRegister vd, float imm);
883   // Provide a template to allow other types to be converted automatically.
884   template<typename T>
Fmov(VRegister vd,T imm)885   void Fmov(VRegister vd, T imm) {
886     Fmov(vd, static_cast<double>(imm));
887   }
Fmov(Register rd,VRegister vn)888   void Fmov(Register rd, VRegister vn) {
889     VIXL_ASSERT(!rd.IsZero());
890     SingleEmissionCheckScope guard(this);
891     fmov(rd, vn);
892   }
Fmul(const VRegister & vd,const VRegister & vn,const VRegister & vm)893   void Fmul(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
894     SingleEmissionCheckScope guard(this);
895     fmul(vd, vn, vm);
896   }
Fnmul(const VRegister & vd,const VRegister & vn,const VRegister & vm)897   void Fnmul(const VRegister& vd, const VRegister& vn,
898              const VRegister& vm) {
899     SingleEmissionCheckScope guard(this);
900     fnmul(vd, vn, vm);
901   }
Fmadd(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)902   void Fmadd(const VRegister& vd,
903              const VRegister& vn,
904              const VRegister& vm,
905              const VRegister& va) {
906     SingleEmissionCheckScope guard(this);
907     fmadd(vd, vn, vm, va);
908   }
Fmsub(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)909   void Fmsub(const VRegister& vd,
910              const VRegister& vn,
911              const VRegister& vm,
912              const VRegister& va) {
913     SingleEmissionCheckScope guard(this);
914     fmsub(vd, vn, vm, va);
915   }
Fnmadd(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)916   void Fnmadd(const VRegister& vd,
917               const VRegister& vn,
918               const VRegister& vm,
919               const VRegister& va) {
920     SingleEmissionCheckScope guard(this);
921     fnmadd(vd, vn, vm, va);
922   }
Fnmsub(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)923   void Fnmsub(const VRegister& vd,
924               const VRegister& vn,
925               const VRegister& vm,
926               const VRegister& va) {
927     SingleEmissionCheckScope guard(this);
928     fnmsub(vd, vn, vm, va);
929   }
Fsub(const VRegister & vd,const VRegister & vn,const VRegister & vm)930   void Fsub(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
931     SingleEmissionCheckScope guard(this);
932     fsub(vd, vn, vm);
933   }
Hint(SystemHint code)934   void Hint(SystemHint code) {
935     SingleEmissionCheckScope guard(this);
936     hint(code);
937   }
Hlt(int code)938   void Hlt(int code) {
939     SingleEmissionCheckScope guard(this);
940     hlt(code);
941   }
Isb()942   void Isb() {
943     SingleEmissionCheckScope guard(this);
944     isb();
945   }
Ldar(const Register & rt,const MemOperand & src)946   void Ldar(const Register& rt, const MemOperand& src) {
947     SingleEmissionCheckScope guard(this);
948     ldar(rt, src);
949   }
Ldarb(const Register & rt,const MemOperand & src)950   void Ldarb(const Register& rt, const MemOperand& src) {
951     SingleEmissionCheckScope guard(this);
952     ldarb(rt, src);
953   }
Ldarh(const Register & rt,const MemOperand & src)954   void Ldarh(const Register& rt, const MemOperand& src) {
955     SingleEmissionCheckScope guard(this);
956     ldarh(rt, src);
957   }
Ldaxp(const Register & rt,const Register & rt2,const MemOperand & src)958   void Ldaxp(const Register& rt, const Register& rt2, const MemOperand& src) {
959     VIXL_ASSERT(!rt.Aliases(rt2));
960     SingleEmissionCheckScope guard(this);
961     ldaxp(rt, rt2, src);
962   }
Ldaxr(const Register & rt,const MemOperand & src)963   void Ldaxr(const Register& rt, const MemOperand& src) {
964     SingleEmissionCheckScope guard(this);
965     ldaxr(rt, src);
966   }
Ldaxrb(const Register & rt,const MemOperand & src)967   void Ldaxrb(const Register& rt, const MemOperand& src) {
968     SingleEmissionCheckScope guard(this);
969     ldaxrb(rt, src);
970   }
Ldaxrh(const Register & rt,const MemOperand & src)971   void Ldaxrh(const Register& rt, const MemOperand& src) {
972     SingleEmissionCheckScope guard(this);
973     ldaxrh(rt, src);
974   }
Ldnp(const CPURegister & rt,const CPURegister & rt2,const MemOperand & src)975   void Ldnp(const CPURegister& rt,
976             const CPURegister& rt2,
977             const MemOperand& src) {
978     SingleEmissionCheckScope guard(this);
979     ldnp(rt, rt2, src);
980   }
981   // Provide both double and float interfaces for FP immediate loads, rather
982   // than relying on implicit C++ casts. This allows signalling NaNs to be
983   // preserved when the immediate matches the format of fd. Most systems convert
984   // signalling NaNs to quiet NaNs when converting between float and double.
Ldr(const VRegister & vt,double imm)985   void Ldr(const VRegister& vt, double imm) {
986     SingleEmissionCheckScope guard(this);
987     if (vt.Is64Bits()) {
988       ldr(vt, imm);
989     } else {
990       ldr(vt, static_cast<float>(imm));
991     }
992   }
Ldr(const VRegister & vt,float imm)993   void Ldr(const VRegister& vt, float imm) {
994     SingleEmissionCheckScope guard(this);
995     if (vt.Is32Bits()) {
996       ldr(vt, imm);
997     } else {
998       ldr(vt, static_cast<double>(imm));
999     }
1000   }
1001   /*
1002   void Ldr(const VRegister& vt, uint64_t high64, uint64_t low64) {
1003     VIXL_ASSERT(vt.IsQ());
1004     SingleEmissionCheckScope guard(this);
1005     ldr(vt, new Literal<uint64_t>(high64, low64,
1006                                   &literal_pool_,
1007                                   RawLiteral::kDeletedOnPlacementByPool));
1008   }
1009   */
Ldr(const Register & rt,uint64_t imm)1010   void Ldr(const Register& rt, uint64_t imm) {
1011     VIXL_ASSERT(!rt.IsZero());
1012     SingleEmissionCheckScope guard(this);
1013     ldr(rt, imm);
1014   }
Ldrsw(const Register & rt,uint32_t imm)1015   void Ldrsw(const Register& rt, uint32_t imm) {
1016     VIXL_ASSERT(!rt.IsZero());
1017     SingleEmissionCheckScope guard(this);
1018     ldrsw(rt, imm);
1019   }
Ldxp(const Register & rt,const Register & rt2,const MemOperand & src)1020   void Ldxp(const Register& rt, const Register& rt2, const MemOperand& src) {
1021     VIXL_ASSERT(!rt.Aliases(rt2));
1022     SingleEmissionCheckScope guard(this);
1023     ldxp(rt, rt2, src);
1024   }
Ldxr(const Register & rt,const MemOperand & src)1025   void Ldxr(const Register& rt, const MemOperand& src) {
1026     SingleEmissionCheckScope guard(this);
1027     ldxr(rt, src);
1028   }
Ldxrb(const Register & rt,const MemOperand & src)1029   void Ldxrb(const Register& rt, const MemOperand& src) {
1030     SingleEmissionCheckScope guard(this);
1031     ldxrb(rt, src);
1032   }
Ldxrh(const Register & rt,const MemOperand & src)1033   void Ldxrh(const Register& rt, const MemOperand& src) {
1034     SingleEmissionCheckScope guard(this);
1035     ldxrh(rt, src);
1036   }
Lsl(const Register & rd,const Register & rn,unsigned shift)1037   void Lsl(const Register& rd, const Register& rn, unsigned shift) {
1038     VIXL_ASSERT(!rd.IsZero());
1039     VIXL_ASSERT(!rn.IsZero());
1040     SingleEmissionCheckScope guard(this);
1041     lsl(rd, rn, shift);
1042   }
Lsl(const Register & rd,const Register & rn,const Register & rm)1043   void Lsl(const Register& rd, const Register& rn, const Register& rm) {
1044     VIXL_ASSERT(!rd.IsZero());
1045     VIXL_ASSERT(!rn.IsZero());
1046     VIXL_ASSERT(!rm.IsZero());
1047     SingleEmissionCheckScope guard(this);
1048     lslv(rd, rn, rm);
1049   }
Lsr(const Register & rd,const Register & rn,unsigned shift)1050   void Lsr(const Register& rd, const Register& rn, unsigned shift) {
1051     VIXL_ASSERT(!rd.IsZero());
1052     VIXL_ASSERT(!rn.IsZero());
1053     SingleEmissionCheckScope guard(this);
1054     lsr(rd, rn, shift);
1055   }
Lsr(const Register & rd,const Register & rn,const Register & rm)1056   void Lsr(const Register& rd, const Register& rn, const Register& rm) {
1057     VIXL_ASSERT(!rd.IsZero());
1058     VIXL_ASSERT(!rn.IsZero());
1059     VIXL_ASSERT(!rm.IsZero());
1060     SingleEmissionCheckScope guard(this);
1061     lsrv(rd, rn, rm);
1062   }
Madd(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1063   void Madd(const Register& rd,
1064             const Register& rn,
1065             const Register& rm,
1066             const Register& ra) {
1067     VIXL_ASSERT(!rd.IsZero());
1068     VIXL_ASSERT(!rn.IsZero());
1069     VIXL_ASSERT(!rm.IsZero());
1070     VIXL_ASSERT(!ra.IsZero());
1071     SingleEmissionCheckScope guard(this);
1072     madd(rd, rn, rm, ra);
1073   }
Mneg(const Register & rd,const Register & rn,const Register & rm)1074   void Mneg(const Register& rd, const Register& rn, const Register& rm) {
1075     VIXL_ASSERT(!rd.IsZero());
1076     VIXL_ASSERT(!rn.IsZero());
1077     VIXL_ASSERT(!rm.IsZero());
1078     SingleEmissionCheckScope guard(this);
1079     mneg(rd, rn, rm);
1080   }
Mov(const Register & rd,const Register & rn)1081   void Mov(const Register& rd, const Register& rn) {
1082     SingleEmissionCheckScope guard(this);
1083     mov(rd, rn);
1084   }
1085   void Movk(const Register& rd, uint64_t imm, int shift = -1) {
1086     VIXL_ASSERT(!rd.IsZero());
1087     SingleEmissionCheckScope guard(this);
1088     movk(rd, imm, shift);
1089   }
Mrs(const Register & rt,SystemRegister sysreg)1090   void Mrs(const Register& rt, SystemRegister sysreg) {
1091     VIXL_ASSERT(!rt.IsZero());
1092     SingleEmissionCheckScope guard(this);
1093     mrs(rt, sysreg);
1094   }
Msr(SystemRegister sysreg,const Register & rt)1095   void Msr(SystemRegister sysreg, const Register& rt) {
1096     VIXL_ASSERT(!rt.IsZero());
1097     SingleEmissionCheckScope guard(this);
1098     msr(sysreg, rt);
1099   }
1100   void Sys(int op1, int crn, int crm, int op2, const Register& rt = xzr) {
1101     SingleEmissionCheckScope guard(this);
1102     sys(op1, crn, crm, op2, rt);
1103   }
Dc(DataCacheOp op,const Register & rt)1104   void Dc(DataCacheOp op, const Register& rt) {
1105     SingleEmissionCheckScope guard(this);
1106     dc(op, rt);
1107   }
Ic(InstructionCacheOp op,const Register & rt)1108   void Ic(InstructionCacheOp op, const Register& rt) {
1109     SingleEmissionCheckScope guard(this);
1110     ic(op, rt);
1111   }
Msub(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1112   void Msub(const Register& rd,
1113             const Register& rn,
1114             const Register& rm,
1115             const Register& ra) {
1116     VIXL_ASSERT(!rd.IsZero());
1117     VIXL_ASSERT(!rn.IsZero());
1118     VIXL_ASSERT(!rm.IsZero());
1119     VIXL_ASSERT(!ra.IsZero());
1120     SingleEmissionCheckScope guard(this);
1121     msub(rd, rn, rm, ra);
1122   }
Mul(const Register & rd,const Register & rn,const Register & rm)1123   void Mul(const Register& rd, const Register& rn, const Register& rm) {
1124     VIXL_ASSERT(!rd.IsZero());
1125     VIXL_ASSERT(!rn.IsZero());
1126     VIXL_ASSERT(!rm.IsZero());
1127     SingleEmissionCheckScope guard(this);
1128     mul(rd, rn, rm);
1129   }
Nop()1130   void Nop() {
1131     SingleEmissionCheckScope guard(this);
1132     nop();
1133   }
Csdb()1134   void Csdb() {
1135     SingleEmissionCheckScope guard(this);
1136     csdb();
1137   }
Rbit(const Register & rd,const Register & rn)1138   void Rbit(const Register& rd, const Register& rn) {
1139     VIXL_ASSERT(!rd.IsZero());
1140     VIXL_ASSERT(!rn.IsZero());
1141     SingleEmissionCheckScope guard(this);
1142     rbit(rd, rn);
1143   }
1144   void Ret(const Register& xn = lr) {
1145     VIXL_ASSERT(!xn.IsZero());
1146     SingleEmissionCheckScope guard(this);
1147     ret(xn);
1148   }
Rev(const Register & rd,const Register & rn)1149   void Rev(const Register& rd, const Register& rn) {
1150     VIXL_ASSERT(!rd.IsZero());
1151     VIXL_ASSERT(!rn.IsZero());
1152     SingleEmissionCheckScope guard(this);
1153     rev(rd, rn);
1154   }
Rev16(const Register & rd,const Register & rn)1155   void Rev16(const Register& rd, const Register& rn) {
1156     VIXL_ASSERT(!rd.IsZero());
1157     VIXL_ASSERT(!rn.IsZero());
1158     SingleEmissionCheckScope guard(this);
1159     rev16(rd, rn);
1160   }
Rev32(const Register & rd,const Register & rn)1161   void Rev32(const Register& rd, const Register& rn) {
1162     VIXL_ASSERT(!rd.IsZero());
1163     VIXL_ASSERT(!rn.IsZero());
1164     SingleEmissionCheckScope guard(this);
1165     rev32(rd, rn);
1166   }
Ror(const Register & rd,const Register & rs,unsigned shift)1167   void Ror(const Register& rd, const Register& rs, unsigned shift) {
1168     VIXL_ASSERT(!rd.IsZero());
1169     VIXL_ASSERT(!rs.IsZero());
1170     SingleEmissionCheckScope guard(this);
1171     ror(rd, rs, shift);
1172   }
Ror(const Register & rd,const Register & rn,const Register & rm)1173   void Ror(const Register& rd, const Register& rn, const Register& rm) {
1174     VIXL_ASSERT(!rd.IsZero());
1175     VIXL_ASSERT(!rn.IsZero());
1176     VIXL_ASSERT(!rm.IsZero());
1177     SingleEmissionCheckScope guard(this);
1178     rorv(rd, rn, rm);
1179   }
Sbfiz(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1180   void Sbfiz(const Register& rd,
1181              const Register& rn,
1182              unsigned lsb,
1183              unsigned width) {
1184     VIXL_ASSERT(!rd.IsZero());
1185     VIXL_ASSERT(!rn.IsZero());
1186     SingleEmissionCheckScope guard(this);
1187     sbfiz(rd, rn, lsb, width);
1188   }
Sbfm(const Register & rd,const Register & rn,unsigned immr,unsigned imms)1189   void Sbfm(const Register& rd,
1190             const Register& rn,
1191             unsigned immr,
1192             unsigned imms) {
1193     VIXL_ASSERT(!rd.IsZero());
1194     VIXL_ASSERT(!rn.IsZero());
1195     SingleEmissionCheckScope guard(this);
1196     sbfm(rd, rn, immr, imms);
1197   }
Sbfx(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1198   void Sbfx(const Register& rd,
1199             const Register& rn,
1200             unsigned lsb,
1201             unsigned width) {
1202     VIXL_ASSERT(!rd.IsZero());
1203     VIXL_ASSERT(!rn.IsZero());
1204     SingleEmissionCheckScope guard(this);
1205     sbfx(rd, rn, lsb, width);
1206   }
1207   void Scvtf(const VRegister& vd, const Register& rn, int fbits = 0) {
1208     VIXL_ASSERT(!rn.IsZero());
1209     SingleEmissionCheckScope guard(this);
1210     scvtf(vd, rn, fbits);
1211   }
Sdiv(const Register & rd,const Register & rn,const Register & rm)1212   void Sdiv(const Register& rd, const Register& rn, const Register& rm) {
1213     VIXL_ASSERT(!rd.IsZero());
1214     VIXL_ASSERT(!rn.IsZero());
1215     VIXL_ASSERT(!rm.IsZero());
1216     SingleEmissionCheckScope guard(this);
1217     sdiv(rd, rn, rm);
1218   }
Smaddl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1219   void Smaddl(const Register& rd,
1220               const Register& rn,
1221               const Register& rm,
1222               const Register& ra) {
1223     VIXL_ASSERT(!rd.IsZero());
1224     VIXL_ASSERT(!rn.IsZero());
1225     VIXL_ASSERT(!rm.IsZero());
1226     VIXL_ASSERT(!ra.IsZero());
1227     SingleEmissionCheckScope guard(this);
1228     smaddl(rd, rn, rm, ra);
1229   }
Smsubl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1230   void Smsubl(const Register& rd,
1231               const Register& rn,
1232               const Register& rm,
1233               const Register& ra) {
1234     VIXL_ASSERT(!rd.IsZero());
1235     VIXL_ASSERT(!rn.IsZero());
1236     VIXL_ASSERT(!rm.IsZero());
1237     VIXL_ASSERT(!ra.IsZero());
1238     SingleEmissionCheckScope guard(this);
1239     smsubl(rd, rn, rm, ra);
1240   }
Smull(const Register & rd,const Register & rn,const Register & rm)1241   void Smull(const Register& rd, const Register& rn, const Register& rm) {
1242     VIXL_ASSERT(!rd.IsZero());
1243     VIXL_ASSERT(!rn.IsZero());
1244     VIXL_ASSERT(!rm.IsZero());
1245     SingleEmissionCheckScope guard(this);
1246     smull(rd, rn, rm);
1247   }
Smulh(const Register & xd,const Register & xn,const Register & xm)1248   void Smulh(const Register& xd, const Register& xn, const Register& xm) {
1249     VIXL_ASSERT(!xd.IsZero());
1250     VIXL_ASSERT(!xn.IsZero());
1251     VIXL_ASSERT(!xm.IsZero());
1252     SingleEmissionCheckScope guard(this);
1253     smulh(xd, xn, xm);
1254   }
Stlr(const Register & rt,const MemOperand & dst)1255   void Stlr(const Register& rt, const MemOperand& dst) {
1256     SingleEmissionCheckScope guard(this);
1257     stlr(rt, dst);
1258   }
Stlrb(const Register & rt,const MemOperand & dst)1259   void Stlrb(const Register& rt, const MemOperand& dst) {
1260     SingleEmissionCheckScope guard(this);
1261     stlrb(rt, dst);
1262   }
Stlrh(const Register & rt,const MemOperand & dst)1263   void Stlrh(const Register& rt, const MemOperand& dst) {
1264     SingleEmissionCheckScope guard(this);
1265     stlrh(rt, dst);
1266   }
Stlxp(const Register & rs,const Register & rt,const Register & rt2,const MemOperand & dst)1267   void Stlxp(const Register& rs,
1268              const Register& rt,
1269              const Register& rt2,
1270              const MemOperand& dst) {
1271     VIXL_ASSERT(!rs.Aliases(dst.base()));
1272     VIXL_ASSERT(!rs.Aliases(rt));
1273     VIXL_ASSERT(!rs.Aliases(rt2));
1274     SingleEmissionCheckScope guard(this);
1275     stlxp(rs, rt, rt2, dst);
1276   }
Stlxr(const Register & rs,const Register & rt,const MemOperand & dst)1277   void Stlxr(const Register& rs, const Register& rt, const MemOperand& dst) {
1278     VIXL_ASSERT(!rs.Aliases(dst.base()));
1279     VIXL_ASSERT(!rs.Aliases(rt));
1280     SingleEmissionCheckScope guard(this);
1281     stlxr(rs, rt, dst);
1282   }
Stlxrb(const Register & rs,const Register & rt,const MemOperand & dst)1283   void Stlxrb(const Register& rs, const Register& rt, const MemOperand& dst) {
1284     VIXL_ASSERT(!rs.Aliases(dst.base()));
1285     VIXL_ASSERT(!rs.Aliases(rt));
1286     SingleEmissionCheckScope guard(this);
1287     stlxrb(rs, rt, dst);
1288   }
Stlxrh(const Register & rs,const Register & rt,const MemOperand & dst)1289   void Stlxrh(const Register& rs, const Register& rt, const MemOperand& dst) {
1290     VIXL_ASSERT(!rs.Aliases(dst.base()));
1291     VIXL_ASSERT(!rs.Aliases(rt));
1292     SingleEmissionCheckScope guard(this);
1293     stlxrh(rs, rt, dst);
1294   }
Stnp(const CPURegister & rt,const CPURegister & rt2,const MemOperand & dst)1295   void Stnp(const CPURegister& rt,
1296             const CPURegister& rt2,
1297             const MemOperand& dst) {
1298     SingleEmissionCheckScope guard(this);
1299     stnp(rt, rt2, dst);
1300   }
Stxp(const Register & rs,const Register & rt,const Register & rt2,const MemOperand & dst)1301   void Stxp(const Register& rs,
1302             const Register& rt,
1303             const Register& rt2,
1304             const MemOperand& dst) {
1305     VIXL_ASSERT(!rs.Aliases(dst.base()));
1306     VIXL_ASSERT(!rs.Aliases(rt));
1307     VIXL_ASSERT(!rs.Aliases(rt2));
1308     SingleEmissionCheckScope guard(this);
1309     stxp(rs, rt, rt2, dst);
1310   }
Stxr(const Register & rs,const Register & rt,const MemOperand & dst)1311   void Stxr(const Register& rs, const Register& rt, const MemOperand& dst) {
1312     VIXL_ASSERT(!rs.Aliases(dst.base()));
1313     VIXL_ASSERT(!rs.Aliases(rt));
1314     SingleEmissionCheckScope guard(this);
1315     stxr(rs, rt, dst);
1316   }
Stxrb(const Register & rs,const Register & rt,const MemOperand & dst)1317   void Stxrb(const Register& rs, const Register& rt, const MemOperand& dst) {
1318     VIXL_ASSERT(!rs.Aliases(dst.base()));
1319     VIXL_ASSERT(!rs.Aliases(rt));
1320     SingleEmissionCheckScope guard(this);
1321     stxrb(rs, rt, dst);
1322   }
Stxrh(const Register & rs,const Register & rt,const MemOperand & dst)1323   void Stxrh(const Register& rs, const Register& rt, const MemOperand& dst) {
1324     VIXL_ASSERT(!rs.Aliases(dst.base()));
1325     VIXL_ASSERT(!rs.Aliases(rt));
1326     SingleEmissionCheckScope guard(this);
1327     stxrh(rs, rt, dst);
1328   }
Svc(int code)1329   void Svc(int code) {
1330     SingleEmissionCheckScope guard(this);
1331     svc(code);
1332   }
Sxtb(const Register & rd,const Register & rn)1333   void Sxtb(const Register& rd, const Register& rn) {
1334     VIXL_ASSERT(!rd.IsZero());
1335     VIXL_ASSERT(!rn.IsZero());
1336     SingleEmissionCheckScope guard(this);
1337     sxtb(rd, rn);
1338   }
Sxth(const Register & rd,const Register & rn)1339   void Sxth(const Register& rd, const Register& rn) {
1340     VIXL_ASSERT(!rd.IsZero());
1341     VIXL_ASSERT(!rn.IsZero());
1342     SingleEmissionCheckScope guard(this);
1343     sxth(rd, rn);
1344   }
Sxtw(const Register & rd,const Register & rn)1345   void Sxtw(const Register& rd, const Register& rn) {
1346     VIXL_ASSERT(!rd.IsZero());
1347     VIXL_ASSERT(!rn.IsZero());
1348     SingleEmissionCheckScope guard(this);
1349     sxtw(rd, rn);
1350   }
Tbl(const VRegister & vd,const VRegister & vn,const VRegister & vm)1351   void Tbl(const VRegister& vd,
1352            const VRegister& vn,
1353            const VRegister& vm) {
1354     SingleEmissionCheckScope guard(this);
1355     tbl(vd, vn, vm);
1356   }
Tbl(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vm)1357   void Tbl(const VRegister& vd,
1358            const VRegister& vn,
1359            const VRegister& vn2,
1360            const VRegister& vm) {
1361     SingleEmissionCheckScope guard(this);
1362     tbl(vd, vn, vn2, vm);
1363   }
Tbl(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vn3,const VRegister & vm)1364   void Tbl(const VRegister& vd,
1365            const VRegister& vn,
1366            const VRegister& vn2,
1367            const VRegister& vn3,
1368            const VRegister& vm) {
1369     SingleEmissionCheckScope guard(this);
1370     tbl(vd, vn, vn2, vn3, vm);
1371   }
Tbl(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vn3,const VRegister & vn4,const VRegister & vm)1372   void Tbl(const VRegister& vd,
1373            const VRegister& vn,
1374            const VRegister& vn2,
1375            const VRegister& vn3,
1376            const VRegister& vn4,
1377            const VRegister& vm) {
1378     SingleEmissionCheckScope guard(this);
1379     tbl(vd, vn, vn2, vn3, vn4, vm);
1380   }
Tbx(const VRegister & vd,const VRegister & vn,const VRegister & vm)1381   void Tbx(const VRegister& vd,
1382            const VRegister& vn,
1383            const VRegister& vm) {
1384     SingleEmissionCheckScope guard(this);
1385     tbx(vd, vn, vm);
1386   }
Tbx(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vm)1387   void Tbx(const VRegister& vd,
1388            const VRegister& vn,
1389            const VRegister& vn2,
1390            const VRegister& vm) {
1391     SingleEmissionCheckScope guard(this);
1392     tbx(vd, vn, vn2, vm);
1393   }
Tbx(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vn3,const VRegister & vm)1394   void Tbx(const VRegister& vd,
1395            const VRegister& vn,
1396            const VRegister& vn2,
1397            const VRegister& vn3,
1398            const VRegister& vm) {
1399     SingleEmissionCheckScope guard(this);
1400     tbx(vd, vn, vn2, vn3, vm);
1401   }
Tbx(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vn3,const VRegister & vn4,const VRegister & vm)1402   void Tbx(const VRegister& vd,
1403            const VRegister& vn,
1404            const VRegister& vn2,
1405            const VRegister& vn3,
1406            const VRegister& vn4,
1407            const VRegister& vm) {
1408     SingleEmissionCheckScope guard(this);
1409     tbx(vd, vn, vn2, vn3, vn4, vm);
1410   }
1411   void Tbnz(const Register& rt, unsigned bit_pos, Label* label);
1412   void Tbz(const Register& rt, unsigned bit_pos, Label* label);
Ubfiz(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1413   void Ubfiz(const Register& rd,
1414              const Register& rn,
1415              unsigned lsb,
1416              unsigned width) {
1417     VIXL_ASSERT(!rd.IsZero());
1418     VIXL_ASSERT(!rn.IsZero());
1419     SingleEmissionCheckScope guard(this);
1420     ubfiz(rd, rn, lsb, width);
1421   }
Ubfm(const Register & rd,const Register & rn,unsigned immr,unsigned imms)1422   void Ubfm(const Register& rd,
1423             const Register& rn,
1424             unsigned immr,
1425             unsigned imms) {
1426     VIXL_ASSERT(!rd.IsZero());
1427     VIXL_ASSERT(!rn.IsZero());
1428     SingleEmissionCheckScope guard(this);
1429     ubfm(rd, rn, immr, imms);
1430   }
Ubfx(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1431   void Ubfx(const Register& rd,
1432             const Register& rn,
1433             unsigned lsb,
1434             unsigned width) {
1435     VIXL_ASSERT(!rd.IsZero());
1436     VIXL_ASSERT(!rn.IsZero());
1437     SingleEmissionCheckScope guard(this);
1438     ubfx(rd, rn, lsb, width);
1439   }
1440   void Ucvtf(const VRegister& vd, const Register& rn, int fbits = 0) {
1441     VIXL_ASSERT(!rn.IsZero());
1442     SingleEmissionCheckScope guard(this);
1443     ucvtf(vd, rn, fbits);
1444   }
Udiv(const Register & rd,const Register & rn,const Register & rm)1445   void Udiv(const Register& rd, const Register& rn, const Register& rm) {
1446     VIXL_ASSERT(!rd.IsZero());
1447     VIXL_ASSERT(!rn.IsZero());
1448     VIXL_ASSERT(!rm.IsZero());
1449     SingleEmissionCheckScope guard(this);
1450     udiv(rd, rn, rm);
1451   }
Umaddl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1452   void Umaddl(const Register& rd,
1453               const Register& rn,
1454               const Register& rm,
1455               const Register& ra) {
1456     VIXL_ASSERT(!rd.IsZero());
1457     VIXL_ASSERT(!rn.IsZero());
1458     VIXL_ASSERT(!rm.IsZero());
1459     VIXL_ASSERT(!ra.IsZero());
1460     SingleEmissionCheckScope guard(this);
1461     umaddl(rd, rn, rm, ra);
1462   }
Umull(const Register & rd,const Register & rn,const Register & rm)1463   void Umull(const Register& rd,
1464              const Register& rn,
1465              const Register& rm) {
1466     VIXL_ASSERT(!rd.IsZero());
1467     VIXL_ASSERT(!rn.IsZero());
1468     VIXL_ASSERT(!rm.IsZero());
1469     SingleEmissionCheckScope guard(this);
1470     umull(rd, rn, rm);
1471   }
Umulh(const Register & xd,const Register & xn,const Register & xm)1472   void Umulh(const Register& xd, const Register& xn, const Register& xm) {
1473     VIXL_ASSERT(!xd.IsZero());
1474     VIXL_ASSERT(!xn.IsZero());
1475     VIXL_ASSERT(!xm.IsZero());
1476     SingleEmissionCheckScope guard(this);
1477     umulh(xd, xn, xm);
1478   }
Umsubl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1479   void Umsubl(const Register& rd,
1480               const Register& rn,
1481               const Register& rm,
1482               const Register& ra) {
1483     VIXL_ASSERT(!rd.IsZero());
1484     VIXL_ASSERT(!rn.IsZero());
1485     VIXL_ASSERT(!rm.IsZero());
1486     VIXL_ASSERT(!ra.IsZero());
1487     SingleEmissionCheckScope guard(this);
1488     umsubl(rd, rn, rm, ra);
1489   }
1490 
Unreachable()1491   void Unreachable() {
1492     SingleEmissionCheckScope guard(this);
1493     Emit(UNDEFINED_INST_PATTERN);
1494   }
1495 
Uxtb(const Register & rd,const Register & rn)1496   void Uxtb(const Register& rd, const Register& rn) {
1497     VIXL_ASSERT(!rd.IsZero());
1498     VIXL_ASSERT(!rn.IsZero());
1499     SingleEmissionCheckScope guard(this);
1500     uxtb(rd, rn);
1501   }
Uxth(const Register & rd,const Register & rn)1502   void Uxth(const Register& rd, const Register& rn) {
1503     VIXL_ASSERT(!rd.IsZero());
1504     VIXL_ASSERT(!rn.IsZero());
1505     SingleEmissionCheckScope guard(this);
1506     uxth(rd, rn);
1507   }
Uxtw(const Register & rd,const Register & rn)1508   void Uxtw(const Register& rd, const Register& rn) {
1509     VIXL_ASSERT(!rd.IsZero());
1510     VIXL_ASSERT(!rn.IsZero());
1511     SingleEmissionCheckScope guard(this);
1512     uxtw(rd, rn);
1513   }
1514 
1515   // NEON 3 vector register instructions.
1516   #define NEON_3VREG_MACRO_LIST(V) \
1517     V(add, Add)                    \
1518     V(addhn, Addhn)                \
1519     V(addhn2, Addhn2)              \
1520     V(addp, Addp)                  \
1521     V(and_, And)                   \
1522     V(bic, Bic)                    \
1523     V(bif, Bif)                    \
1524     V(bit, Bit)                    \
1525     V(bsl, Bsl)                    \
1526     V(cmeq, Cmeq)                  \
1527     V(cmge, Cmge)                  \
1528     V(cmgt, Cmgt)                  \
1529     V(cmhi, Cmhi)                  \
1530     V(cmhs, Cmhs)                  \
1531     V(cmtst, Cmtst)                \
1532     V(eor, Eor)                    \
1533     V(fabd, Fabd)                  \
1534     V(facge, Facge)                \
1535     V(facgt, Facgt)                \
1536     V(faddp, Faddp)                \
1537     V(fcmeq, Fcmeq)                \
1538     V(fcmge, Fcmge)                \
1539     V(fcmgt, Fcmgt)                \
1540     V(fmaxnmp, Fmaxnmp)            \
1541     V(fmaxp, Fmaxp)                \
1542     V(fminnmp, Fminnmp)            \
1543     V(fminp, Fminp)                \
1544     V(fmla, Fmla)                  \
1545     V(fmls, Fmls)                  \
1546     V(fmulx, Fmulx)                \
1547     V(frecps, Frecps)              \
1548     V(frsqrts, Frsqrts)            \
1549     V(mla, Mla)                    \
1550     V(mls, Mls)                    \
1551     V(mul, Mul)                    \
1552     V(orn, Orn)                    \
1553     V(orr, Orr)                    \
1554     V(pmul, Pmul)                  \
1555     V(pmull, Pmull)                \
1556     V(pmull2, Pmull2)              \
1557     V(raddhn, Raddhn)              \
1558     V(raddhn2, Raddhn2)            \
1559     V(rsubhn, Rsubhn)              \
1560     V(rsubhn2, Rsubhn2)            \
1561     V(saba, Saba)                  \
1562     V(sabal, Sabal)                \
1563     V(sabal2, Sabal2)              \
1564     V(sabd, Sabd)                  \
1565     V(sabdl, Sabdl)                \
1566     V(sabdl2, Sabdl2)              \
1567     V(saddl, Saddl)                \
1568     V(saddl2, Saddl2)              \
1569     V(saddw, Saddw)                \
1570     V(saddw2, Saddw2)              \
1571     V(shadd, Shadd)                \
1572     V(shsub, Shsub)                \
1573     V(smax, Smax)                  \
1574     V(smaxp, Smaxp)                \
1575     V(smin, Smin)                  \
1576     V(sminp, Sminp)                \
1577     V(smlal, Smlal)                \
1578     V(smlal2, Smlal2)              \
1579     V(smlsl, Smlsl)                \
1580     V(smlsl2, Smlsl2)              \
1581     V(smull, Smull)                \
1582     V(smull2, Smull2)              \
1583     V(sqadd, Sqadd)                \
1584     V(sqdmlal, Sqdmlal)            \
1585     V(sqdmlal2, Sqdmlal2)          \
1586     V(sqdmlsl, Sqdmlsl)            \
1587     V(sqdmlsl2, Sqdmlsl2)          \
1588     V(sqdmulh, Sqdmulh)            \
1589     V(sqdmull, Sqdmull)            \
1590     V(sqdmull2, Sqdmull2)          \
1591     V(sqrdmulh, Sqrdmulh)          \
1592     V(sqrshl, Sqrshl)              \
1593     V(sqshl, Sqshl)                \
1594     V(sqsub, Sqsub)                \
1595     V(srhadd, Srhadd)              \
1596     V(srshl, Srshl)                \
1597     V(sshl, Sshl)                  \
1598     V(ssubl, Ssubl)                \
1599     V(ssubl2, Ssubl2)              \
1600     V(ssubw, Ssubw)                \
1601     V(ssubw2, Ssubw2)              \
1602     V(sub, Sub)                    \
1603     V(subhn, Subhn)                \
1604     V(subhn2, Subhn2)              \
1605     V(trn1, Trn1)                  \
1606     V(trn2, Trn2)                  \
1607     V(uaba, Uaba)                  \
1608     V(uabal, Uabal)                \
1609     V(uabal2, Uabal2)              \
1610     V(uabd, Uabd)                  \
1611     V(uabdl, Uabdl)                \
1612     V(uabdl2, Uabdl2)              \
1613     V(uaddl, Uaddl)                \
1614     V(uaddl2, Uaddl2)              \
1615     V(uaddw, Uaddw)                \
1616     V(uaddw2, Uaddw2)              \
1617     V(uhadd, Uhadd)                \
1618     V(uhsub, Uhsub)                \
1619     V(umax, Umax)                  \
1620     V(umaxp, Umaxp)                \
1621     V(umin, Umin)                  \
1622     V(uminp, Uminp)                \
1623     V(umlal, Umlal)                \
1624     V(umlal2, Umlal2)              \
1625     V(umlsl, Umlsl)                \
1626     V(umlsl2, Umlsl2)              \
1627     V(umull, Umull)                \
1628     V(umull2, Umull2)              \
1629     V(uqadd, Uqadd)                \
1630     V(uqrshl, Uqrshl)              \
1631     V(uqshl, Uqshl)                \
1632     V(uqsub, Uqsub)                \
1633     V(urhadd, Urhadd)              \
1634     V(urshl, Urshl)                \
1635     V(ushl, Ushl)                  \
1636     V(usubl, Usubl)                \
1637     V(usubl2, Usubl2)              \
1638     V(usubw, Usubw)                \
1639     V(usubw2, Usubw2)              \
1640     V(uzp1, Uzp1)                  \
1641     V(uzp2, Uzp2)                  \
1642     V(zip1, Zip1)                  \
1643     V(zip2, Zip2)
1644 
1645   #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)   \
1646   void MASM(const VRegister& vd,             \
1647             const VRegister& vn,             \
1648             const VRegister& vm) {           \
1649     SingleEmissionCheckScope guard(this);    \
1650     ASM(vd, vn, vm);                         \
1651   }
1652   NEON_3VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
1653   #undef DEFINE_MACRO_ASM_FUNC
1654 
1655   // NEON 2 vector register instructions.
1656   #define NEON_2VREG_MACRO_LIST(V) \
1657     V(abs,     Abs)                \
1658     V(addp,    Addp)               \
1659     V(addv,    Addv)               \
1660     V(cls,     Cls)                \
1661     V(clz,     Clz)                \
1662     V(cnt,     Cnt)                \
1663     V(fabs,    Fabs)               \
1664     V(faddp,   Faddp)              \
1665     V(fcvtas,  Fcvtas)             \
1666     V(fcvtau,  Fcvtau)             \
1667     V(fcvtms,  Fcvtms)             \
1668     V(fcvtmu,  Fcvtmu)             \
1669     V(fcvtns,  Fcvtns)             \
1670     V(fcvtnu,  Fcvtnu)             \
1671     V(fcvtps,  Fcvtps)             \
1672     V(fcvtpu,  Fcvtpu)             \
1673     V(fmaxnmp, Fmaxnmp)            \
1674     V(fmaxnmv, Fmaxnmv)            \
1675     V(fmaxp,   Fmaxp)              \
1676     V(fmaxv,   Fmaxv)              \
1677     V(fminnmp, Fminnmp)            \
1678     V(fminnmv, Fminnmv)            \
1679     V(fminp,   Fminp)              \
1680     V(fminv,   Fminv)              \
1681     V(fneg,    Fneg)               \
1682     V(frecpe,  Frecpe)             \
1683     V(frecpx,  Frecpx)             \
1684     V(frinta,  Frinta)             \
1685     V(frinti,  Frinti)             \
1686     V(frintm,  Frintm)             \
1687     V(frintn,  Frintn)             \
1688     V(frintp,  Frintp)             \
1689     V(frintx,  Frintx)             \
1690     V(frintz,  Frintz)             \
1691     V(frsqrte, Frsqrte)            \
1692     V(fsqrt,   Fsqrt)              \
1693     V(mov,     Mov)                \
1694     V(mvn,     Mvn)                \
1695     V(neg,     Neg)                \
1696     V(not_,    Not)                \
1697     V(rbit,    Rbit)               \
1698     V(rev16,   Rev16)              \
1699     V(rev32,   Rev32)              \
1700     V(rev64,   Rev64)              \
1701     V(sadalp,  Sadalp)             \
1702     V(saddlp,  Saddlp)             \
1703     V(saddlv,  Saddlv)             \
1704     V(smaxv,   Smaxv)              \
1705     V(sminv,   Sminv)              \
1706     V(sqabs,   Sqabs)              \
1707     V(sqneg,   Sqneg)              \
1708     V(sqxtn,   Sqxtn)              \
1709     V(sqxtn2,  Sqxtn2)             \
1710     V(sqxtun,  Sqxtun)             \
1711     V(sqxtun2, Sqxtun2)            \
1712     V(suqadd,  Suqadd)             \
1713     V(sxtl,    Sxtl)               \
1714     V(sxtl2,   Sxtl2)              \
1715     V(uadalp,  Uadalp)             \
1716     V(uaddlp,  Uaddlp)             \
1717     V(uaddlv,  Uaddlv)             \
1718     V(umaxv,   Umaxv)              \
1719     V(uminv,   Uminv)              \
1720     V(uqxtn,   Uqxtn)              \
1721     V(uqxtn2,  Uqxtn2)             \
1722     V(urecpe,  Urecpe)             \
1723     V(ursqrte, Ursqrte)            \
1724     V(usqadd,  Usqadd)             \
1725     V(uxtl,    Uxtl)               \
1726     V(uxtl2,   Uxtl2)              \
1727     V(xtn,     Xtn)                \
1728     V(xtn2,    Xtn2)
1729 
1730   #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)   \
1731   void MASM(const VRegister& vd,             \
1732             const VRegister& vn) {           \
1733     SingleEmissionCheckScope guard(this);    \
1734     ASM(vd, vn);                             \
1735   }
NEON_2VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)1736   NEON_2VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
1737   #undef DEFINE_MACRO_ASM_FUNC
1738 
1739   // NEON 2 vector register with immediate instructions.
1740   #define NEON_2VREG_FPIMM_MACRO_LIST(V) \
1741     V(fcmeq, Fcmeq)                      \
1742     V(fcmge, Fcmge)                      \
1743     V(fcmgt, Fcmgt)                      \
1744     V(fcmle, Fcmle)                      \
1745     V(fcmlt, Fcmlt)
1746 
1747   #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)   \
1748   void MASM(const VRegister& vd,             \
1749             const VRegister& vn,             \
1750             double imm) {                    \
1751     SingleEmissionCheckScope guard(this);    \
1752     ASM(vd, vn, imm);                        \
1753   }
1754   NEON_2VREG_FPIMM_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
1755   #undef DEFINE_MACRO_ASM_FUNC
1756 
1757   // NEON by element instructions.
1758   #define NEON_BYELEMENT_MACRO_LIST(V) \
1759     V(fmul, Fmul)                      \
1760     V(fmla, Fmla)                      \
1761     V(fmls, Fmls)                      \
1762     V(fmulx, Fmulx)                    \
1763     V(mul, Mul)                        \
1764     V(mla, Mla)                        \
1765     V(mls, Mls)                        \
1766     V(sqdmulh, Sqdmulh)                \
1767     V(sqrdmulh, Sqrdmulh)              \
1768     V(sqdmull,  Sqdmull)               \
1769     V(sqdmull2, Sqdmull2)              \
1770     V(sqdmlal,  Sqdmlal)               \
1771     V(sqdmlal2, Sqdmlal2)              \
1772     V(sqdmlsl,  Sqdmlsl)               \
1773     V(sqdmlsl2, Sqdmlsl2)              \
1774     V(smull,  Smull)                   \
1775     V(smull2, Smull2)                  \
1776     V(smlal,  Smlal)                   \
1777     V(smlal2, Smlal2)                  \
1778     V(smlsl,  Smlsl)                   \
1779     V(smlsl2, Smlsl2)                  \
1780     V(umull,  Umull)                   \
1781     V(umull2, Umull2)                  \
1782     V(umlal,  Umlal)                   \
1783     V(umlal2, Umlal2)                  \
1784     V(umlsl,  Umlsl)                   \
1785     V(umlsl2, Umlsl2)
1786 
1787   #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)   \
1788   void MASM(const VRegister& vd,             \
1789             const VRegister& vn,             \
1790             const VRegister& vm,             \
1791             int vm_index                     \
1792             ) {                              \
1793     SingleEmissionCheckScope guard(this);    \
1794     ASM(vd, vn, vm, vm_index);               \
1795   }
1796   NEON_BYELEMENT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
1797   #undef DEFINE_MACRO_ASM_FUNC
1798 
1799   #define NEON_2VREG_SHIFT_MACRO_LIST(V) \
1800     V(rshrn,     Rshrn)                  \
1801     V(rshrn2,    Rshrn2)                 \
1802     V(shl,       Shl)                    \
1803     V(shll,      Shll)                   \
1804     V(shll2,     Shll2)                  \
1805     V(shrn,      Shrn)                   \
1806     V(shrn2,     Shrn2)                  \
1807     V(sli,       Sli)                    \
1808     V(sqrshrn,   Sqrshrn)                \
1809     V(sqrshrn2,  Sqrshrn2)               \
1810     V(sqrshrun,  Sqrshrun)               \
1811     V(sqrshrun2, Sqrshrun2)              \
1812     V(sqshl,     Sqshl)                  \
1813     V(sqshlu,    Sqshlu)                 \
1814     V(sqshrn,    Sqshrn)                 \
1815     V(sqshrn2,   Sqshrn2)                \
1816     V(sqshrun,   Sqshrun)                \
1817     V(sqshrun2,  Sqshrun2)               \
1818     V(sri,       Sri)                    \
1819     V(srshr,     Srshr)                  \
1820     V(srsra,     Srsra)                  \
1821     V(sshll,     Sshll)                  \
1822     V(sshll2,    Sshll2)                 \
1823     V(sshr,      Sshr)                   \
1824     V(ssra,      Ssra)                   \
1825     V(uqrshrn,   Uqrshrn)                \
1826     V(uqrshrn2,  Uqrshrn2)               \
1827     V(uqshl,     Uqshl)                  \
1828     V(uqshrn,    Uqshrn)                 \
1829     V(uqshrn2,   Uqshrn2)                \
1830     V(urshr,     Urshr)                  \
1831     V(ursra,     Ursra)                  \
1832     V(ushll,     Ushll)                  \
1833     V(ushll2,    Ushll2)                 \
1834     V(ushr,      Ushr)                   \
1835     V(usra,      Usra)                   \
1836 
1837   #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)   \
1838   void MASM(const VRegister& vd,             \
1839             const VRegister& vn,             \
1840             int shift) {                     \
1841     SingleEmissionCheckScope guard(this);    \
1842     ASM(vd, vn, shift);                      \
1843   }
1844   NEON_2VREG_SHIFT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
1845   #undef DEFINE_MACRO_ASM_FUNC
1846 
1847   void Bic(const VRegister& vd,
1848            const int imm8,
1849            const int left_shift = 0) {
1850     SingleEmissionCheckScope guard(this);
1851     bic(vd, imm8, left_shift);
1852   }
Cmeq(const VRegister & vd,const VRegister & vn,int imm)1853   void Cmeq(const VRegister& vd,
1854             const VRegister& vn,
1855             int imm) {
1856     SingleEmissionCheckScope guard(this);
1857     cmeq(vd, vn, imm);
1858   }
Cmge(const VRegister & vd,const VRegister & vn,int imm)1859   void Cmge(const VRegister& vd,
1860             const VRegister& vn,
1861             int imm) {
1862     SingleEmissionCheckScope guard(this);
1863     cmge(vd, vn, imm);
1864   }
Cmgt(const VRegister & vd,const VRegister & vn,int imm)1865   void Cmgt(const VRegister& vd,
1866             const VRegister& vn,
1867             int imm) {
1868     SingleEmissionCheckScope guard(this);
1869     cmgt(vd, vn, imm);
1870   }
Cmle(const VRegister & vd,const VRegister & vn,int imm)1871   void Cmle(const VRegister& vd,
1872             const VRegister& vn,
1873             int imm) {
1874     SingleEmissionCheckScope guard(this);
1875     cmle(vd, vn, imm);
1876   }
Cmlt(const VRegister & vd,const VRegister & vn,int imm)1877   void Cmlt(const VRegister& vd,
1878             const VRegister& vn,
1879             int imm) {
1880     SingleEmissionCheckScope guard(this);
1881     cmlt(vd, vn, imm);
1882   }
Dup(const VRegister & vd,const VRegister & vn,int index)1883   void Dup(const VRegister& vd,
1884            const VRegister& vn,
1885            int index) {
1886     SingleEmissionCheckScope guard(this);
1887     dup(vd, vn, index);
1888   }
Dup(const VRegister & vd,const Register & rn)1889   void Dup(const VRegister& vd,
1890            const Register& rn) {
1891     SingleEmissionCheckScope guard(this);
1892     dup(vd, rn);
1893   }
Ext(const VRegister & vd,const VRegister & vn,const VRegister & vm,int index)1894   void Ext(const VRegister& vd,
1895            const VRegister& vn,
1896            const VRegister& vm,
1897            int index) {
1898     SingleEmissionCheckScope guard(this);
1899     ext(vd, vn, vm, index);
1900   }
Ins(const VRegister & vd,int vd_index,const VRegister & vn,int vn_index)1901   void Ins(const VRegister& vd,
1902            int vd_index,
1903            const VRegister& vn,
1904            int vn_index) {
1905     SingleEmissionCheckScope guard(this);
1906     ins(vd, vd_index, vn, vn_index);
1907   }
Ins(const VRegister & vd,int vd_index,const Register & rn)1908   void Ins(const VRegister& vd,
1909            int vd_index,
1910            const Register& rn) {
1911     SingleEmissionCheckScope guard(this);
1912     ins(vd, vd_index, rn);
1913   }
Ld1(const VRegister & vt,const MemOperand & src)1914   void Ld1(const VRegister& vt,
1915            const MemOperand& src) {
1916     SingleEmissionCheckScope guard(this);
1917     ld1(vt, src);
1918   }
Ld1(const VRegister & vt,const VRegister & vt2,const MemOperand & src)1919   void Ld1(const VRegister& vt,
1920            const VRegister& vt2,
1921            const MemOperand& src) {
1922     SingleEmissionCheckScope guard(this);
1923     ld1(vt, vt2, src);
1924   }
Ld1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & src)1925   void Ld1(const VRegister& vt,
1926            const VRegister& vt2,
1927            const VRegister& vt3,
1928            const MemOperand& src) {
1929     SingleEmissionCheckScope guard(this);
1930     ld1(vt, vt2, vt3, src);
1931   }
Ld1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & src)1932   void Ld1(const VRegister& vt,
1933            const VRegister& vt2,
1934            const VRegister& vt3,
1935            const VRegister& vt4,
1936            const MemOperand& src) {
1937     SingleEmissionCheckScope guard(this);
1938     ld1(vt, vt2, vt3, vt4, src);
1939   }
Ld1(const VRegister & vt,int lane,const MemOperand & src)1940   void Ld1(const VRegister& vt,
1941            int lane,
1942            const MemOperand& src) {
1943     SingleEmissionCheckScope guard(this);
1944     ld1(vt, lane, src);
1945   }
Ld1r(const VRegister & vt,const MemOperand & src)1946   void Ld1r(const VRegister& vt,
1947             const MemOperand& src) {
1948     SingleEmissionCheckScope guard(this);
1949     ld1r(vt, src);
1950   }
Ld2(const VRegister & vt,const VRegister & vt2,const MemOperand & src)1951   void Ld2(const VRegister& vt,
1952            const VRegister& vt2,
1953            const MemOperand& src) {
1954     SingleEmissionCheckScope guard(this);
1955     ld2(vt, vt2, src);
1956   }
Ld2(const VRegister & vt,const VRegister & vt2,int lane,const MemOperand & src)1957   void Ld2(const VRegister& vt,
1958            const VRegister& vt2,
1959            int lane,
1960            const MemOperand& src) {
1961     SingleEmissionCheckScope guard(this);
1962     ld2(vt, vt2, lane, src);
1963   }
Ld2r(const VRegister & vt,const VRegister & vt2,const MemOperand & src)1964   void Ld2r(const VRegister& vt,
1965             const VRegister& vt2,
1966             const MemOperand& src) {
1967     SingleEmissionCheckScope guard(this);
1968     ld2r(vt, vt2, src);
1969   }
Ld3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & src)1970   void Ld3(const VRegister& vt,
1971            const VRegister& vt2,
1972            const VRegister& vt3,
1973            const MemOperand& src) {
1974     SingleEmissionCheckScope guard(this);
1975     ld3(vt, vt2, vt3, src);
1976   }
Ld3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,int lane,const MemOperand & src)1977   void Ld3(const VRegister& vt,
1978            const VRegister& vt2,
1979            const VRegister& vt3,
1980            int lane,
1981            const MemOperand& src) {
1982     SingleEmissionCheckScope guard(this);
1983     ld3(vt, vt2, vt3, lane, src);
1984   }
Ld3r(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & src)1985   void Ld3r(const VRegister& vt,
1986             const VRegister& vt2,
1987             const VRegister& vt3,
1988            const MemOperand& src) {
1989     SingleEmissionCheckScope guard(this);
1990     ld3r(vt, vt2, vt3, src);
1991   }
Ld4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & src)1992   void Ld4(const VRegister& vt,
1993            const VRegister& vt2,
1994            const VRegister& vt3,
1995            const VRegister& vt4,
1996            const MemOperand& src) {
1997     SingleEmissionCheckScope guard(this);
1998     ld4(vt, vt2, vt3, vt4, src);
1999   }
Ld4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,int lane,const MemOperand & src)2000   void Ld4(const VRegister& vt,
2001            const VRegister& vt2,
2002            const VRegister& vt3,
2003            const VRegister& vt4,
2004            int lane,
2005            const MemOperand& src) {
2006     SingleEmissionCheckScope guard(this);
2007     ld4(vt, vt2, vt3, vt4, lane, src);
2008   }
Ld4r(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & src)2009   void Ld4r(const VRegister& vt,
2010             const VRegister& vt2,
2011             const VRegister& vt3,
2012             const VRegister& vt4,
2013            const MemOperand& src) {
2014     SingleEmissionCheckScope guard(this);
2015     ld4r(vt, vt2, vt3, vt4, src);
2016   }
Mov(const VRegister & vd,int vd_index,const VRegister & vn,int vn_index)2017   void Mov(const VRegister& vd,
2018            int vd_index,
2019            const VRegister& vn,
2020            int vn_index) {
2021     SingleEmissionCheckScope guard(this);
2022     mov(vd, vd_index, vn, vn_index);
2023   }
Mov(const VRegister & vd,const VRegister & vn,int index)2024   void Mov(const VRegister& vd,
2025            const VRegister& vn,
2026            int index) {
2027     SingleEmissionCheckScope guard(this);
2028     mov(vd, vn, index);
2029   }
Mov(const VRegister & vd,int vd_index,const Register & rn)2030   void Mov(const VRegister& vd,
2031            int vd_index,
2032            const Register& rn) {
2033     SingleEmissionCheckScope guard(this);
2034     mov(vd, vd_index, rn);
2035   }
Mov(const Register & rd,const VRegister & vn,int vn_index)2036   void Mov(const Register& rd,
2037            const VRegister& vn,
2038            int vn_index) {
2039     SingleEmissionCheckScope guard(this);
2040     mov(rd, vn, vn_index);
2041   }
2042   void Movi(const VRegister& vd,
2043             uint64_t imm,
2044             Shift shift = LSL,
2045             int shift_amount = 0);
2046   void Movi(const VRegister& vd, uint64_t hi, uint64_t lo);
2047   void Mvni(const VRegister& vd,
2048             const int imm8,
2049             Shift shift = LSL,
2050             const int shift_amount = 0) {
2051     SingleEmissionCheckScope guard(this);
2052     mvni(vd, imm8, shift, shift_amount);
2053   }
2054   void Orr(const VRegister& vd,
2055            const int imm8,
2056            const int left_shift = 0) {
2057     SingleEmissionCheckScope guard(this);
2058     orr(vd, imm8, left_shift);
2059   }
2060   void Scvtf(const VRegister& vd,
2061              const VRegister& vn,
2062              int fbits = 0) {
2063     SingleEmissionCheckScope guard(this);
2064     scvtf(vd, vn, fbits);
2065   }
2066   void Ucvtf(const VRegister& vd,
2067              const VRegister& vn,
2068              int fbits = 0) {
2069     SingleEmissionCheckScope guard(this);
2070     ucvtf(vd, vn, fbits);
2071   }
2072   void Fcvtzs(const VRegister& vd,
2073               const VRegister& vn,
2074               int fbits = 0) {
2075     SingleEmissionCheckScope guard(this);
2076     fcvtzs(vd, vn, fbits);
2077   }
2078   void Fcvtzu(const VRegister& vd,
2079               const VRegister& vn,
2080               int fbits = 0) {
2081     SingleEmissionCheckScope guard(this);
2082     fcvtzu(vd, vn, fbits);
2083   }
St1(const VRegister & vt,const MemOperand & dst)2084   void St1(const VRegister& vt,
2085            const MemOperand& dst) {
2086     SingleEmissionCheckScope guard(this);
2087     st1(vt, dst);
2088   }
St1(const VRegister & vt,const VRegister & vt2,const MemOperand & dst)2089   void St1(const VRegister& vt,
2090            const VRegister& vt2,
2091            const MemOperand& dst) {
2092     SingleEmissionCheckScope guard(this);
2093     st1(vt, vt2, dst);
2094   }
St1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & dst)2095   void St1(const VRegister& vt,
2096            const VRegister& vt2,
2097            const VRegister& vt3,
2098            const MemOperand& dst) {
2099     SingleEmissionCheckScope guard(this);
2100     st1(vt, vt2, vt3, dst);
2101   }
St1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & dst)2102   void St1(const VRegister& vt,
2103            const VRegister& vt2,
2104            const VRegister& vt3,
2105            const VRegister& vt4,
2106            const MemOperand& dst) {
2107     SingleEmissionCheckScope guard(this);
2108     st1(vt, vt2, vt3, vt4, dst);
2109   }
St1(const VRegister & vt,int lane,const MemOperand & dst)2110   void St1(const VRegister& vt,
2111            int lane,
2112            const MemOperand& dst) {
2113     SingleEmissionCheckScope guard(this);
2114     st1(vt, lane, dst);
2115   }
St2(const VRegister & vt,const VRegister & vt2,const MemOperand & dst)2116   void St2(const VRegister& vt,
2117            const VRegister& vt2,
2118            const MemOperand& dst) {
2119     SingleEmissionCheckScope guard(this);
2120     st2(vt, vt2, dst);
2121   }
St3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & dst)2122   void St3(const VRegister& vt,
2123            const VRegister& vt2,
2124            const VRegister& vt3,
2125            const MemOperand& dst) {
2126     SingleEmissionCheckScope guard(this);
2127     st3(vt, vt2, vt3, dst);
2128   }
St4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & dst)2129   void St4(const VRegister& vt,
2130            const VRegister& vt2,
2131            const VRegister& vt3,
2132            const VRegister& vt4,
2133            const MemOperand& dst) {
2134     SingleEmissionCheckScope guard(this);
2135     st4(vt, vt2, vt3, vt4, dst);
2136   }
St2(const VRegister & vt,const VRegister & vt2,int lane,const MemOperand & dst)2137   void St2(const VRegister& vt,
2138            const VRegister& vt2,
2139            int lane,
2140            const MemOperand& dst) {
2141     SingleEmissionCheckScope guard(this);
2142     st2(vt, vt2, lane, dst);
2143   }
St3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,int lane,const MemOperand & dst)2144   void St3(const VRegister& vt,
2145            const VRegister& vt2,
2146            const VRegister& vt3,
2147            int lane,
2148            const MemOperand& dst) {
2149     SingleEmissionCheckScope guard(this);
2150     st3(vt, vt2, vt3, lane, dst);
2151   }
St4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,int lane,const MemOperand & dst)2152   void St4(const VRegister& vt,
2153            const VRegister& vt2,
2154            const VRegister& vt3,
2155            const VRegister& vt4,
2156            int lane,
2157            const MemOperand& dst) {
2158     SingleEmissionCheckScope guard(this);
2159     st4(vt, vt2, vt3, vt4, lane, dst);
2160   }
Smov(const Register & rd,const VRegister & vn,int vn_index)2161   void Smov(const Register& rd,
2162             const VRegister& vn,
2163             int vn_index) {
2164     SingleEmissionCheckScope guard(this);
2165     smov(rd, vn, vn_index);
2166   }
Umov(const Register & rd,const VRegister & vn,int vn_index)2167   void Umov(const Register& rd,
2168             const VRegister& vn,
2169             int vn_index) {
2170     SingleEmissionCheckScope guard(this);
2171     umov(rd, vn, vn_index);
2172   }
Crc32b(const Register & rd,const Register & rn,const Register & rm)2173   void Crc32b(const Register& rd,
2174               const Register& rn,
2175               const Register& rm) {
2176     SingleEmissionCheckScope guard(this);
2177     crc32b(rd, rn, rm);
2178   }
Crc32h(const Register & rd,const Register & rn,const Register & rm)2179   void Crc32h(const Register& rd,
2180               const Register& rn,
2181               const Register& rm) {
2182     SingleEmissionCheckScope guard(this);
2183     crc32h(rd, rn, rm);
2184   }
Crc32w(const Register & rd,const Register & rn,const Register & rm)2185   void Crc32w(const Register& rd,
2186               const Register& rn,
2187               const Register& rm) {
2188     SingleEmissionCheckScope guard(this);
2189     crc32w(rd, rn, rm);
2190   }
Crc32x(const Register & rd,const Register & rn,const Register & rm)2191   void Crc32x(const Register& rd,
2192               const Register& rn,
2193               const Register& rm) {
2194     SingleEmissionCheckScope guard(this);
2195     crc32x(rd, rn, rm);
2196   }
Crc32cb(const Register & rd,const Register & rn,const Register & rm)2197   void Crc32cb(const Register& rd,
2198                const Register& rn,
2199                const Register& rm) {
2200     SingleEmissionCheckScope guard(this);
2201     crc32cb(rd, rn, rm);
2202   }
Crc32ch(const Register & rd,const Register & rn,const Register & rm)2203   void Crc32ch(const Register& rd,
2204                const Register& rn,
2205                const Register& rm) {
2206     SingleEmissionCheckScope guard(this);
2207     crc32ch(rd, rn, rm);
2208   }
Crc32cw(const Register & rd,const Register & rn,const Register & rm)2209   void Crc32cw(const Register& rd,
2210                const Register& rn,
2211                const Register& rm) {
2212     SingleEmissionCheckScope guard(this);
2213     crc32cw(rd, rn, rm);
2214   }
Crc32cx(const Register & rd,const Register & rn,const Register & rm)2215   void Crc32cx(const Register& rd,
2216                const Register& rn,
2217                const Register& rm) {
2218     SingleEmissionCheckScope guard(this);
2219     crc32cx(rd, rn, rm);
2220   }
2221 
2222   // Push the system stack pointer (sp) down to allow the same to be done to
2223   // the current stack pointer (according to StackPointer()). This must be
2224   // called _before_ accessing the memory.
2225   //
2226   // This is necessary when pushing or otherwise adding things to the stack, to
2227   // satisfy the AAPCS64 constraint that the memory below the system stack
2228   // pointer is not accessed.
2229   //
2230   // This method asserts that StackPointer() is not sp, since the call does
2231   // not make sense in that context.
2232   //
2233   // TODO: This method can only accept values of 'space' that can be encoded in
2234   // one instruction. Refer to the implementation for details.
2235   void BumpSystemStackPointer(const Operand& space);
2236 
2237   // Set the current stack pointer, but don't generate any code.
SetStackPointer64(const Register & stack_pointer)2238   void SetStackPointer64(const Register& stack_pointer) {
2239     VIXL_ASSERT(!TmpList()->IncludesAliasOf(stack_pointer));
2240     sp_ = stack_pointer;
2241   }
2242 
2243   // Return the current stack pointer, as set by SetStackPointer.
StackPointer()2244   const Register& StackPointer() const {
2245     return sp_;
2246   }
2247 
GetStackPointer64()2248   const Register& GetStackPointer64() const {
2249     return sp_;
2250   }
2251 
getStackPointer()2252   js::jit::RegisterOrSP getStackPointer() const {
2253       return js::jit::RegisterOrSP(sp_.code());
2254   }
2255 
TmpList()2256   CPURegList* TmpList() { return &tmp_list_; }
FPTmpList()2257   CPURegList* FPTmpList() { return &fptmp_list_; }
2258 
2259   // Trace control when running the debug simulator.
2260   //
2261   // For example:
2262   //
2263   // __ Trace(LOG_REGS, TRACE_ENABLE);
2264   // Will add registers to the trace if it wasn't already the case.
2265   //
2266   // __ Trace(LOG_DISASM, TRACE_DISABLE);
2267   // Will stop logging disassembly. It has no effect if the disassembly wasn't
2268   // already being logged.
2269   void Trace(TraceParameters parameters, TraceCommand command);
2270 
2271   // Log the requested data independently of what is being traced.
2272   //
2273   // For example:
2274   //
2275   // __ Log(LOG_FLAGS)
2276   // Will output the flags.
2277   void Log(TraceParameters parameters);
2278 
2279   // Enable or disable instrumentation when an Instrument visitor is attached to
2280   // the simulator.
2281   void EnableInstrumentation();
2282   void DisableInstrumentation();
2283 
2284   // Add a marker to the instrumentation data produced by an Instrument visitor.
2285   // The name is a two character string that will be attached to the marker in
2286   // the output data.
2287   void AnnotateInstrumentation(const char* marker_name);
2288 
2289  private:
2290   // The actual Push and Pop implementations. These don't generate any code
2291   // other than that required for the push or pop. This allows
2292   // (Push|Pop)CPURegList to bundle together setup code for a large block of
2293   // registers.
2294   //
2295   // Note that size is per register, and is specified in bytes.
2296   void PushHelper(int count, int size,
2297                   const CPURegister& src0, const CPURegister& src1,
2298                   const CPURegister& src2, const CPURegister& src3);
2299   void PopHelper(int count, int size,
2300                  const CPURegister& dst0, const CPURegister& dst1,
2301                  const CPURegister& dst2, const CPURegister& dst3);
2302 
2303   void Movi16bitHelper(const VRegister& vd, uint64_t imm);
2304   void Movi32bitHelper(const VRegister& vd, uint64_t imm);
2305   void Movi64bitHelper(const VRegister& vd, uint64_t imm);
2306 
2307   // Perform necessary maintenance operations before a push or pop.
2308   //
2309   // Note that size is per register, and is specified in bytes.
2310   void PrepareForPush(int count, int size);
2311   void PrepareForPop(int count, int size);
2312 
2313   // The actual implementation of load and store operations for CPURegList.
2314   enum LoadStoreCPURegListAction {
2315     kLoad,
2316     kStore
2317   };
2318   void LoadStoreCPURegListHelper(LoadStoreCPURegListAction operation,
2319                                  CPURegList registers,
2320                                  const MemOperand& mem);
2321   // Returns a MemOperand suitable for loading or storing a CPURegList at `dst`.
2322   // This helper may allocate registers from `scratch_scope` and generate code
2323   // to compute an intermediate address. The resulting MemOperand is only valid
2324   // as long as `scratch_scope` remains valid.
2325   MemOperand BaseMemOperandForLoadStoreCPURegList(
2326       const CPURegList& registers,
2327       const MemOperand& mem,
2328       UseScratchRegisterScope* scratch_scope);
2329 
LabelIsOutOfRange(Label * label,ImmBranchType branch_type)2330   bool LabelIsOutOfRange(Label* label, ImmBranchType branch_type) {
2331     return !Instruction::IsValidImmPCOffset(branch_type, nextOffset().getOffset() - label->offset());
2332   }
2333 
2334   // The register to use as a stack pointer for stack operations.
2335   Register sp_;
2336 
2337   // Scratch registers available for use by the MacroAssembler.
2338   CPURegList tmp_list_;
2339   CPURegList fptmp_list_;
2340 
2341   ptrdiff_t checkpoint_;
2342   ptrdiff_t recommended_checkpoint_;
2343 };
2344 
2345 
2346 // All Assembler emits MUST acquire/release the underlying code buffer. The
2347 // helper scope below will do so and optionally ensure the buffer is big enough
2348 // to receive the emit. It is possible to request the scope not to perform any
2349 // checks (kNoCheck) if for example it is known in advance the buffer size is
2350 // adequate or there is some other size checking mechanism in place.
2351 class CodeBufferCheckScope {
2352  public:
2353   // Tell whether or not the scope needs to ensure the associated CodeBuffer
2354   // has enough space for the requested size.
2355   enum CheckPolicy {
2356     kNoCheck,
2357     kCheck
2358   };
2359 
2360   // Tell whether or not the scope should assert the amount of code emitted
2361   // within the scope is consistent with the requested amount.
2362   enum AssertPolicy {
2363     kNoAssert,    // No assert required.
2364     kExactSize,   // The code emitted must be exactly size bytes.
2365     kMaximumSize  // The code emitted must be at most size bytes.
2366   };
2367 
2368   CodeBufferCheckScope(Assembler* assm,
2369                        size_t size,
2370                        CheckPolicy check_policy = kCheck,
2371                        AssertPolicy assert_policy = kMaximumSize)
2372   { }
2373 
2374   // This is a shortcut for CodeBufferCheckScope(assm, 0, kNoCheck, kNoAssert).
CodeBufferCheckScope(Assembler * assm)2375   explicit CodeBufferCheckScope(Assembler* assm) {}
2376 };
2377 
2378 
2379 // Use this scope when you need a one-to-one mapping between methods and
2380 // instructions. This scope prevents the MacroAssembler from being called and
2381 // literal pools from being emitted. It also asserts the number of instructions
2382 // emitted is what you specified when creating the scope.
2383 // FIXME: Because of the disabled calls below, this class asserts nothing.
2384 class InstructionAccurateScope : public CodeBufferCheckScope {
2385  public:
2386   InstructionAccurateScope(MacroAssembler* masm,
2387                            int64_t count,
2388                            AssertPolicy policy = kExactSize)
2389       : CodeBufferCheckScope(masm,
2390                              (count * kInstructionSize),
2391                              kCheck,
2392                              policy) {
2393   }
2394 };
2395 
2396 
2397 // This scope utility allows scratch registers to be managed safely. The
2398 // MacroAssembler's TmpList() (and FPTmpList()) is used as a pool of scratch
2399 // registers. These registers can be allocated on demand, and will be returned
2400 // at the end of the scope.
2401 //
2402 // When the scope ends, the MacroAssembler's lists will be restored to their
2403 // original state, even if the lists were modified by some other means.
2404 class UseScratchRegisterScope {
2405  public:
2406   // This constructor implicitly calls the `Open` function to initialise the
2407   // scope, so it is ready to use immediately after it has been constructed.
2408   explicit UseScratchRegisterScope(MacroAssembler* masm);
2409   // This constructor allows deferred and optional initialisation of the scope.
2410   // The user is required to explicitly call the `Open` function before using
2411   // the scope.
2412   UseScratchRegisterScope();
2413   // This function performs the actual initialisation work.
2414   void Open(MacroAssembler* masm);
2415 
2416   // The destructor always implicitly calls the `Close` function.
2417   ~UseScratchRegisterScope();
2418   // This function performs the cleaning-up work. It must succeed even if the
2419   // scope has not been opened. It is safe to call multiple times.
2420   void Close();
2421 
2422 
2423   bool IsAvailable(const CPURegister& reg) const;
2424 
2425 
2426   // Take a register from the appropriate temps list. It will be returned
2427   // automatically when the scope ends.
AcquireW()2428   Register AcquireW() { return AcquireNextAvailable(available_).W(); }
AcquireX()2429   Register AcquireX() { return AcquireNextAvailable(available_).X(); }
AcquireS()2430   VRegister AcquireS() { return AcquireNextAvailable(availablefp_).S(); }
AcquireD()2431   VRegister AcquireD() { return AcquireNextAvailable(availablefp_).D(); }
AcquireQ()2432   VRegister AcquireQ() { return AcquireNextAvailable(availablefp_).Q(); }
2433 
2434 
2435   Register AcquireSameSizeAs(const Register& reg);
2436   VRegister AcquireSameSizeAs(const VRegister& reg);
2437 
2438 
2439   // Explicitly release an acquired (or excluded) register, putting it back in
2440   // the appropriate temps list.
2441   void Release(const CPURegister& reg);
2442 
2443 
2444   // Make the specified registers available as scratch registers for the
2445   // duration of this scope.
2446   void Include(const CPURegList& list);
2447   void Include(const Register& reg1,
2448                const Register& reg2 = NoReg,
2449                const Register& reg3 = NoReg,
2450                const Register& reg4 = NoReg);
2451   void Include(const VRegister& reg1,
2452                const VRegister& reg2 = NoVReg,
2453                const VRegister& reg3 = NoVReg,
2454                const VRegister& reg4 = NoVReg);
2455 
2456 
2457   // Make sure that the specified registers are not available in this scope.
2458   // This can be used to prevent helper functions from using sensitive
2459   // registers, for example.
2460   void Exclude(const CPURegList& list);
2461   void Exclude(const Register& reg1,
2462                const Register& reg2 = NoReg,
2463                const Register& reg3 = NoReg,
2464                const Register& reg4 = NoReg);
2465   void Exclude(const VRegister& reg1,
2466                const VRegister& reg2 = NoVReg,
2467                const VRegister& reg3 = NoVReg,
2468                const VRegister& reg4 = NoVReg);
2469   void Exclude(const CPURegister& reg1,
2470                const CPURegister& reg2 = NoCPUReg,
2471                const CPURegister& reg3 = NoCPUReg,
2472                const CPURegister& reg4 = NoCPUReg);
2473 
2474 
2475   // Prevent any scratch registers from being used in this scope.
2476   void ExcludeAll();
2477 
2478 
2479  private:
2480   static CPURegister AcquireNextAvailable(CPURegList* available);
2481 
2482   static void ReleaseByCode(CPURegList* available, int code);
2483 
2484   static void ReleaseByRegList(CPURegList* available,
2485                                RegList regs);
2486 
2487   static void IncludeByRegList(CPURegList* available,
2488                                RegList exclude);
2489 
2490   static void ExcludeByRegList(CPURegList* available,
2491                                RegList exclude);
2492 
2493   // Available scratch registers.
2494   CPURegList* available_;     // kRegister
2495   CPURegList* availablefp_;   // kVRegister
2496 
2497   // The state of the available lists at the start of this scope.
2498   RegList old_available_;     // kRegister
2499   RegList old_availablefp_;   // kVRegister
2500 #ifdef DEBUG
2501   bool initialised_;
2502 #endif
2503 
2504   // Disallow copy constructor and operator=.
UseScratchRegisterScope(const UseScratchRegisterScope &)2505   UseScratchRegisterScope(const UseScratchRegisterScope&) {
2506     VIXL_UNREACHABLE();
2507   }
2508   void operator=(const UseScratchRegisterScope&) {
2509     VIXL_UNREACHABLE();
2510   }
2511 };
2512 
2513 
2514 }  // namespace vixl
2515 
2516 #endif  // VIXL_A64_MACRO_ASSEMBLER_A64_H_
2517