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     VIXL_ASSERT(!rn.IsZero());
660     VIXL_ASSERT(!rm.IsZero());
661     VIXL_ASSERT((cond != al) && (cond != nv));
662     SingleEmissionCheckScope guard(this);
663     csinc(rd, rn, rm, cond);
664   }
Csinv(const Register & rd,const Register & rn,const Register & rm,Condition cond)665   void Csinv(const Register& rd,
666              const Register& rn,
667              const Register& rm,
668              Condition cond) {
669     VIXL_ASSERT(!rd.IsZero());
670     VIXL_ASSERT(!rn.IsZero());
671     VIXL_ASSERT(!rm.IsZero());
672     VIXL_ASSERT((cond != al) && (cond != nv));
673     SingleEmissionCheckScope guard(this);
674     csinv(rd, rn, rm, cond);
675   }
Csneg(const Register & rd,const Register & rn,const Register & rm,Condition cond)676   void Csneg(const Register& rd,
677              const Register& rn,
678              const Register& rm,
679              Condition cond) {
680     VIXL_ASSERT(!rd.IsZero());
681     VIXL_ASSERT(!rn.IsZero());
682     VIXL_ASSERT(!rm.IsZero());
683     VIXL_ASSERT((cond != al) && (cond != nv));
684     SingleEmissionCheckScope guard(this);
685     csneg(rd, rn, rm, cond);
686   }
Dmb(BarrierDomain domain,BarrierType type)687   void Dmb(BarrierDomain domain, BarrierType type) {
688     SingleEmissionCheckScope guard(this);
689     dmb(domain, type);
690   }
Dsb(BarrierDomain domain,BarrierType type)691   void Dsb(BarrierDomain domain, BarrierType type) {
692     SingleEmissionCheckScope guard(this);
693     dsb(domain, type);
694   }
Extr(const Register & rd,const Register & rn,const Register & rm,unsigned lsb)695   void Extr(const Register& rd,
696             const Register& rn,
697             const Register& rm,
698             unsigned lsb) {
699     VIXL_ASSERT(!rd.IsZero());
700     VIXL_ASSERT(!rn.IsZero());
701     VIXL_ASSERT(!rm.IsZero());
702     SingleEmissionCheckScope guard(this);
703     extr(rd, rn, rm, lsb);
704   }
Fadd(const VRegister & vd,const VRegister & vn,const VRegister & vm)705   void Fadd(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
706     SingleEmissionCheckScope guard(this);
707     fadd(vd, vn, vm);
708   }
709   void Fccmp(const VRegister& vn,
710              const VRegister& vm,
711              StatusFlags nzcv,
712              Condition cond,
713              FPTrapFlags trap = DisableTrap) {
714     VIXL_ASSERT((cond != al) && (cond != nv));
715     SingleEmissionCheckScope guard(this);
716     FPCCompareMacro(vn, vm, nzcv, cond, trap);
717   }
Fccmpe(const VRegister & vn,const VRegister & vm,StatusFlags nzcv,Condition cond)718   void Fccmpe(const VRegister& vn,
719               const VRegister& vm,
720               StatusFlags nzcv,
721               Condition cond) {
722     Fccmp(vn, vm, nzcv, cond, EnableTrap);
723   }
724   void Fcmp(const VRegister& vn, const VRegister& vm,
725             FPTrapFlags trap = DisableTrap) {
726     SingleEmissionCheckScope guard(this);
727     FPCompareMacro(vn, vm, trap);
728   }
729   void Fcmp(const VRegister& vn, double value,
730             FPTrapFlags trap = DisableTrap);
731   void Fcmpe(const VRegister& vn, double value);
Fcmpe(const VRegister & vn,const VRegister & vm)732   void Fcmpe(const VRegister& vn, const VRegister& vm) {
733     Fcmp(vn, vm, EnableTrap);
734   }
Fcsel(const VRegister & vd,const VRegister & vn,const VRegister & vm,Condition cond)735   void Fcsel(const VRegister& vd,
736              const VRegister& vn,
737              const VRegister& vm,
738              Condition cond) {
739     VIXL_ASSERT((cond != al) && (cond != nv));
740     SingleEmissionCheckScope guard(this);
741     fcsel(vd, vn, vm, cond);
742   }
Fcvt(const VRegister & vd,const VRegister & vn)743   void Fcvt(const VRegister& vd, const VRegister& vn) {
744     SingleEmissionCheckScope guard(this);
745     fcvt(vd, vn);
746   }
Fcvtl(const VRegister & vd,const VRegister & vn)747   void Fcvtl(const VRegister& vd, const VRegister& vn) {
748     SingleEmissionCheckScope guard(this);
749     fcvtl(vd, vn);
750   }
Fcvtl2(const VRegister & vd,const VRegister & vn)751   void Fcvtl2(const VRegister& vd, const VRegister& vn) {
752     SingleEmissionCheckScope guard(this);
753     fcvtl2(vd, vn);
754   }
Fcvtn(const VRegister & vd,const VRegister & vn)755   void Fcvtn(const VRegister& vd, const VRegister& vn) {
756     SingleEmissionCheckScope guard(this);
757     fcvtn(vd, vn);
758   }
Fcvtn2(const VRegister & vd,const VRegister & vn)759   void Fcvtn2(const VRegister& vd, const VRegister& vn) {
760     SingleEmissionCheckScope guard(this);
761     fcvtn2(vd, vn);
762   }
Fcvtxn(const VRegister & vd,const VRegister & vn)763   void Fcvtxn(const VRegister& vd, const VRegister& vn) {
764     SingleEmissionCheckScope guard(this);
765     fcvtxn(vd, vn);
766   }
Fcvtxn2(const VRegister & vd,const VRegister & vn)767   void Fcvtxn2(const VRegister& vd, const VRegister& vn) {
768     SingleEmissionCheckScope guard(this);
769     fcvtxn2(vd, vn);
770   }
Fcvtas(const Register & rd,const VRegister & vn)771   void Fcvtas(const Register& rd, const VRegister& vn) {
772     VIXL_ASSERT(!rd.IsZero());
773     SingleEmissionCheckScope guard(this);
774     fcvtas(rd, vn);
775   }
Fcvtau(const Register & rd,const VRegister & vn)776   void Fcvtau(const Register& rd, const VRegister& vn) {
777     VIXL_ASSERT(!rd.IsZero());
778     SingleEmissionCheckScope guard(this);
779     fcvtau(rd, vn);
780   }
Fcvtms(const Register & rd,const VRegister & vn)781   void Fcvtms(const Register& rd, const VRegister& vn) {
782     VIXL_ASSERT(!rd.IsZero());
783     SingleEmissionCheckScope guard(this);
784     fcvtms(rd, vn);
785   }
Fcvtmu(const Register & rd,const VRegister & vn)786   void Fcvtmu(const Register& rd, const VRegister& vn) {
787     VIXL_ASSERT(!rd.IsZero());
788     SingleEmissionCheckScope guard(this);
789     fcvtmu(rd, vn);
790   }
Fcvtns(const Register & rd,const VRegister & vn)791   void Fcvtns(const Register& rd, const VRegister& vn) {
792     VIXL_ASSERT(!rd.IsZero());
793     SingleEmissionCheckScope guard(this);
794     fcvtns(rd, vn);
795   }
Fcvtnu(const Register & rd,const VRegister & vn)796   void Fcvtnu(const Register& rd, const VRegister& vn) {
797     VIXL_ASSERT(!rd.IsZero());
798     SingleEmissionCheckScope guard(this);
799     fcvtnu(rd, vn);
800   }
Fcvtps(const Register & rd,const VRegister & vn)801   void Fcvtps(const Register& rd, const VRegister& vn) {
802     VIXL_ASSERT(!rd.IsZero());
803     SingleEmissionCheckScope guard(this);
804     fcvtps(rd, vn);
805   }
Fcvtpu(const Register & rd,const VRegister & vn)806   void Fcvtpu(const Register& rd, const VRegister& vn) {
807     VIXL_ASSERT(!rd.IsZero());
808     SingleEmissionCheckScope guard(this);
809     fcvtpu(rd, vn);
810   }
811   void Fcvtzs(const Register& rd, const VRegister& vn, int fbits = 0) {
812     VIXL_ASSERT(!rd.IsZero());
813     SingleEmissionCheckScope guard(this);
814     fcvtzs(rd, vn, fbits);
815   }
816   void Fcvtzu(const Register& rd, const VRegister& vn, int fbits = 0) {
817     VIXL_ASSERT(!rd.IsZero());
818     SingleEmissionCheckScope guard(this);
819     fcvtzu(rd, vn, fbits);
820   }
Fdiv(const VRegister & vd,const VRegister & vn,const VRegister & vm)821   void Fdiv(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
822     SingleEmissionCheckScope guard(this);
823     fdiv(vd, vn, vm);
824   }
Fmax(const VRegister & vd,const VRegister & vn,const VRegister & vm)825   void Fmax(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
826     SingleEmissionCheckScope guard(this);
827     fmax(vd, vn, vm);
828   }
Fmaxnm(const VRegister & vd,const VRegister & vn,const VRegister & vm)829   void Fmaxnm(const VRegister& vd,
830               const VRegister& vn,
831               const VRegister& vm) {
832     SingleEmissionCheckScope guard(this);
833     fmaxnm(vd, vn, vm);
834   }
Fmin(const VRegister & vd,const VRegister & vn,const VRegister & vm)835   void Fmin(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
836     SingleEmissionCheckScope guard(this);
837     fmin(vd, vn, vm);
838   }
Fminnm(const VRegister & vd,const VRegister & vn,const VRegister & vm)839   void Fminnm(const VRegister& vd,
840               const VRegister& vn,
841               const VRegister& vm) {
842     SingleEmissionCheckScope guard(this);
843     fminnm(vd, vn, vm);
844   }
Fmov(VRegister vd,VRegister vn)845   void Fmov(VRegister vd, VRegister vn) {
846     SingleEmissionCheckScope guard(this);
847     // Only emit an instruction if vd and vn are different, and they are both D
848     // registers. fmov(s0, s0) is not a no-op because it clears the top word of
849     // d0. Technically, fmov(d0, d0) is not a no-op either because it clears
850     // the top of q0, but VRegister does not currently support Q registers.
851     if (!vd.Is(vn) || !vd.Is64Bits()) {
852       fmov(vd, vn);
853     }
854   }
Fmov(VRegister vd,Register rn)855   void Fmov(VRegister vd, Register rn) {
856     VIXL_ASSERT(!rn.IsZero());
857     SingleEmissionCheckScope guard(this);
858     fmov(vd, rn);
859   }
Fmov(const VRegister & vd,int index,const Register & rn)860   void Fmov(const VRegister& vd, int index, const Register& rn) {
861     SingleEmissionCheckScope guard(this);
862     fmov(vd, index, rn);
863   }
Fmov(const Register & rd,const VRegister & vn,int index)864   void Fmov(const Register& rd, const VRegister& vn, int index) {
865     SingleEmissionCheckScope guard(this);
866     fmov(rd, vn, index);
867   }
868 
869   // Provide explicit double and float interfaces for FP immediate moves, rather
870   // than relying on implicit C++ casts. This allows signalling NaNs to be
871   // preserved when the immediate matches the format of vd. Most systems convert
872   // signalling NaNs to quiet NaNs when converting between float and double.
873   void Fmov(VRegister vd, double imm);
874   void Fmov(VRegister vd, float imm);
875   // Provide a template to allow other types to be converted automatically.
876   template<typename T>
Fmov(VRegister vd,T imm)877   void Fmov(VRegister vd, T imm) {
878     Fmov(vd, static_cast<double>(imm));
879   }
Fmov(Register rd,VRegister vn)880   void Fmov(Register rd, VRegister vn) {
881     VIXL_ASSERT(!rd.IsZero());
882     SingleEmissionCheckScope guard(this);
883     fmov(rd, vn);
884   }
Fmul(const VRegister & vd,const VRegister & vn,const VRegister & vm)885   void Fmul(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
886     SingleEmissionCheckScope guard(this);
887     fmul(vd, vn, vm);
888   }
Fnmul(const VRegister & vd,const VRegister & vn,const VRegister & vm)889   void Fnmul(const VRegister& vd, const VRegister& vn,
890              const VRegister& vm) {
891     SingleEmissionCheckScope guard(this);
892     fnmul(vd, vn, vm);
893   }
Fmadd(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)894   void Fmadd(const VRegister& vd,
895              const VRegister& vn,
896              const VRegister& vm,
897              const VRegister& va) {
898     SingleEmissionCheckScope guard(this);
899     fmadd(vd, vn, vm, va);
900   }
Fmsub(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)901   void Fmsub(const VRegister& vd,
902              const VRegister& vn,
903              const VRegister& vm,
904              const VRegister& va) {
905     SingleEmissionCheckScope guard(this);
906     fmsub(vd, vn, vm, va);
907   }
Fnmadd(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)908   void Fnmadd(const VRegister& vd,
909               const VRegister& vn,
910               const VRegister& vm,
911               const VRegister& va) {
912     SingleEmissionCheckScope guard(this);
913     fnmadd(vd, vn, vm, va);
914   }
Fnmsub(const VRegister & vd,const VRegister & vn,const VRegister & vm,const VRegister & va)915   void Fnmsub(const VRegister& vd,
916               const VRegister& vn,
917               const VRegister& vm,
918               const VRegister& va) {
919     SingleEmissionCheckScope guard(this);
920     fnmsub(vd, vn, vm, va);
921   }
Fsub(const VRegister & vd,const VRegister & vn,const VRegister & vm)922   void Fsub(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
923     SingleEmissionCheckScope guard(this);
924     fsub(vd, vn, vm);
925   }
Hint(SystemHint code)926   void Hint(SystemHint code) {
927     SingleEmissionCheckScope guard(this);
928     hint(code);
929   }
Hlt(int code)930   void Hlt(int code) {
931     SingleEmissionCheckScope guard(this);
932     hlt(code);
933   }
Isb()934   void Isb() {
935     SingleEmissionCheckScope guard(this);
936     isb();
937   }
Ldar(const Register & rt,const MemOperand & src)938   void Ldar(const Register& rt, const MemOperand& src) {
939     SingleEmissionCheckScope guard(this);
940     ldar(rt, src);
941   }
Ldarb(const Register & rt,const MemOperand & src)942   void Ldarb(const Register& rt, const MemOperand& src) {
943     SingleEmissionCheckScope guard(this);
944     ldarb(rt, src);
945   }
Ldarh(const Register & rt,const MemOperand & src)946   void Ldarh(const Register& rt, const MemOperand& src) {
947     SingleEmissionCheckScope guard(this);
948     ldarh(rt, src);
949   }
Ldaxp(const Register & rt,const Register & rt2,const MemOperand & src)950   void Ldaxp(const Register& rt, const Register& rt2, const MemOperand& src) {
951     VIXL_ASSERT(!rt.Aliases(rt2));
952     SingleEmissionCheckScope guard(this);
953     ldaxp(rt, rt2, src);
954   }
Ldaxr(const Register & rt,const MemOperand & src)955   void Ldaxr(const Register& rt, const MemOperand& src) {
956     SingleEmissionCheckScope guard(this);
957     ldaxr(rt, src);
958   }
Ldaxrb(const Register & rt,const MemOperand & src)959   void Ldaxrb(const Register& rt, const MemOperand& src) {
960     SingleEmissionCheckScope guard(this);
961     ldaxrb(rt, src);
962   }
Ldaxrh(const Register & rt,const MemOperand & src)963   void Ldaxrh(const Register& rt, const MemOperand& src) {
964     SingleEmissionCheckScope guard(this);
965     ldaxrh(rt, src);
966   }
Ldnp(const CPURegister & rt,const CPURegister & rt2,const MemOperand & src)967   void Ldnp(const CPURegister& rt,
968             const CPURegister& rt2,
969             const MemOperand& src) {
970     SingleEmissionCheckScope guard(this);
971     ldnp(rt, rt2, src);
972   }
973   // Provide both double and float interfaces for FP immediate loads, rather
974   // than relying on implicit C++ casts. This allows signalling NaNs to be
975   // preserved when the immediate matches the format of fd. Most systems convert
976   // signalling NaNs to quiet NaNs when converting between float and double.
Ldr(const VRegister & vt,double imm)977   void Ldr(const VRegister& vt, double imm) {
978     SingleEmissionCheckScope guard(this);
979     if (vt.Is64Bits()) {
980       ldr(vt, imm);
981     } else {
982       ldr(vt, static_cast<float>(imm));
983     }
984   }
Ldr(const VRegister & vt,float imm)985   void Ldr(const VRegister& vt, float imm) {
986     SingleEmissionCheckScope guard(this);
987     if (vt.Is32Bits()) {
988       ldr(vt, imm);
989     } else {
990       ldr(vt, static_cast<double>(imm));
991     }
992   }
993   /*
994   void Ldr(const VRegister& vt, uint64_t high64, uint64_t low64) {
995     VIXL_ASSERT(vt.IsQ());
996     SingleEmissionCheckScope guard(this);
997     ldr(vt, new Literal<uint64_t>(high64, low64,
998                                   &literal_pool_,
999                                   RawLiteral::kDeletedOnPlacementByPool));
1000   }
1001   */
Ldr(const Register & rt,uint64_t imm)1002   void Ldr(const Register& rt, uint64_t imm) {
1003     VIXL_ASSERT(!rt.IsZero());
1004     SingleEmissionCheckScope guard(this);
1005     ldr(rt, imm);
1006   }
Ldrsw(const Register & rt,uint32_t imm)1007   void Ldrsw(const Register& rt, uint32_t imm) {
1008     VIXL_ASSERT(!rt.IsZero());
1009     SingleEmissionCheckScope guard(this);
1010     ldrsw(rt, imm);
1011   }
Ldxp(const Register & rt,const Register & rt2,const MemOperand & src)1012   void Ldxp(const Register& rt, const Register& rt2, const MemOperand& src) {
1013     VIXL_ASSERT(!rt.Aliases(rt2));
1014     SingleEmissionCheckScope guard(this);
1015     ldxp(rt, rt2, src);
1016   }
Ldxr(const Register & rt,const MemOperand & src)1017   void Ldxr(const Register& rt, const MemOperand& src) {
1018     SingleEmissionCheckScope guard(this);
1019     ldxr(rt, src);
1020   }
Ldxrb(const Register & rt,const MemOperand & src)1021   void Ldxrb(const Register& rt, const MemOperand& src) {
1022     SingleEmissionCheckScope guard(this);
1023     ldxrb(rt, src);
1024   }
Ldxrh(const Register & rt,const MemOperand & src)1025   void Ldxrh(const Register& rt, const MemOperand& src) {
1026     SingleEmissionCheckScope guard(this);
1027     ldxrh(rt, src);
1028   }
Lsl(const Register & rd,const Register & rn,unsigned shift)1029   void Lsl(const Register& rd, const Register& rn, unsigned shift) {
1030     VIXL_ASSERT(!rd.IsZero());
1031     VIXL_ASSERT(!rn.IsZero());
1032     SingleEmissionCheckScope guard(this);
1033     lsl(rd, rn, shift);
1034   }
Lsl(const Register & rd,const Register & rn,const Register & rm)1035   void Lsl(const Register& rd, const Register& rn, const Register& rm) {
1036     VIXL_ASSERT(!rd.IsZero());
1037     VIXL_ASSERT(!rn.IsZero());
1038     VIXL_ASSERT(!rm.IsZero());
1039     SingleEmissionCheckScope guard(this);
1040     lslv(rd, rn, rm);
1041   }
Lsr(const Register & rd,const Register & rn,unsigned shift)1042   void Lsr(const Register& rd, const Register& rn, unsigned shift) {
1043     VIXL_ASSERT(!rd.IsZero());
1044     VIXL_ASSERT(!rn.IsZero());
1045     SingleEmissionCheckScope guard(this);
1046     lsr(rd, rn, shift);
1047   }
Lsr(const Register & rd,const Register & rn,const Register & rm)1048   void Lsr(const Register& rd, const Register& rn, const Register& rm) {
1049     VIXL_ASSERT(!rd.IsZero());
1050     VIXL_ASSERT(!rn.IsZero());
1051     VIXL_ASSERT(!rm.IsZero());
1052     SingleEmissionCheckScope guard(this);
1053     lsrv(rd, rn, rm);
1054   }
Madd(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1055   void Madd(const Register& rd,
1056             const Register& rn,
1057             const Register& rm,
1058             const Register& ra) {
1059     VIXL_ASSERT(!rd.IsZero());
1060     VIXL_ASSERT(!rn.IsZero());
1061     VIXL_ASSERT(!rm.IsZero());
1062     VIXL_ASSERT(!ra.IsZero());
1063     SingleEmissionCheckScope guard(this);
1064     madd(rd, rn, rm, ra);
1065   }
Mneg(const Register & rd,const Register & rn,const Register & rm)1066   void Mneg(const Register& rd, const Register& rn, const Register& rm) {
1067     VIXL_ASSERT(!rd.IsZero());
1068     VIXL_ASSERT(!rn.IsZero());
1069     VIXL_ASSERT(!rm.IsZero());
1070     SingleEmissionCheckScope guard(this);
1071     mneg(rd, rn, rm);
1072   }
Mov(const Register & rd,const Register & rn)1073   void Mov(const Register& rd, const Register& rn) {
1074     SingleEmissionCheckScope guard(this);
1075     mov(rd, rn);
1076   }
1077   void Movk(const Register& rd, uint64_t imm, int shift = -1) {
1078     VIXL_ASSERT(!rd.IsZero());
1079     SingleEmissionCheckScope guard(this);
1080     movk(rd, imm, shift);
1081   }
Mrs(const Register & rt,SystemRegister sysreg)1082   void Mrs(const Register& rt, SystemRegister sysreg) {
1083     VIXL_ASSERT(!rt.IsZero());
1084     SingleEmissionCheckScope guard(this);
1085     mrs(rt, sysreg);
1086   }
Msr(SystemRegister sysreg,const Register & rt)1087   void Msr(SystemRegister sysreg, const Register& rt) {
1088     VIXL_ASSERT(!rt.IsZero());
1089     SingleEmissionCheckScope guard(this);
1090     msr(sysreg, rt);
1091   }
1092   void Sys(int op1, int crn, int crm, int op2, const Register& rt = xzr) {
1093     SingleEmissionCheckScope guard(this);
1094     sys(op1, crn, crm, op2, rt);
1095   }
Dc(DataCacheOp op,const Register & rt)1096   void Dc(DataCacheOp op, const Register& rt) {
1097     SingleEmissionCheckScope guard(this);
1098     dc(op, rt);
1099   }
Ic(InstructionCacheOp op,const Register & rt)1100   void Ic(InstructionCacheOp op, const Register& rt) {
1101     SingleEmissionCheckScope guard(this);
1102     ic(op, rt);
1103   }
Msub(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1104   void Msub(const Register& rd,
1105             const Register& rn,
1106             const Register& rm,
1107             const Register& ra) {
1108     VIXL_ASSERT(!rd.IsZero());
1109     VIXL_ASSERT(!rn.IsZero());
1110     VIXL_ASSERT(!rm.IsZero());
1111     VIXL_ASSERT(!ra.IsZero());
1112     SingleEmissionCheckScope guard(this);
1113     msub(rd, rn, rm, ra);
1114   }
Mul(const Register & rd,const Register & rn,const Register & rm)1115   void Mul(const Register& rd, const Register& rn, const Register& rm) {
1116     VIXL_ASSERT(!rd.IsZero());
1117     VIXL_ASSERT(!rn.IsZero());
1118     VIXL_ASSERT(!rm.IsZero());
1119     SingleEmissionCheckScope guard(this);
1120     mul(rd, rn, rm);
1121   }
Nop()1122   void Nop() {
1123     SingleEmissionCheckScope guard(this);
1124     nop();
1125   }
Csdb()1126   void Csdb() {
1127     SingleEmissionCheckScope guard(this);
1128     csdb();
1129   }
Rbit(const Register & rd,const Register & rn)1130   void Rbit(const Register& rd, const Register& rn) {
1131     VIXL_ASSERT(!rd.IsZero());
1132     VIXL_ASSERT(!rn.IsZero());
1133     SingleEmissionCheckScope guard(this);
1134     rbit(rd, rn);
1135   }
1136   void Ret(const Register& xn = lr) {
1137     VIXL_ASSERT(!xn.IsZero());
1138     SingleEmissionCheckScope guard(this);
1139     ret(xn);
1140   }
Rev(const Register & rd,const Register & rn)1141   void Rev(const Register& rd, const Register& rn) {
1142     VIXL_ASSERT(!rd.IsZero());
1143     VIXL_ASSERT(!rn.IsZero());
1144     SingleEmissionCheckScope guard(this);
1145     rev(rd, rn);
1146   }
Rev16(const Register & rd,const Register & rn)1147   void Rev16(const Register& rd, const Register& rn) {
1148     VIXL_ASSERT(!rd.IsZero());
1149     VIXL_ASSERT(!rn.IsZero());
1150     SingleEmissionCheckScope guard(this);
1151     rev16(rd, rn);
1152   }
Rev32(const Register & rd,const Register & rn)1153   void Rev32(const Register& rd, const Register& rn) {
1154     VIXL_ASSERT(!rd.IsZero());
1155     VIXL_ASSERT(!rn.IsZero());
1156     SingleEmissionCheckScope guard(this);
1157     rev32(rd, rn);
1158   }
Ror(const Register & rd,const Register & rs,unsigned shift)1159   void Ror(const Register& rd, const Register& rs, unsigned shift) {
1160     VIXL_ASSERT(!rd.IsZero());
1161     VIXL_ASSERT(!rs.IsZero());
1162     SingleEmissionCheckScope guard(this);
1163     ror(rd, rs, shift);
1164   }
Ror(const Register & rd,const Register & rn,const Register & rm)1165   void Ror(const Register& rd, const Register& rn, const Register& rm) {
1166     VIXL_ASSERT(!rd.IsZero());
1167     VIXL_ASSERT(!rn.IsZero());
1168     VIXL_ASSERT(!rm.IsZero());
1169     SingleEmissionCheckScope guard(this);
1170     rorv(rd, rn, rm);
1171   }
Sbfiz(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1172   void Sbfiz(const Register& rd,
1173              const Register& rn,
1174              unsigned lsb,
1175              unsigned width) {
1176     VIXL_ASSERT(!rd.IsZero());
1177     VIXL_ASSERT(!rn.IsZero());
1178     SingleEmissionCheckScope guard(this);
1179     sbfiz(rd, rn, lsb, width);
1180   }
Sbfm(const Register & rd,const Register & rn,unsigned immr,unsigned imms)1181   void Sbfm(const Register& rd,
1182             const Register& rn,
1183             unsigned immr,
1184             unsigned imms) {
1185     VIXL_ASSERT(!rd.IsZero());
1186     VIXL_ASSERT(!rn.IsZero());
1187     SingleEmissionCheckScope guard(this);
1188     sbfm(rd, rn, immr, imms);
1189   }
Sbfx(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1190   void Sbfx(const Register& rd,
1191             const Register& rn,
1192             unsigned lsb,
1193             unsigned width) {
1194     VIXL_ASSERT(!rd.IsZero());
1195     VIXL_ASSERT(!rn.IsZero());
1196     SingleEmissionCheckScope guard(this);
1197     sbfx(rd, rn, lsb, width);
1198   }
1199   void Scvtf(const VRegister& vd, const Register& rn, int fbits = 0) {
1200     VIXL_ASSERT(!rn.IsZero());
1201     SingleEmissionCheckScope guard(this);
1202     scvtf(vd, rn, fbits);
1203   }
Sdiv(const Register & rd,const Register & rn,const Register & rm)1204   void Sdiv(const Register& rd, const Register& rn, const Register& rm) {
1205     VIXL_ASSERT(!rd.IsZero());
1206     VIXL_ASSERT(!rn.IsZero());
1207     VIXL_ASSERT(!rm.IsZero());
1208     SingleEmissionCheckScope guard(this);
1209     sdiv(rd, rn, rm);
1210   }
Smaddl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1211   void Smaddl(const Register& rd,
1212               const Register& rn,
1213               const Register& rm,
1214               const Register& ra) {
1215     VIXL_ASSERT(!rd.IsZero());
1216     VIXL_ASSERT(!rn.IsZero());
1217     VIXL_ASSERT(!rm.IsZero());
1218     VIXL_ASSERT(!ra.IsZero());
1219     SingleEmissionCheckScope guard(this);
1220     smaddl(rd, rn, rm, ra);
1221   }
Smsubl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1222   void Smsubl(const Register& rd,
1223               const Register& rn,
1224               const Register& rm,
1225               const Register& ra) {
1226     VIXL_ASSERT(!rd.IsZero());
1227     VIXL_ASSERT(!rn.IsZero());
1228     VIXL_ASSERT(!rm.IsZero());
1229     VIXL_ASSERT(!ra.IsZero());
1230     SingleEmissionCheckScope guard(this);
1231     smsubl(rd, rn, rm, ra);
1232   }
Smull(const Register & rd,const Register & rn,const Register & rm)1233   void Smull(const Register& rd, const Register& rn, const Register& rm) {
1234     VIXL_ASSERT(!rd.IsZero());
1235     VIXL_ASSERT(!rn.IsZero());
1236     VIXL_ASSERT(!rm.IsZero());
1237     SingleEmissionCheckScope guard(this);
1238     smull(rd, rn, rm);
1239   }
Smulh(const Register & xd,const Register & xn,const Register & xm)1240   void Smulh(const Register& xd, const Register& xn, const Register& xm) {
1241     VIXL_ASSERT(!xd.IsZero());
1242     VIXL_ASSERT(!xn.IsZero());
1243     VIXL_ASSERT(!xm.IsZero());
1244     SingleEmissionCheckScope guard(this);
1245     smulh(xd, xn, xm);
1246   }
Stlr(const Register & rt,const MemOperand & dst)1247   void Stlr(const Register& rt, const MemOperand& dst) {
1248     SingleEmissionCheckScope guard(this);
1249     stlr(rt, dst);
1250   }
Stlrb(const Register & rt,const MemOperand & dst)1251   void Stlrb(const Register& rt, const MemOperand& dst) {
1252     SingleEmissionCheckScope guard(this);
1253     stlrb(rt, dst);
1254   }
Stlrh(const Register & rt,const MemOperand & dst)1255   void Stlrh(const Register& rt, const MemOperand& dst) {
1256     SingleEmissionCheckScope guard(this);
1257     stlrh(rt, dst);
1258   }
Stlxp(const Register & rs,const Register & rt,const Register & rt2,const MemOperand & dst)1259   void Stlxp(const Register& rs,
1260              const Register& rt,
1261              const Register& rt2,
1262              const MemOperand& dst) {
1263     VIXL_ASSERT(!rs.Aliases(dst.base()));
1264     VIXL_ASSERT(!rs.Aliases(rt));
1265     VIXL_ASSERT(!rs.Aliases(rt2));
1266     SingleEmissionCheckScope guard(this);
1267     stlxp(rs, rt, rt2, dst);
1268   }
Stlxr(const Register & rs,const Register & rt,const MemOperand & dst)1269   void Stlxr(const Register& rs, const Register& rt, const MemOperand& dst) {
1270     VIXL_ASSERT(!rs.Aliases(dst.base()));
1271     VIXL_ASSERT(!rs.Aliases(rt));
1272     SingleEmissionCheckScope guard(this);
1273     stlxr(rs, rt, dst);
1274   }
Stlxrb(const Register & rs,const Register & rt,const MemOperand & dst)1275   void Stlxrb(const Register& rs, const Register& rt, const MemOperand& dst) {
1276     VIXL_ASSERT(!rs.Aliases(dst.base()));
1277     VIXL_ASSERT(!rs.Aliases(rt));
1278     SingleEmissionCheckScope guard(this);
1279     stlxrb(rs, rt, dst);
1280   }
Stlxrh(const Register & rs,const Register & rt,const MemOperand & dst)1281   void Stlxrh(const Register& rs, const Register& rt, const MemOperand& dst) {
1282     VIXL_ASSERT(!rs.Aliases(dst.base()));
1283     VIXL_ASSERT(!rs.Aliases(rt));
1284     SingleEmissionCheckScope guard(this);
1285     stlxrh(rs, rt, dst);
1286   }
Stnp(const CPURegister & rt,const CPURegister & rt2,const MemOperand & dst)1287   void Stnp(const CPURegister& rt,
1288             const CPURegister& rt2,
1289             const MemOperand& dst) {
1290     SingleEmissionCheckScope guard(this);
1291     stnp(rt, rt2, dst);
1292   }
Stxp(const Register & rs,const Register & rt,const Register & rt2,const MemOperand & dst)1293   void Stxp(const Register& rs,
1294             const Register& rt,
1295             const Register& rt2,
1296             const MemOperand& dst) {
1297     VIXL_ASSERT(!rs.Aliases(dst.base()));
1298     VIXL_ASSERT(!rs.Aliases(rt));
1299     VIXL_ASSERT(!rs.Aliases(rt2));
1300     SingleEmissionCheckScope guard(this);
1301     stxp(rs, rt, rt2, dst);
1302   }
Stxr(const Register & rs,const Register & rt,const MemOperand & dst)1303   void Stxr(const Register& rs, const Register& rt, const MemOperand& dst) {
1304     VIXL_ASSERT(!rs.Aliases(dst.base()));
1305     VIXL_ASSERT(!rs.Aliases(rt));
1306     SingleEmissionCheckScope guard(this);
1307     stxr(rs, rt, dst);
1308   }
Stxrb(const Register & rs,const Register & rt,const MemOperand & dst)1309   void Stxrb(const Register& rs, const Register& rt, const MemOperand& dst) {
1310     VIXL_ASSERT(!rs.Aliases(dst.base()));
1311     VIXL_ASSERT(!rs.Aliases(rt));
1312     SingleEmissionCheckScope guard(this);
1313     stxrb(rs, rt, dst);
1314   }
Stxrh(const Register & rs,const Register & rt,const MemOperand & dst)1315   void Stxrh(const Register& rs, const Register& rt, const MemOperand& dst) {
1316     VIXL_ASSERT(!rs.Aliases(dst.base()));
1317     VIXL_ASSERT(!rs.Aliases(rt));
1318     SingleEmissionCheckScope guard(this);
1319     stxrh(rs, rt, dst);
1320   }
Svc(int code)1321   void Svc(int code) {
1322     SingleEmissionCheckScope guard(this);
1323     svc(code);
1324   }
Sxtb(const Register & rd,const Register & rn)1325   void Sxtb(const Register& rd, const Register& rn) {
1326     VIXL_ASSERT(!rd.IsZero());
1327     VIXL_ASSERT(!rn.IsZero());
1328     SingleEmissionCheckScope guard(this);
1329     sxtb(rd, rn);
1330   }
Sxth(const Register & rd,const Register & rn)1331   void Sxth(const Register& rd, const Register& rn) {
1332     VIXL_ASSERT(!rd.IsZero());
1333     VIXL_ASSERT(!rn.IsZero());
1334     SingleEmissionCheckScope guard(this);
1335     sxth(rd, rn);
1336   }
Sxtw(const Register & rd,const Register & rn)1337   void Sxtw(const Register& rd, const Register& rn) {
1338     VIXL_ASSERT(!rd.IsZero());
1339     VIXL_ASSERT(!rn.IsZero());
1340     SingleEmissionCheckScope guard(this);
1341     sxtw(rd, rn);
1342   }
Tbl(const VRegister & vd,const VRegister & vn,const VRegister & vm)1343   void Tbl(const VRegister& vd,
1344            const VRegister& vn,
1345            const VRegister& vm) {
1346     SingleEmissionCheckScope guard(this);
1347     tbl(vd, vn, vm);
1348   }
Tbl(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vm)1349   void Tbl(const VRegister& vd,
1350            const VRegister& vn,
1351            const VRegister& vn2,
1352            const VRegister& vm) {
1353     SingleEmissionCheckScope guard(this);
1354     tbl(vd, vn, vn2, vm);
1355   }
Tbl(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vn3,const VRegister & vm)1356   void Tbl(const VRegister& vd,
1357            const VRegister& vn,
1358            const VRegister& vn2,
1359            const VRegister& vn3,
1360            const VRegister& vm) {
1361     SingleEmissionCheckScope guard(this);
1362     tbl(vd, vn, vn2, vn3, vm);
1363   }
Tbl(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vn3,const VRegister & vn4,const VRegister & vm)1364   void Tbl(const VRegister& vd,
1365            const VRegister& vn,
1366            const VRegister& vn2,
1367            const VRegister& vn3,
1368            const VRegister& vn4,
1369            const VRegister& vm) {
1370     SingleEmissionCheckScope guard(this);
1371     tbl(vd, vn, vn2, vn3, vn4, vm);
1372   }
Tbx(const VRegister & vd,const VRegister & vn,const VRegister & vm)1373   void Tbx(const VRegister& vd,
1374            const VRegister& vn,
1375            const VRegister& vm) {
1376     SingleEmissionCheckScope guard(this);
1377     tbx(vd, vn, vm);
1378   }
Tbx(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vm)1379   void Tbx(const VRegister& vd,
1380            const VRegister& vn,
1381            const VRegister& vn2,
1382            const VRegister& vm) {
1383     SingleEmissionCheckScope guard(this);
1384     tbx(vd, vn, vn2, vm);
1385   }
Tbx(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vn3,const VRegister & vm)1386   void Tbx(const VRegister& vd,
1387            const VRegister& vn,
1388            const VRegister& vn2,
1389            const VRegister& vn3,
1390            const VRegister& vm) {
1391     SingleEmissionCheckScope guard(this);
1392     tbx(vd, vn, vn2, vn3, vm);
1393   }
Tbx(const VRegister & vd,const VRegister & vn,const VRegister & vn2,const VRegister & vn3,const VRegister & vn4,const VRegister & vm)1394   void Tbx(const VRegister& vd,
1395            const VRegister& vn,
1396            const VRegister& vn2,
1397            const VRegister& vn3,
1398            const VRegister& vn4,
1399            const VRegister& vm) {
1400     SingleEmissionCheckScope guard(this);
1401     tbx(vd, vn, vn2, vn3, vn4, vm);
1402   }
1403   void Tbnz(const Register& rt, unsigned bit_pos, Label* label);
1404   void Tbz(const Register& rt, unsigned bit_pos, Label* label);
Ubfiz(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1405   void Ubfiz(const Register& rd,
1406              const Register& rn,
1407              unsigned lsb,
1408              unsigned width) {
1409     VIXL_ASSERT(!rd.IsZero());
1410     VIXL_ASSERT(!rn.IsZero());
1411     SingleEmissionCheckScope guard(this);
1412     ubfiz(rd, rn, lsb, width);
1413   }
Ubfm(const Register & rd,const Register & rn,unsigned immr,unsigned imms)1414   void Ubfm(const Register& rd,
1415             const Register& rn,
1416             unsigned immr,
1417             unsigned imms) {
1418     VIXL_ASSERT(!rd.IsZero());
1419     VIXL_ASSERT(!rn.IsZero());
1420     SingleEmissionCheckScope guard(this);
1421     ubfm(rd, rn, immr, imms);
1422   }
Ubfx(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1423   void Ubfx(const Register& rd,
1424             const Register& rn,
1425             unsigned lsb,
1426             unsigned width) {
1427     VIXL_ASSERT(!rd.IsZero());
1428     VIXL_ASSERT(!rn.IsZero());
1429     SingleEmissionCheckScope guard(this);
1430     ubfx(rd, rn, lsb, width);
1431   }
1432   void Ucvtf(const VRegister& vd, const Register& rn, int fbits = 0) {
1433     VIXL_ASSERT(!rn.IsZero());
1434     SingleEmissionCheckScope guard(this);
1435     ucvtf(vd, rn, fbits);
1436   }
Udiv(const Register & rd,const Register & rn,const Register & rm)1437   void Udiv(const Register& rd, const Register& rn, const Register& rm) {
1438     VIXL_ASSERT(!rd.IsZero());
1439     VIXL_ASSERT(!rn.IsZero());
1440     VIXL_ASSERT(!rm.IsZero());
1441     SingleEmissionCheckScope guard(this);
1442     udiv(rd, rn, rm);
1443   }
Umaddl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1444   void Umaddl(const Register& rd,
1445               const Register& rn,
1446               const Register& rm,
1447               const Register& ra) {
1448     VIXL_ASSERT(!rd.IsZero());
1449     VIXL_ASSERT(!rn.IsZero());
1450     VIXL_ASSERT(!rm.IsZero());
1451     VIXL_ASSERT(!ra.IsZero());
1452     SingleEmissionCheckScope guard(this);
1453     umaddl(rd, rn, rm, ra);
1454   }
Umull(const Register & rd,const Register & rn,const Register & rm)1455   void Umull(const Register& rd,
1456              const Register& rn,
1457              const Register& rm) {
1458     VIXL_ASSERT(!rd.IsZero());
1459     VIXL_ASSERT(!rn.IsZero());
1460     VIXL_ASSERT(!rm.IsZero());
1461     SingleEmissionCheckScope guard(this);
1462     umull(rd, rn, rm);
1463   }
Umulh(const Register & xd,const Register & xn,const Register & xm)1464   void Umulh(const Register& xd, const Register& xn, const Register& xm) {
1465     VIXL_ASSERT(!xd.IsZero());
1466     VIXL_ASSERT(!xn.IsZero());
1467     VIXL_ASSERT(!xm.IsZero());
1468     SingleEmissionCheckScope guard(this);
1469     umulh(xd, xn, xm);
1470   }
Umsubl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1471   void Umsubl(const Register& rd,
1472               const Register& rn,
1473               const Register& rm,
1474               const Register& ra) {
1475     VIXL_ASSERT(!rd.IsZero());
1476     VIXL_ASSERT(!rn.IsZero());
1477     VIXL_ASSERT(!rm.IsZero());
1478     VIXL_ASSERT(!ra.IsZero());
1479     SingleEmissionCheckScope guard(this);
1480     umsubl(rd, rn, rm, ra);
1481   }
Unreachable()1482   void Unreachable() {
1483     SingleEmissionCheckScope guard(this);
1484 #ifdef JS_SIMULATOR_ARM64
1485     hlt(kUnreachableOpcode);
1486 #else
1487     // A couple of strategies we can use here.  There are no unencoded
1488     // instructions in the instruction set that are guaranteed to remain that
1489     // way.  However there are some currently (as of 2018) unencoded
1490     // instructions that are good candidates.
1491     //
1492     // Ideally, unencoded instructions should be non-destructive to the register
1493     // state, and should be unencoded at all exception levels.
1494     //
1495     // At the trap the pc will hold the address of the offending instruction.
1496 
1497     // Some candidates for unencoded instructions:
1498     //
1499     // 0xd4a00000 (essentially dcps0, a good one since it is nonsensical and may
1500     //             remain unencoded in the future for that reason)
1501     // 0x33000000 (bfm variant)
1502     // 0xd67f0000 (br variant)
1503     // 0x5ac00c00 (rbit variant)
1504 
1505     Emit(0xd4a00000);		// "dcps0", also has 16-bit payload if needed
1506 #endif
1507   }
Uxtb(const Register & rd,const Register & rn)1508   void Uxtb(const Register& rd, const Register& rn) {
1509     VIXL_ASSERT(!rd.IsZero());
1510     VIXL_ASSERT(!rn.IsZero());
1511     SingleEmissionCheckScope guard(this);
1512     uxtb(rd, rn);
1513   }
Uxth(const Register & rd,const Register & rn)1514   void Uxth(const Register& rd, const Register& rn) {
1515     VIXL_ASSERT(!rd.IsZero());
1516     VIXL_ASSERT(!rn.IsZero());
1517     SingleEmissionCheckScope guard(this);
1518     uxth(rd, rn);
1519   }
Uxtw(const Register & rd,const Register & rn)1520   void Uxtw(const Register& rd, const Register& rn) {
1521     VIXL_ASSERT(!rd.IsZero());
1522     VIXL_ASSERT(!rn.IsZero());
1523     SingleEmissionCheckScope guard(this);
1524     uxtw(rd, rn);
1525   }
1526 
1527   // NEON 3 vector register instructions.
1528   #define NEON_3VREG_MACRO_LIST(V) \
1529     V(add, Add)                    \
1530     V(addhn, Addhn)                \
1531     V(addhn2, Addhn2)              \
1532     V(addp, Addp)                  \
1533     V(and_, And)                   \
1534     V(bic, Bic)                    \
1535     V(bif, Bif)                    \
1536     V(bit, Bit)                    \
1537     V(bsl, Bsl)                    \
1538     V(cmeq, Cmeq)                  \
1539     V(cmge, Cmge)                  \
1540     V(cmgt, Cmgt)                  \
1541     V(cmhi, Cmhi)                  \
1542     V(cmhs, Cmhs)                  \
1543     V(cmtst, Cmtst)                \
1544     V(eor, Eor)                    \
1545     V(fabd, Fabd)                  \
1546     V(facge, Facge)                \
1547     V(facgt, Facgt)                \
1548     V(faddp, Faddp)                \
1549     V(fcmeq, Fcmeq)                \
1550     V(fcmge, Fcmge)                \
1551     V(fcmgt, Fcmgt)                \
1552     V(fmaxnmp, Fmaxnmp)            \
1553     V(fmaxp, Fmaxp)                \
1554     V(fminnmp, Fminnmp)            \
1555     V(fminp, Fminp)                \
1556     V(fmla, Fmla)                  \
1557     V(fmls, Fmls)                  \
1558     V(fmulx, Fmulx)                \
1559     V(frecps, Frecps)              \
1560     V(frsqrts, Frsqrts)            \
1561     V(mla, Mla)                    \
1562     V(mls, Mls)                    \
1563     V(mul, Mul)                    \
1564     V(orn, Orn)                    \
1565     V(orr, Orr)                    \
1566     V(pmul, Pmul)                  \
1567     V(pmull, Pmull)                \
1568     V(pmull2, Pmull2)              \
1569     V(raddhn, Raddhn)              \
1570     V(raddhn2, Raddhn2)            \
1571     V(rsubhn, Rsubhn)              \
1572     V(rsubhn2, Rsubhn2)            \
1573     V(saba, Saba)                  \
1574     V(sabal, Sabal)                \
1575     V(sabal2, Sabal2)              \
1576     V(sabd, Sabd)                  \
1577     V(sabdl, Sabdl)                \
1578     V(sabdl2, Sabdl2)              \
1579     V(saddl, Saddl)                \
1580     V(saddl2, Saddl2)              \
1581     V(saddw, Saddw)                \
1582     V(saddw2, Saddw2)              \
1583     V(shadd, Shadd)                \
1584     V(shsub, Shsub)                \
1585     V(smax, Smax)                  \
1586     V(smaxp, Smaxp)                \
1587     V(smin, Smin)                  \
1588     V(sminp, Sminp)                \
1589     V(smlal, Smlal)                \
1590     V(smlal2, Smlal2)              \
1591     V(smlsl, Smlsl)                \
1592     V(smlsl2, Smlsl2)              \
1593     V(smull, Smull)                \
1594     V(smull2, Smull2)              \
1595     V(sqadd, Sqadd)                \
1596     V(sqdmlal, Sqdmlal)            \
1597     V(sqdmlal2, Sqdmlal2)          \
1598     V(sqdmlsl, Sqdmlsl)            \
1599     V(sqdmlsl2, Sqdmlsl2)          \
1600     V(sqdmulh, Sqdmulh)            \
1601     V(sqdmull, Sqdmull)            \
1602     V(sqdmull2, Sqdmull2)          \
1603     V(sqrdmulh, Sqrdmulh)          \
1604     V(sqrshl, Sqrshl)              \
1605     V(sqshl, Sqshl)                \
1606     V(sqsub, Sqsub)                \
1607     V(srhadd, Srhadd)              \
1608     V(srshl, Srshl)                \
1609     V(sshl, Sshl)                  \
1610     V(ssubl, Ssubl)                \
1611     V(ssubl2, Ssubl2)              \
1612     V(ssubw, Ssubw)                \
1613     V(ssubw2, Ssubw2)              \
1614     V(sub, Sub)                    \
1615     V(subhn, Subhn)                \
1616     V(subhn2, Subhn2)              \
1617     V(trn1, Trn1)                  \
1618     V(trn2, Trn2)                  \
1619     V(uaba, Uaba)                  \
1620     V(uabal, Uabal)                \
1621     V(uabal2, Uabal2)              \
1622     V(uabd, Uabd)                  \
1623     V(uabdl, Uabdl)                \
1624     V(uabdl2, Uabdl2)              \
1625     V(uaddl, Uaddl)                \
1626     V(uaddl2, Uaddl2)              \
1627     V(uaddw, Uaddw)                \
1628     V(uaddw2, Uaddw2)              \
1629     V(uhadd, Uhadd)                \
1630     V(uhsub, Uhsub)                \
1631     V(umax, Umax)                  \
1632     V(umaxp, Umaxp)                \
1633     V(umin, Umin)                  \
1634     V(uminp, Uminp)                \
1635     V(umlal, Umlal)                \
1636     V(umlal2, Umlal2)              \
1637     V(umlsl, Umlsl)                \
1638     V(umlsl2, Umlsl2)              \
1639     V(umull, Umull)                \
1640     V(umull2, Umull2)              \
1641     V(uqadd, Uqadd)                \
1642     V(uqrshl, Uqrshl)              \
1643     V(uqshl, Uqshl)                \
1644     V(uqsub, Uqsub)                \
1645     V(urhadd, Urhadd)              \
1646     V(urshl, Urshl)                \
1647     V(ushl, Ushl)                  \
1648     V(usubl, Usubl)                \
1649     V(usubl2, Usubl2)              \
1650     V(usubw, Usubw)                \
1651     V(usubw2, Usubw2)              \
1652     V(uzp1, Uzp1)                  \
1653     V(uzp2, Uzp2)                  \
1654     V(zip1, Zip1)                  \
1655     V(zip2, Zip2)
1656 
1657   #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)   \
1658   void MASM(const VRegister& vd,             \
1659             const VRegister& vn,             \
1660             const VRegister& vm) {           \
1661     SingleEmissionCheckScope guard(this);    \
1662     ASM(vd, vn, vm);                         \
1663   }
1664   NEON_3VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
1665   #undef DEFINE_MACRO_ASM_FUNC
1666 
1667   // NEON 2 vector register instructions.
1668   #define NEON_2VREG_MACRO_LIST(V) \
1669     V(abs,     Abs)                \
1670     V(addp,    Addp)               \
1671     V(addv,    Addv)               \
1672     V(cls,     Cls)                \
1673     V(clz,     Clz)                \
1674     V(cnt,     Cnt)                \
1675     V(fabs,    Fabs)               \
1676     V(faddp,   Faddp)              \
1677     V(fcvtas,  Fcvtas)             \
1678     V(fcvtau,  Fcvtau)             \
1679     V(fcvtms,  Fcvtms)             \
1680     V(fcvtmu,  Fcvtmu)             \
1681     V(fcvtns,  Fcvtns)             \
1682     V(fcvtnu,  Fcvtnu)             \
1683     V(fcvtps,  Fcvtps)             \
1684     V(fcvtpu,  Fcvtpu)             \
1685     V(fmaxnmp, Fmaxnmp)            \
1686     V(fmaxnmv, Fmaxnmv)            \
1687     V(fmaxp,   Fmaxp)              \
1688     V(fmaxv,   Fmaxv)              \
1689     V(fminnmp, Fminnmp)            \
1690     V(fminnmv, Fminnmv)            \
1691     V(fminp,   Fminp)              \
1692     V(fminv,   Fminv)              \
1693     V(fneg,    Fneg)               \
1694     V(frecpe,  Frecpe)             \
1695     V(frecpx,  Frecpx)             \
1696     V(frinta,  Frinta)             \
1697     V(frinti,  Frinti)             \
1698     V(frintm,  Frintm)             \
1699     V(frintn,  Frintn)             \
1700     V(frintp,  Frintp)             \
1701     V(frintx,  Frintx)             \
1702     V(frintz,  Frintz)             \
1703     V(frsqrte, Frsqrte)            \
1704     V(fsqrt,   Fsqrt)              \
1705     V(mov,     Mov)                \
1706     V(mvn,     Mvn)                \
1707     V(neg,     Neg)                \
1708     V(not_,    Not)                \
1709     V(rbit,    Rbit)               \
1710     V(rev16,   Rev16)              \
1711     V(rev32,   Rev32)              \
1712     V(rev64,   Rev64)              \
1713     V(sadalp,  Sadalp)             \
1714     V(saddlp,  Saddlp)             \
1715     V(saddlv,  Saddlv)             \
1716     V(smaxv,   Smaxv)              \
1717     V(sminv,   Sminv)              \
1718     V(sqabs,   Sqabs)              \
1719     V(sqneg,   Sqneg)              \
1720     V(sqxtn,   Sqxtn)              \
1721     V(sqxtn2,  Sqxtn2)             \
1722     V(sqxtun,  Sqxtun)             \
1723     V(sqxtun2, Sqxtun2)            \
1724     V(suqadd,  Suqadd)             \
1725     V(sxtl,    Sxtl)               \
1726     V(sxtl2,   Sxtl2)              \
1727     V(uadalp,  Uadalp)             \
1728     V(uaddlp,  Uaddlp)             \
1729     V(uaddlv,  Uaddlv)             \
1730     V(umaxv,   Umaxv)              \
1731     V(uminv,   Uminv)              \
1732     V(uqxtn,   Uqxtn)              \
1733     V(uqxtn2,  Uqxtn2)             \
1734     V(urecpe,  Urecpe)             \
1735     V(ursqrte, Ursqrte)            \
1736     V(usqadd,  Usqadd)             \
1737     V(uxtl,    Uxtl)               \
1738     V(uxtl2,   Uxtl2)              \
1739     V(xtn,     Xtn)                \
1740     V(xtn2,    Xtn2)
1741 
1742   #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)   \
1743   void MASM(const VRegister& vd,             \
1744             const VRegister& vn) {           \
1745     SingleEmissionCheckScope guard(this);    \
1746     ASM(vd, vn);                             \
1747   }
NEON_2VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)1748   NEON_2VREG_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
1749   #undef DEFINE_MACRO_ASM_FUNC
1750 
1751   // NEON 2 vector register with immediate instructions.
1752   #define NEON_2VREG_FPIMM_MACRO_LIST(V) \
1753     V(fcmeq, Fcmeq)                      \
1754     V(fcmge, Fcmge)                      \
1755     V(fcmgt, Fcmgt)                      \
1756     V(fcmle, Fcmle)                      \
1757     V(fcmlt, Fcmlt)
1758 
1759   #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)   \
1760   void MASM(const VRegister& vd,             \
1761             const VRegister& vn,             \
1762             double imm) {                    \
1763     SingleEmissionCheckScope guard(this);    \
1764     ASM(vd, vn, imm);                        \
1765   }
1766   NEON_2VREG_FPIMM_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
1767   #undef DEFINE_MACRO_ASM_FUNC
1768 
1769   // NEON by element instructions.
1770   #define NEON_BYELEMENT_MACRO_LIST(V) \
1771     V(fmul, Fmul)                      \
1772     V(fmla, Fmla)                      \
1773     V(fmls, Fmls)                      \
1774     V(fmulx, Fmulx)                    \
1775     V(mul, Mul)                        \
1776     V(mla, Mla)                        \
1777     V(mls, Mls)                        \
1778     V(sqdmulh, Sqdmulh)                \
1779     V(sqrdmulh, Sqrdmulh)              \
1780     V(sqdmull,  Sqdmull)               \
1781     V(sqdmull2, Sqdmull2)              \
1782     V(sqdmlal,  Sqdmlal)               \
1783     V(sqdmlal2, Sqdmlal2)              \
1784     V(sqdmlsl,  Sqdmlsl)               \
1785     V(sqdmlsl2, Sqdmlsl2)              \
1786     V(smull,  Smull)                   \
1787     V(smull2, Smull2)                  \
1788     V(smlal,  Smlal)                   \
1789     V(smlal2, Smlal2)                  \
1790     V(smlsl,  Smlsl)                   \
1791     V(smlsl2, Smlsl2)                  \
1792     V(umull,  Umull)                   \
1793     V(umull2, Umull2)                  \
1794     V(umlal,  Umlal)                   \
1795     V(umlal2, Umlal2)                  \
1796     V(umlsl,  Umlsl)                   \
1797     V(umlsl2, Umlsl2)
1798 
1799   #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)   \
1800   void MASM(const VRegister& vd,             \
1801             const VRegister& vn,             \
1802             const VRegister& vm,             \
1803             int vm_index                     \
1804             ) {                              \
1805     SingleEmissionCheckScope guard(this);    \
1806     ASM(vd, vn, vm, vm_index);               \
1807   }
1808   NEON_BYELEMENT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
1809   #undef DEFINE_MACRO_ASM_FUNC
1810 
1811   #define NEON_2VREG_SHIFT_MACRO_LIST(V) \
1812     V(rshrn,     Rshrn)                  \
1813     V(rshrn2,    Rshrn2)                 \
1814     V(shl,       Shl)                    \
1815     V(shll,      Shll)                   \
1816     V(shll2,     Shll2)                  \
1817     V(shrn,      Shrn)                   \
1818     V(shrn2,     Shrn2)                  \
1819     V(sli,       Sli)                    \
1820     V(sqrshrn,   Sqrshrn)                \
1821     V(sqrshrn2,  Sqrshrn2)               \
1822     V(sqrshrun,  Sqrshrun)               \
1823     V(sqrshrun2, Sqrshrun2)              \
1824     V(sqshl,     Sqshl)                  \
1825     V(sqshlu,    Sqshlu)                 \
1826     V(sqshrn,    Sqshrn)                 \
1827     V(sqshrn2,   Sqshrn2)                \
1828     V(sqshrun,   Sqshrun)                \
1829     V(sqshrun2,  Sqshrun2)               \
1830     V(sri,       Sri)                    \
1831     V(srshr,     Srshr)                  \
1832     V(srsra,     Srsra)                  \
1833     V(sshll,     Sshll)                  \
1834     V(sshll2,    Sshll2)                 \
1835     V(sshr,      Sshr)                   \
1836     V(ssra,      Ssra)                   \
1837     V(uqrshrn,   Uqrshrn)                \
1838     V(uqrshrn2,  Uqrshrn2)               \
1839     V(uqshl,     Uqshl)                  \
1840     V(uqshrn,    Uqshrn)                 \
1841     V(uqshrn2,   Uqshrn2)                \
1842     V(urshr,     Urshr)                  \
1843     V(ursra,     Ursra)                  \
1844     V(ushll,     Ushll)                  \
1845     V(ushll2,    Ushll2)                 \
1846     V(ushr,      Ushr)                   \
1847     V(usra,      Usra)                   \
1848 
1849   #define DEFINE_MACRO_ASM_FUNC(ASM, MASM)   \
1850   void MASM(const VRegister& vd,             \
1851             const VRegister& vn,             \
1852             int shift) {                     \
1853     SingleEmissionCheckScope guard(this);    \
1854     ASM(vd, vn, shift);                      \
1855   }
1856   NEON_2VREG_SHIFT_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
1857   #undef DEFINE_MACRO_ASM_FUNC
1858 
1859   void Bic(const VRegister& vd,
1860            const int imm8,
1861            const int left_shift = 0) {
1862     SingleEmissionCheckScope guard(this);
1863     bic(vd, imm8, left_shift);
1864   }
Cmeq(const VRegister & vd,const VRegister & vn,int imm)1865   void Cmeq(const VRegister& vd,
1866             const VRegister& vn,
1867             int imm) {
1868     SingleEmissionCheckScope guard(this);
1869     cmeq(vd, vn, imm);
1870   }
Cmge(const VRegister & vd,const VRegister & vn,int imm)1871   void Cmge(const VRegister& vd,
1872             const VRegister& vn,
1873             int imm) {
1874     SingleEmissionCheckScope guard(this);
1875     cmge(vd, vn, imm);
1876   }
Cmgt(const VRegister & vd,const VRegister & vn,int imm)1877   void Cmgt(const VRegister& vd,
1878             const VRegister& vn,
1879             int imm) {
1880     SingleEmissionCheckScope guard(this);
1881     cmgt(vd, vn, imm);
1882   }
Cmle(const VRegister & vd,const VRegister & vn,int imm)1883   void Cmle(const VRegister& vd,
1884             const VRegister& vn,
1885             int imm) {
1886     SingleEmissionCheckScope guard(this);
1887     cmle(vd, vn, imm);
1888   }
Cmlt(const VRegister & vd,const VRegister & vn,int imm)1889   void Cmlt(const VRegister& vd,
1890             const VRegister& vn,
1891             int imm) {
1892     SingleEmissionCheckScope guard(this);
1893     cmlt(vd, vn, imm);
1894   }
Dup(const VRegister & vd,const VRegister & vn,int index)1895   void Dup(const VRegister& vd,
1896            const VRegister& vn,
1897            int index) {
1898     SingleEmissionCheckScope guard(this);
1899     dup(vd, vn, index);
1900   }
Dup(const VRegister & vd,const Register & rn)1901   void Dup(const VRegister& vd,
1902            const Register& rn) {
1903     SingleEmissionCheckScope guard(this);
1904     dup(vd, rn);
1905   }
Ext(const VRegister & vd,const VRegister & vn,const VRegister & vm,int index)1906   void Ext(const VRegister& vd,
1907            const VRegister& vn,
1908            const VRegister& vm,
1909            int index) {
1910     SingleEmissionCheckScope guard(this);
1911     ext(vd, vn, vm, index);
1912   }
Ins(const VRegister & vd,int vd_index,const VRegister & vn,int vn_index)1913   void Ins(const VRegister& vd,
1914            int vd_index,
1915            const VRegister& vn,
1916            int vn_index) {
1917     SingleEmissionCheckScope guard(this);
1918     ins(vd, vd_index, vn, vn_index);
1919   }
Ins(const VRegister & vd,int vd_index,const Register & rn)1920   void Ins(const VRegister& vd,
1921            int vd_index,
1922            const Register& rn) {
1923     SingleEmissionCheckScope guard(this);
1924     ins(vd, vd_index, rn);
1925   }
Ld1(const VRegister & vt,const MemOperand & src)1926   void Ld1(const VRegister& vt,
1927            const MemOperand& src) {
1928     SingleEmissionCheckScope guard(this);
1929     ld1(vt, src);
1930   }
Ld1(const VRegister & vt,const VRegister & vt2,const MemOperand & src)1931   void Ld1(const VRegister& vt,
1932            const VRegister& vt2,
1933            const MemOperand& src) {
1934     SingleEmissionCheckScope guard(this);
1935     ld1(vt, vt2, src);
1936   }
Ld1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & src)1937   void Ld1(const VRegister& vt,
1938            const VRegister& vt2,
1939            const VRegister& vt3,
1940            const MemOperand& src) {
1941     SingleEmissionCheckScope guard(this);
1942     ld1(vt, vt2, vt3, src);
1943   }
Ld1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & src)1944   void Ld1(const VRegister& vt,
1945            const VRegister& vt2,
1946            const VRegister& vt3,
1947            const VRegister& vt4,
1948            const MemOperand& src) {
1949     SingleEmissionCheckScope guard(this);
1950     ld1(vt, vt2, vt3, vt4, src);
1951   }
Ld1(const VRegister & vt,int lane,const MemOperand & src)1952   void Ld1(const VRegister& vt,
1953            int lane,
1954            const MemOperand& src) {
1955     SingleEmissionCheckScope guard(this);
1956     ld1(vt, lane, src);
1957   }
Ld1r(const VRegister & vt,const MemOperand & src)1958   void Ld1r(const VRegister& vt,
1959             const MemOperand& src) {
1960     SingleEmissionCheckScope guard(this);
1961     ld1r(vt, src);
1962   }
Ld2(const VRegister & vt,const VRegister & vt2,const MemOperand & src)1963   void Ld2(const VRegister& vt,
1964            const VRegister& vt2,
1965            const MemOperand& src) {
1966     SingleEmissionCheckScope guard(this);
1967     ld2(vt, vt2, src);
1968   }
Ld2(const VRegister & vt,const VRegister & vt2,int lane,const MemOperand & src)1969   void Ld2(const VRegister& vt,
1970            const VRegister& vt2,
1971            int lane,
1972            const MemOperand& src) {
1973     SingleEmissionCheckScope guard(this);
1974     ld2(vt, vt2, lane, src);
1975   }
Ld2r(const VRegister & vt,const VRegister & vt2,const MemOperand & src)1976   void Ld2r(const VRegister& vt,
1977             const VRegister& vt2,
1978             const MemOperand& src) {
1979     SingleEmissionCheckScope guard(this);
1980     ld2r(vt, vt2, src);
1981   }
Ld3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & src)1982   void Ld3(const VRegister& vt,
1983            const VRegister& vt2,
1984            const VRegister& vt3,
1985            const MemOperand& src) {
1986     SingleEmissionCheckScope guard(this);
1987     ld3(vt, vt2, vt3, src);
1988   }
Ld3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,int lane,const MemOperand & src)1989   void Ld3(const VRegister& vt,
1990            const VRegister& vt2,
1991            const VRegister& vt3,
1992            int lane,
1993            const MemOperand& src) {
1994     SingleEmissionCheckScope guard(this);
1995     ld3(vt, vt2, vt3, lane, src);
1996   }
Ld3r(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & src)1997   void Ld3r(const VRegister& vt,
1998             const VRegister& vt2,
1999             const VRegister& vt3,
2000            const MemOperand& src) {
2001     SingleEmissionCheckScope guard(this);
2002     ld3r(vt, vt2, vt3, src);
2003   }
Ld4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & src)2004   void Ld4(const VRegister& vt,
2005            const VRegister& vt2,
2006            const VRegister& vt3,
2007            const VRegister& vt4,
2008            const MemOperand& src) {
2009     SingleEmissionCheckScope guard(this);
2010     ld4(vt, vt2, vt3, vt4, src);
2011   }
Ld4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,int lane,const MemOperand & src)2012   void Ld4(const VRegister& vt,
2013            const VRegister& vt2,
2014            const VRegister& vt3,
2015            const VRegister& vt4,
2016            int lane,
2017            const MemOperand& src) {
2018     SingleEmissionCheckScope guard(this);
2019     ld4(vt, vt2, vt3, vt4, lane, src);
2020   }
Ld4r(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & src)2021   void Ld4r(const VRegister& vt,
2022             const VRegister& vt2,
2023             const VRegister& vt3,
2024             const VRegister& vt4,
2025            const MemOperand& src) {
2026     SingleEmissionCheckScope guard(this);
2027     ld4r(vt, vt2, vt3, vt4, src);
2028   }
Mov(const VRegister & vd,int vd_index,const VRegister & vn,int vn_index)2029   void Mov(const VRegister& vd,
2030            int vd_index,
2031            const VRegister& vn,
2032            int vn_index) {
2033     SingleEmissionCheckScope guard(this);
2034     mov(vd, vd_index, vn, vn_index);
2035   }
Mov(const VRegister & vd,const VRegister & vn,int index)2036   void Mov(const VRegister& vd,
2037            const VRegister& vn,
2038            int index) {
2039     SingleEmissionCheckScope guard(this);
2040     mov(vd, vn, index);
2041   }
Mov(const VRegister & vd,int vd_index,const Register & rn)2042   void Mov(const VRegister& vd,
2043            int vd_index,
2044            const Register& rn) {
2045     SingleEmissionCheckScope guard(this);
2046     mov(vd, vd_index, rn);
2047   }
Mov(const Register & rd,const VRegister & vn,int vn_index)2048   void Mov(const Register& rd,
2049            const VRegister& vn,
2050            int vn_index) {
2051     SingleEmissionCheckScope guard(this);
2052     mov(rd, vn, vn_index);
2053   }
2054   void Movi(const VRegister& vd,
2055             uint64_t imm,
2056             Shift shift = LSL,
2057             int shift_amount = 0);
2058   void Movi(const VRegister& vd, uint64_t hi, uint64_t lo);
2059   void Mvni(const VRegister& vd,
2060             const int imm8,
2061             Shift shift = LSL,
2062             const int shift_amount = 0) {
2063     SingleEmissionCheckScope guard(this);
2064     mvni(vd, imm8, shift, shift_amount);
2065   }
2066   void Orr(const VRegister& vd,
2067            const int imm8,
2068            const int left_shift = 0) {
2069     SingleEmissionCheckScope guard(this);
2070     orr(vd, imm8, left_shift);
2071   }
2072   void Scvtf(const VRegister& vd,
2073              const VRegister& vn,
2074              int fbits = 0) {
2075     SingleEmissionCheckScope guard(this);
2076     scvtf(vd, vn, fbits);
2077   }
2078   void Ucvtf(const VRegister& vd,
2079              const VRegister& vn,
2080              int fbits = 0) {
2081     SingleEmissionCheckScope guard(this);
2082     ucvtf(vd, vn, fbits);
2083   }
2084   void Fcvtzs(const VRegister& vd,
2085               const VRegister& vn,
2086               int fbits = 0) {
2087     SingleEmissionCheckScope guard(this);
2088     fcvtzs(vd, vn, fbits);
2089   }
2090   void Fcvtzu(const VRegister& vd,
2091               const VRegister& vn,
2092               int fbits = 0) {
2093     SingleEmissionCheckScope guard(this);
2094     fcvtzu(vd, vn, fbits);
2095   }
St1(const VRegister & vt,const MemOperand & dst)2096   void St1(const VRegister& vt,
2097            const MemOperand& dst) {
2098     SingleEmissionCheckScope guard(this);
2099     st1(vt, dst);
2100   }
St1(const VRegister & vt,const VRegister & vt2,const MemOperand & dst)2101   void St1(const VRegister& vt,
2102            const VRegister& vt2,
2103            const MemOperand& dst) {
2104     SingleEmissionCheckScope guard(this);
2105     st1(vt, vt2, dst);
2106   }
St1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & dst)2107   void St1(const VRegister& vt,
2108            const VRegister& vt2,
2109            const VRegister& vt3,
2110            const MemOperand& dst) {
2111     SingleEmissionCheckScope guard(this);
2112     st1(vt, vt2, vt3, dst);
2113   }
St1(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & dst)2114   void St1(const VRegister& vt,
2115            const VRegister& vt2,
2116            const VRegister& vt3,
2117            const VRegister& vt4,
2118            const MemOperand& dst) {
2119     SingleEmissionCheckScope guard(this);
2120     st1(vt, vt2, vt3, vt4, dst);
2121   }
St1(const VRegister & vt,int lane,const MemOperand & dst)2122   void St1(const VRegister& vt,
2123            int lane,
2124            const MemOperand& dst) {
2125     SingleEmissionCheckScope guard(this);
2126     st1(vt, lane, dst);
2127   }
St2(const VRegister & vt,const VRegister & vt2,const MemOperand & dst)2128   void St2(const VRegister& vt,
2129            const VRegister& vt2,
2130            const MemOperand& dst) {
2131     SingleEmissionCheckScope guard(this);
2132     st2(vt, vt2, dst);
2133   }
St3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const MemOperand & dst)2134   void St3(const VRegister& vt,
2135            const VRegister& vt2,
2136            const VRegister& vt3,
2137            const MemOperand& dst) {
2138     SingleEmissionCheckScope guard(this);
2139     st3(vt, vt2, vt3, dst);
2140   }
St4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,const MemOperand & dst)2141   void St4(const VRegister& vt,
2142            const VRegister& vt2,
2143            const VRegister& vt3,
2144            const VRegister& vt4,
2145            const MemOperand& dst) {
2146     SingleEmissionCheckScope guard(this);
2147     st4(vt, vt2, vt3, vt4, dst);
2148   }
St2(const VRegister & vt,const VRegister & vt2,int lane,const MemOperand & dst)2149   void St2(const VRegister& vt,
2150            const VRegister& vt2,
2151            int lane,
2152            const MemOperand& dst) {
2153     SingleEmissionCheckScope guard(this);
2154     st2(vt, vt2, lane, dst);
2155   }
St3(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,int lane,const MemOperand & dst)2156   void St3(const VRegister& vt,
2157            const VRegister& vt2,
2158            const VRegister& vt3,
2159            int lane,
2160            const MemOperand& dst) {
2161     SingleEmissionCheckScope guard(this);
2162     st3(vt, vt2, vt3, lane, dst);
2163   }
St4(const VRegister & vt,const VRegister & vt2,const VRegister & vt3,const VRegister & vt4,int lane,const MemOperand & dst)2164   void St4(const VRegister& vt,
2165            const VRegister& vt2,
2166            const VRegister& vt3,
2167            const VRegister& vt4,
2168            int lane,
2169            const MemOperand& dst) {
2170     SingleEmissionCheckScope guard(this);
2171     st4(vt, vt2, vt3, vt4, lane, dst);
2172   }
Smov(const Register & rd,const VRegister & vn,int vn_index)2173   void Smov(const Register& rd,
2174             const VRegister& vn,
2175             int vn_index) {
2176     SingleEmissionCheckScope guard(this);
2177     smov(rd, vn, vn_index);
2178   }
Umov(const Register & rd,const VRegister & vn,int vn_index)2179   void Umov(const Register& rd,
2180             const VRegister& vn,
2181             int vn_index) {
2182     SingleEmissionCheckScope guard(this);
2183     umov(rd, vn, vn_index);
2184   }
Crc32b(const Register & rd,const Register & rn,const Register & rm)2185   void Crc32b(const Register& rd,
2186               const Register& rn,
2187               const Register& rm) {
2188     SingleEmissionCheckScope guard(this);
2189     crc32b(rd, rn, rm);
2190   }
Crc32h(const Register & rd,const Register & rn,const Register & rm)2191   void Crc32h(const Register& rd,
2192               const Register& rn,
2193               const Register& rm) {
2194     SingleEmissionCheckScope guard(this);
2195     crc32h(rd, rn, rm);
2196   }
Crc32w(const Register & rd,const Register & rn,const Register & rm)2197   void Crc32w(const Register& rd,
2198               const Register& rn,
2199               const Register& rm) {
2200     SingleEmissionCheckScope guard(this);
2201     crc32w(rd, rn, rm);
2202   }
Crc32x(const Register & rd,const Register & rn,const Register & rm)2203   void Crc32x(const Register& rd,
2204               const Register& rn,
2205               const Register& rm) {
2206     SingleEmissionCheckScope guard(this);
2207     crc32x(rd, rn, rm);
2208   }
Crc32cb(const Register & rd,const Register & rn,const Register & rm)2209   void Crc32cb(const Register& rd,
2210                const Register& rn,
2211                const Register& rm) {
2212     SingleEmissionCheckScope guard(this);
2213     crc32cb(rd, rn, rm);
2214   }
Crc32ch(const Register & rd,const Register & rn,const Register & rm)2215   void Crc32ch(const Register& rd,
2216                const Register& rn,
2217                const Register& rm) {
2218     SingleEmissionCheckScope guard(this);
2219     crc32ch(rd, rn, rm);
2220   }
Crc32cw(const Register & rd,const Register & rn,const Register & rm)2221   void Crc32cw(const Register& rd,
2222                const Register& rn,
2223                const Register& rm) {
2224     SingleEmissionCheckScope guard(this);
2225     crc32cw(rd, rn, rm);
2226   }
Crc32cx(const Register & rd,const Register & rn,const Register & rm)2227   void Crc32cx(const Register& rd,
2228                const Register& rn,
2229                const Register& rm) {
2230     SingleEmissionCheckScope guard(this);
2231     crc32cx(rd, rn, rm);
2232   }
2233 
2234   // Push the system stack pointer (sp) down to allow the same to be done to
2235   // the current stack pointer (according to StackPointer()). This must be
2236   // called _before_ accessing the memory.
2237   //
2238   // This is necessary when pushing or otherwise adding things to the stack, to
2239   // satisfy the AAPCS64 constraint that the memory below the system stack
2240   // pointer is not accessed.
2241   //
2242   // This method asserts that StackPointer() is not sp, since the call does
2243   // not make sense in that context.
2244   //
2245   // TODO: This method can only accept values of 'space' that can be encoded in
2246   // one instruction. Refer to the implementation for details.
2247   void BumpSystemStackPointer(const Operand& space);
2248 
2249   // Set the current stack pointer, but don't generate any code.
SetStackPointer64(const Register & stack_pointer)2250   void SetStackPointer64(const Register& stack_pointer) {
2251     VIXL_ASSERT(!TmpList()->IncludesAliasOf(stack_pointer));
2252     sp_ = stack_pointer;
2253   }
2254 
2255   // Return the current stack pointer, as set by SetStackPointer.
StackPointer()2256   const Register& StackPointer() const {
2257     return sp_;
2258   }
2259 
GetStackPointer64()2260   const Register& GetStackPointer64() const {
2261     return sp_;
2262   }
2263 
getStackPointer()2264   const js::jit::RegisterOrSP getStackPointer() const {
2265       return js::jit::RegisterOrSP(sp_.code());
2266   }
2267 
TmpList()2268   CPURegList* TmpList() { return &tmp_list_; }
FPTmpList()2269   CPURegList* FPTmpList() { return &fptmp_list_; }
2270 
2271   // Trace control when running the debug simulator.
2272   //
2273   // For example:
2274   //
2275   // __ Trace(LOG_REGS, TRACE_ENABLE);
2276   // Will add registers to the trace if it wasn't already the case.
2277   //
2278   // __ Trace(LOG_DISASM, TRACE_DISABLE);
2279   // Will stop logging disassembly. It has no effect if the disassembly wasn't
2280   // already being logged.
2281   void Trace(TraceParameters parameters, TraceCommand command);
2282 
2283   // Log the requested data independently of what is being traced.
2284   //
2285   // For example:
2286   //
2287   // __ Log(LOG_FLAGS)
2288   // Will output the flags.
2289   void Log(TraceParameters parameters);
2290 
2291   // Enable or disable instrumentation when an Instrument visitor is attached to
2292   // the simulator.
2293   void EnableInstrumentation();
2294   void DisableInstrumentation();
2295 
2296   // Add a marker to the instrumentation data produced by an Instrument visitor.
2297   // The name is a two character string that will be attached to the marker in
2298   // the output data.
2299   void AnnotateInstrumentation(const char* marker_name);
2300 
2301  private:
2302   // The actual Push and Pop implementations. These don't generate any code
2303   // other than that required for the push or pop. This allows
2304   // (Push|Pop)CPURegList to bundle together setup code for a large block of
2305   // registers.
2306   //
2307   // Note that size is per register, and is specified in bytes.
2308   void PushHelper(int count, int size,
2309                   const CPURegister& src0, const CPURegister& src1,
2310                   const CPURegister& src2, const CPURegister& src3);
2311   void PopHelper(int count, int size,
2312                  const CPURegister& dst0, const CPURegister& dst1,
2313                  const CPURegister& dst2, const CPURegister& dst3);
2314 
2315   void Movi16bitHelper(const VRegister& vd, uint64_t imm);
2316   void Movi32bitHelper(const VRegister& vd, uint64_t imm);
2317   void Movi64bitHelper(const VRegister& vd, uint64_t imm);
2318 
2319   // Perform necessary maintenance operations before a push or pop.
2320   //
2321   // Note that size is per register, and is specified in bytes.
2322   void PrepareForPush(int count, int size);
2323   void PrepareForPop(int count, int size);
2324 
2325   // The actual implementation of load and store operations for CPURegList.
2326   enum LoadStoreCPURegListAction {
2327     kLoad,
2328     kStore
2329   };
2330   void LoadStoreCPURegListHelper(LoadStoreCPURegListAction operation,
2331                                  CPURegList registers,
2332                                  const MemOperand& mem);
2333   // Returns a MemOperand suitable for loading or storing a CPURegList at `dst`.
2334   // This helper may allocate registers from `scratch_scope` and generate code
2335   // to compute an intermediate address. The resulting MemOperand is only valid
2336   // as long as `scratch_scope` remains valid.
2337   MemOperand BaseMemOperandForLoadStoreCPURegList(
2338       const CPURegList& registers,
2339       const MemOperand& mem,
2340       UseScratchRegisterScope* scratch_scope);
2341 
LabelIsOutOfRange(Label * label,ImmBranchType branch_type)2342   bool LabelIsOutOfRange(Label* label, ImmBranchType branch_type) {
2343     return !Instruction::IsValidImmPCOffset(branch_type, nextOffset().getOffset() - label->offset());
2344   }
2345 
2346   // The register to use as a stack pointer for stack operations.
2347   Register sp_;
2348 
2349   // Scratch registers available for use by the MacroAssembler.
2350   CPURegList tmp_list_;
2351   CPURegList fptmp_list_;
2352 
2353   ptrdiff_t checkpoint_;
2354   ptrdiff_t recommended_checkpoint_;
2355 };
2356 
2357 
2358 // All Assembler emits MUST acquire/release the underlying code buffer. The
2359 // helper scope below will do so and optionally ensure the buffer is big enough
2360 // to receive the emit. It is possible to request the scope not to perform any
2361 // checks (kNoCheck) if for example it is known in advance the buffer size is
2362 // adequate or there is some other size checking mechanism in place.
2363 class CodeBufferCheckScope {
2364  public:
2365   // Tell whether or not the scope needs to ensure the associated CodeBuffer
2366   // has enough space for the requested size.
2367   enum CheckPolicy {
2368     kNoCheck,
2369     kCheck
2370   };
2371 
2372   // Tell whether or not the scope should assert the amount of code emitted
2373   // within the scope is consistent with the requested amount.
2374   enum AssertPolicy {
2375     kNoAssert,    // No assert required.
2376     kExactSize,   // The code emitted must be exactly size bytes.
2377     kMaximumSize  // The code emitted must be at most size bytes.
2378   };
2379 
2380   CodeBufferCheckScope(Assembler* assm,
2381                        size_t size,
2382                        CheckPolicy check_policy = kCheck,
2383                        AssertPolicy assert_policy = kMaximumSize)
2384   { }
2385 
2386   // This is a shortcut for CodeBufferCheckScope(assm, 0, kNoCheck, kNoAssert).
CodeBufferCheckScope(Assembler * assm)2387   explicit CodeBufferCheckScope(Assembler* assm) {}
2388 };
2389 
2390 
2391 // Use this scope when you need a one-to-one mapping between methods and
2392 // instructions. This scope prevents the MacroAssembler from being called and
2393 // literal pools from being emitted. It also asserts the number of instructions
2394 // emitted is what you specified when creating the scope.
2395 // FIXME: Because of the disabled calls below, this class asserts nothing.
2396 class InstructionAccurateScope : public CodeBufferCheckScope {
2397  public:
2398   InstructionAccurateScope(MacroAssembler* masm,
2399                            int64_t count,
2400                            AssertPolicy policy = kExactSize)
2401       : CodeBufferCheckScope(masm,
2402                              (count * kInstructionSize),
2403                              kCheck,
2404                              policy) {
2405   }
2406 };
2407 
2408 
2409 // This scope utility allows scratch registers to be managed safely. The
2410 // MacroAssembler's TmpList() (and FPTmpList()) is used as a pool of scratch
2411 // registers. These registers can be allocated on demand, and will be returned
2412 // at the end of the scope.
2413 //
2414 // When the scope ends, the MacroAssembler's lists will be restored to their
2415 // original state, even if the lists were modified by some other means.
2416 class UseScratchRegisterScope {
2417  public:
2418   // This constructor implicitly calls the `Open` function to initialise the
2419   // scope, so it is ready to use immediately after it has been constructed.
2420   explicit UseScratchRegisterScope(MacroAssembler* masm);
2421   // This constructor allows deferred and optional initialisation of the scope.
2422   // The user is required to explicitly call the `Open` function before using
2423   // the scope.
2424   UseScratchRegisterScope();
2425   // This function performs the actual initialisation work.
2426   void Open(MacroAssembler* masm);
2427 
2428   // The destructor always implicitly calls the `Close` function.
2429   ~UseScratchRegisterScope();
2430   // This function performs the cleaning-up work. It must succeed even if the
2431   // scope has not been opened. It is safe to call multiple times.
2432   void Close();
2433 
2434 
2435   bool IsAvailable(const CPURegister& reg) const;
2436 
2437 
2438   // Take a register from the appropriate temps list. It will be returned
2439   // automatically when the scope ends.
AcquireW()2440   Register AcquireW() { return AcquireNextAvailable(available_).W(); }
AcquireX()2441   Register AcquireX() { return AcquireNextAvailable(available_).X(); }
AcquireS()2442   VRegister AcquireS() { return AcquireNextAvailable(availablefp_).S(); }
AcquireD()2443   VRegister AcquireD() { return AcquireNextAvailable(availablefp_).D(); }
2444 
2445 
2446   Register AcquireSameSizeAs(const Register& reg);
2447   VRegister AcquireSameSizeAs(const VRegister& reg);
2448 
2449 
2450   // Explicitly release an acquired (or excluded) register, putting it back in
2451   // the appropriate temps list.
2452   void Release(const CPURegister& reg);
2453 
2454 
2455   // Make the specified registers available as scratch registers for the
2456   // duration of this scope.
2457   void Include(const CPURegList& list);
2458   void Include(const Register& reg1,
2459                const Register& reg2 = NoReg,
2460                const Register& reg3 = NoReg,
2461                const Register& reg4 = NoReg);
2462   void Include(const VRegister& reg1,
2463                const VRegister& reg2 = NoVReg,
2464                const VRegister& reg3 = NoVReg,
2465                const VRegister& reg4 = NoVReg);
2466 
2467 
2468   // Make sure that the specified registers are not available in this scope.
2469   // This can be used to prevent helper functions from using sensitive
2470   // registers, for example.
2471   void Exclude(const CPURegList& list);
2472   void Exclude(const Register& reg1,
2473                const Register& reg2 = NoReg,
2474                const Register& reg3 = NoReg,
2475                const Register& reg4 = NoReg);
2476   void Exclude(const VRegister& reg1,
2477                const VRegister& reg2 = NoVReg,
2478                const VRegister& reg3 = NoVReg,
2479                const VRegister& reg4 = NoVReg);
2480   void Exclude(const CPURegister& reg1,
2481                const CPURegister& reg2 = NoCPUReg,
2482                const CPURegister& reg3 = NoCPUReg,
2483                const CPURegister& reg4 = NoCPUReg);
2484 
2485 
2486   // Prevent any scratch registers from being used in this scope.
2487   void ExcludeAll();
2488 
2489 
2490  private:
2491   static CPURegister AcquireNextAvailable(CPURegList* available);
2492 
2493   static void ReleaseByCode(CPURegList* available, int code);
2494 
2495   static void ReleaseByRegList(CPURegList* available,
2496                                RegList regs);
2497 
2498   static void IncludeByRegList(CPURegList* available,
2499                                RegList exclude);
2500 
2501   static void ExcludeByRegList(CPURegList* available,
2502                                RegList exclude);
2503 
2504   // Available scratch registers.
2505   CPURegList* available_;     // kRegister
2506   CPURegList* availablefp_;   // kVRegister
2507 
2508   // The state of the available lists at the start of this scope.
2509   RegList old_available_;     // kRegister
2510   RegList old_availablefp_;   // kVRegister
2511 #ifdef DEBUG
2512   bool initialised_;
2513 #endif
2514 
2515   // Disallow copy constructor and operator=.
UseScratchRegisterScope(const UseScratchRegisterScope &)2516   UseScratchRegisterScope(const UseScratchRegisterScope&) {
2517     VIXL_UNREACHABLE();
2518   }
2519   void operator=(const UseScratchRegisterScope&) {
2520     VIXL_UNREACHABLE();
2521   }
2522 };
2523 
2524 
2525 }  // namespace vixl
2526 
2527 #endif  // VIXL_A64_MACRO_ASSEMBLER_A64_H_
2528