1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_
6 #define V8_ARM64_ASSEMBLER_ARM64_H_
7 
8 #include <deque>
9 #include <list>
10 #include <map>
11 #include <vector>
12 
13 #include "src/arm64/instructions-arm64.h"
14 #include "src/assembler.h"
15 #include "src/globals.h"
16 #include "src/utils.h"
17 
18 
19 namespace v8 {
20 namespace internal {
21 
22 
23 // -----------------------------------------------------------------------------
24 // Registers.
25 // clang-format off
26 #define GENERAL_REGISTER_CODE_LIST(R)                     \
27   R(0)  R(1)  R(2)  R(3)  R(4)  R(5)  R(6)  R(7)          \
28   R(8)  R(9)  R(10) R(11) R(12) R(13) R(14) R(15)         \
29   R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23)         \
30   R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
31 
32 #define GENERAL_REGISTERS(R)                              \
33   R(x0)  R(x1)  R(x2)  R(x3)  R(x4)  R(x5)  R(x6)  R(x7)  \
34   R(x8)  R(x9)  R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \
35   R(x16) R(x17) R(x18) R(x19) R(x20) R(x21) R(x22) R(x23) \
36   R(x24) R(x25) R(x26) R(x27) R(x28) R(x29) R(x30) R(x31)
37 
38 #define ALLOCATABLE_GENERAL_REGISTERS(R)                  \
39   R(x0)  R(x1)  R(x2)  R(x3)  R(x4)  R(x5)  R(x6)  R(x7)  \
40   R(x8)  R(x9)  R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \
41   R(x18) R(x19) R(x20) R(x21) R(x22) R(x23) R(x24) R(x27)
42 
43 #define DOUBLE_REGISTERS(R)                               \
44   R(d0)  R(d1)  R(d2)  R(d3)  R(d4)  R(d5)  R(d6)  R(d7)  \
45   R(d8)  R(d9)  R(d10) R(d11) R(d12) R(d13) R(d14) R(d15) \
46   R(d16) R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) \
47   R(d24) R(d25) R(d26) R(d27) R(d28) R(d29) R(d30) R(d31)
48 
49 #define ALLOCATABLE_DOUBLE_REGISTERS(R)                   \
50   R(d0)  R(d1)  R(d2)  R(d3)  R(d4)  R(d5)  R(d6)  R(d7)  \
51   R(d8)  R(d9)  R(d10) R(d11) R(d12) R(d13) R(d14) R(d16) \
52   R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) R(d24) \
53   R(d25) R(d26) R(d27) R(d28)
54 // clang-format on
55 
56 static const int kRegListSizeInBits = sizeof(RegList) * kBitsPerByte;
57 
58 
59 // Some CPURegister methods can return Register and FPRegister types, so we
60 // need to declare them in advance.
61 struct Register;
62 struct FPRegister;
63 
64 
65 struct CPURegister {
66   enum Code {
67 #define REGISTER_CODE(R) kCode_##R,
68     GENERAL_REGISTERS(REGISTER_CODE)
69 #undef REGISTER_CODE
70         kAfterLast,
71     kCode_no_reg = -1
72   };
73 
74   enum RegisterType {
75     // The kInvalid value is used to detect uninitialized static instances,
76     // which are always zero-initialized before any constructors are called.
77     kInvalid = 0,
78     kRegister,
79     kFPRegister,
80     kNoRegister
81   };
82 
CreateCPURegister83   static CPURegister Create(int code, int size, RegisterType type) {
84     CPURegister r = {code, size, type};
85     return r;
86   }
87 
88   int code() const;
89   RegisterType type() const;
90   RegList Bit() const;
91   int SizeInBits() const;
92   int SizeInBytes() const;
93   bool Is32Bits() const;
94   bool Is64Bits() const;
95   bool IsValid() const;
96   bool IsValidOrNone() const;
97   bool IsValidRegister() const;
98   bool IsValidFPRegister() const;
99   bool IsNone() const;
100   bool Is(const CPURegister& other) const;
101   bool Aliases(const CPURegister& other) const;
102 
103   bool IsZero() const;
104   bool IsSP() const;
105 
106   bool IsRegister() const;
107   bool IsFPRegister() const;
108 
109   Register X() const;
110   Register W() const;
111   FPRegister D() const;
112   FPRegister S() const;
113 
114   bool IsSameSizeAndType(const CPURegister& other) const;
115 
116   // V8 compatibility.
isCPURegister117   bool is(const CPURegister& other) const { return Is(other); }
is_validCPURegister118   bool is_valid() const { return IsValid(); }
119 
120   int reg_code;
121   int reg_size;
122   RegisterType reg_type;
123 };
124 
125 
126 struct Register : public CPURegister {
CreateRegister127   static Register Create(int code, int size) {
128     return Register(CPURegister::Create(code, size, CPURegister::kRegister));
129   }
130 
RegisterRegister131   Register() {
132     reg_code = 0;
133     reg_size = 0;
134     reg_type = CPURegister::kNoRegister;
135   }
136 
RegisterRegister137   explicit Register(const CPURegister& r) {
138     reg_code = r.reg_code;
139     reg_size = r.reg_size;
140     reg_type = r.reg_type;
141     DCHECK(IsValidOrNone());
142   }
143 
RegisterRegister144   Register(const Register& r) {  // NOLINT(runtime/explicit)
145     reg_code = r.reg_code;
146     reg_size = r.reg_size;
147     reg_type = r.reg_type;
148     DCHECK(IsValidOrNone());
149   }
150 
151   const char* ToString();
152   bool IsAllocatable() const;
IsValidRegister153   bool IsValid() const {
154     DCHECK(IsRegister() || IsNone());
155     return IsValidRegister();
156   }
157 
158   static Register XRegFromCode(unsigned code);
159   static Register WRegFromCode(unsigned code);
160 
161   // Start of V8 compatibility section ---------------------
162   // These memebers are necessary for compilation.
163   // A few of them may be unused for now.
164 
165   static const int kNumRegisters = kNumberOfRegisters;
166   STATIC_ASSERT(kNumRegisters == Code::kAfterLast);
NumRegistersRegister167   static int NumRegisters() { return kNumRegisters; }
168 
169   // We allow crankshaft to use the following registers:
170   //   - x0 to x15
171   //   - x18 to x24
172   //   - x27 (also context)
173   //
174   // TODO(all): Register x25 is currently free and could be available for
175   // crankshaft, but we don't use it as we might use it as a per function
176   // literal pool pointer in the future.
177   //
178   // TODO(all): Consider storing cp in x25 to have only two ranges.
179   // We split allocatable registers in three ranges called
180   //   - "low range"
181   //   - "high range"
182   //   - "context"
183 
from_codeRegister184   static Register from_code(int code) {
185     // Always return an X register.
186     return Register::Create(code, kXRegSizeInBits);
187   }
188 
189   // End of V8 compatibility section -----------------------
190 };
191 
192 
193 struct FPRegister : public CPURegister {
194   enum Code {
195 #define REGISTER_CODE(R) kCode_##R,
196     DOUBLE_REGISTERS(REGISTER_CODE)
197 #undef REGISTER_CODE
198         kAfterLast,
199     kCode_no_reg = -1
200   };
201 
CreateFPRegister202   static FPRegister Create(int code, int size) {
203     return FPRegister(
204         CPURegister::Create(code, size, CPURegister::kFPRegister));
205   }
206 
FPRegisterFPRegister207   FPRegister() {
208     reg_code = 0;
209     reg_size = 0;
210     reg_type = CPURegister::kNoRegister;
211   }
212 
FPRegisterFPRegister213   explicit FPRegister(const CPURegister& r) {
214     reg_code = r.reg_code;
215     reg_size = r.reg_size;
216     reg_type = r.reg_type;
217     DCHECK(IsValidOrNone());
218   }
219 
FPRegisterFPRegister220   FPRegister(const FPRegister& r) {  // NOLINT(runtime/explicit)
221     reg_code = r.reg_code;
222     reg_size = r.reg_size;
223     reg_type = r.reg_type;
224     DCHECK(IsValidOrNone());
225   }
226 
227   const char* ToString();
228   bool IsAllocatable() const;
IsValidFPRegister229   bool IsValid() const {
230     DCHECK(IsFPRegister() || IsNone());
231     return IsValidFPRegister();
232   }
233 
234   static FPRegister SRegFromCode(unsigned code);
235   static FPRegister DRegFromCode(unsigned code);
236 
237   // Start of V8 compatibility section ---------------------
238   static const int kMaxNumRegisters = kNumberOfFPRegisters;
239   STATIC_ASSERT(kMaxNumRegisters == Code::kAfterLast);
240 
241   // Crankshaft can use all the FP registers except:
242   //   - d15 which is used to keep the 0 double value
243   //   - d30 which is used in crankshaft as a double scratch register
244   //   - d31 which is used in the MacroAssembler as a double scratch register
from_codeFPRegister245   static FPRegister from_code(int code) {
246     // Always return a D register.
247     return FPRegister::Create(code, kDRegSizeInBits);
248   }
249   // End of V8 compatibility section -----------------------
250 };
251 
252 
253 STATIC_ASSERT(sizeof(CPURegister) == sizeof(Register));
254 STATIC_ASSERT(sizeof(CPURegister) == sizeof(FPRegister));
255 
256 
257 #if defined(ARM64_DEFINE_REG_STATICS)
258 #define INITIALIZE_REGISTER(register_class, name, code, size, type)      \
259   const CPURegister init_##register_class##_##name = {code, size, type}; \
260   const register_class& name = *reinterpret_cast<const register_class*>( \
261                                     &init_##register_class##_##name)
262 #define ALIAS_REGISTER(register_class, alias, name)                       \
263   const register_class& alias = *reinterpret_cast<const register_class*>( \
264                                      &init_##register_class##_##name)
265 #else
266 #define INITIALIZE_REGISTER(register_class, name, code, size, type) \
267   extern const register_class& name
268 #define ALIAS_REGISTER(register_class, alias, name) \
269   extern const register_class& alias
270 #endif  // defined(ARM64_DEFINE_REG_STATICS)
271 
272 // No*Reg is used to indicate an unused argument, or an error case. Note that
273 // these all compare equal (using the Is() method). The Register and FPRegister
274 // variants are provided for convenience.
275 INITIALIZE_REGISTER(Register, NoReg, 0, 0, CPURegister::kNoRegister);
276 INITIALIZE_REGISTER(FPRegister, NoFPReg, 0, 0, CPURegister::kNoRegister);
277 INITIALIZE_REGISTER(CPURegister, NoCPUReg, 0, 0, CPURegister::kNoRegister);
278 
279 // v8 compatibility.
280 INITIALIZE_REGISTER(Register, no_reg, 0, 0, CPURegister::kNoRegister);
281 
282 #define DEFINE_REGISTERS(N)                                                  \
283   INITIALIZE_REGISTER(Register, w##N, N,                                     \
284                       kWRegSizeInBits, CPURegister::kRegister);              \
285   INITIALIZE_REGISTER(Register, x##N, N,                                     \
286                       kXRegSizeInBits, CPURegister::kRegister);
287 GENERAL_REGISTER_CODE_LIST(DEFINE_REGISTERS)
288 #undef DEFINE_REGISTERS
289 
290 INITIALIZE_REGISTER(Register, wcsp, kSPRegInternalCode, kWRegSizeInBits,
291                     CPURegister::kRegister);
292 INITIALIZE_REGISTER(Register, csp, kSPRegInternalCode, kXRegSizeInBits,
293                     CPURegister::kRegister);
294 
295 #define DEFINE_FPREGISTERS(N)                                                  \
296   INITIALIZE_REGISTER(FPRegister, s##N, N,                                     \
297                       kSRegSizeInBits, CPURegister::kFPRegister);              \
298   INITIALIZE_REGISTER(FPRegister, d##N, N,                                     \
299                       kDRegSizeInBits, CPURegister::kFPRegister);
300 GENERAL_REGISTER_CODE_LIST(DEFINE_FPREGISTERS)
301 #undef DEFINE_FPREGISTERS
302 
303 #undef INITIALIZE_REGISTER
304 
305 // Registers aliases.
306 ALIAS_REGISTER(Register, ip0, x16);
307 ALIAS_REGISTER(Register, ip1, x17);
308 ALIAS_REGISTER(Register, wip0, w16);
309 ALIAS_REGISTER(Register, wip1, w17);
310 // Root register.
311 ALIAS_REGISTER(Register, root, x26);
312 ALIAS_REGISTER(Register, rr, x26);
313 // Context pointer register.
314 ALIAS_REGISTER(Register, cp, x27);
315 // We use a register as a JS stack pointer to overcome the restriction on the
316 // architectural SP alignment.
317 // We chose x28 because it is contiguous with the other specific purpose
318 // registers.
319 STATIC_ASSERT(kJSSPCode == 28);
320 ALIAS_REGISTER(Register, jssp, x28);
321 ALIAS_REGISTER(Register, wjssp, w28);
322 ALIAS_REGISTER(Register, fp, x29);
323 ALIAS_REGISTER(Register, lr, x30);
324 ALIAS_REGISTER(Register, xzr, x31);
325 ALIAS_REGISTER(Register, wzr, w31);
326 
327 // Keeps the 0 double value.
328 ALIAS_REGISTER(FPRegister, fp_zero, d15);
329 // Crankshaft double scratch register.
330 ALIAS_REGISTER(FPRegister, crankshaft_fp_scratch, d29);
331 // MacroAssembler double scratch registers.
332 ALIAS_REGISTER(FPRegister, fp_scratch, d30);
333 ALIAS_REGISTER(FPRegister, fp_scratch1, d30);
334 ALIAS_REGISTER(FPRegister, fp_scratch2, d31);
335 
336 #undef ALIAS_REGISTER
337 
338 
339 Register GetAllocatableRegisterThatIsNotOneOf(Register reg1,
340                                               Register reg2 = NoReg,
341                                               Register reg3 = NoReg,
342                                               Register reg4 = NoReg);
343 
344 
345 // AreAliased returns true if any of the named registers overlap. Arguments set
346 // to NoReg are ignored. The system stack pointer may be specified.
347 bool AreAliased(const CPURegister& reg1,
348                 const CPURegister& reg2,
349                 const CPURegister& reg3 = NoReg,
350                 const CPURegister& reg4 = NoReg,
351                 const CPURegister& reg5 = NoReg,
352                 const CPURegister& reg6 = NoReg,
353                 const CPURegister& reg7 = NoReg,
354                 const CPURegister& reg8 = NoReg);
355 
356 // AreSameSizeAndType returns true if all of the specified registers have the
357 // same size, and are of the same type. The system stack pointer may be
358 // specified. Arguments set to NoReg are ignored, as are any subsequent
359 // arguments. At least one argument (reg1) must be valid (not NoCPUReg).
360 bool AreSameSizeAndType(const CPURegister& reg1,
361                         const CPURegister& reg2,
362                         const CPURegister& reg3 = NoCPUReg,
363                         const CPURegister& reg4 = NoCPUReg,
364                         const CPURegister& reg5 = NoCPUReg,
365                         const CPURegister& reg6 = NoCPUReg,
366                         const CPURegister& reg7 = NoCPUReg,
367                         const CPURegister& reg8 = NoCPUReg);
368 
369 
370 typedef FPRegister DoubleRegister;
371 
372 
373 // -----------------------------------------------------------------------------
374 // Lists of registers.
375 class CPURegList {
376  public:
377   explicit CPURegList(CPURegister reg1,
378                       CPURegister reg2 = NoCPUReg,
379                       CPURegister reg3 = NoCPUReg,
380                       CPURegister reg4 = NoCPUReg)
381       : list_(reg1.Bit() | reg2.Bit() | reg3.Bit() | reg4.Bit()),
382         size_(reg1.SizeInBits()), type_(reg1.type()) {
383     DCHECK(AreSameSizeAndType(reg1, reg2, reg3, reg4));
384     DCHECK(IsValid());
385   }
386 
CPURegList(CPURegister::RegisterType type,int size,RegList list)387   CPURegList(CPURegister::RegisterType type, int size, RegList list)
388       : list_(list), size_(size), type_(type) {
389     DCHECK(IsValid());
390   }
391 
CPURegList(CPURegister::RegisterType type,int size,int first_reg,int last_reg)392   CPURegList(CPURegister::RegisterType type, int size, int first_reg,
393              int last_reg)
394       : size_(size), type_(type) {
395     DCHECK(((type == CPURegister::kRegister) &&
396             (last_reg < kNumberOfRegisters)) ||
397            ((type == CPURegister::kFPRegister) &&
398             (last_reg < kNumberOfFPRegisters)));
399     DCHECK(last_reg >= first_reg);
400     list_ = (1UL << (last_reg + 1)) - 1;
401     list_ &= ~((1UL << first_reg) - 1);
402     DCHECK(IsValid());
403   }
404 
type()405   CPURegister::RegisterType type() const {
406     DCHECK(IsValid());
407     return type_;
408   }
409 
list()410   RegList list() const {
411     DCHECK(IsValid());
412     return list_;
413   }
414 
set_list(RegList new_list)415   inline void set_list(RegList new_list) {
416     DCHECK(IsValid());
417     list_ = new_list;
418   }
419 
420   // Combine another CPURegList into this one. Registers that already exist in
421   // this list are left unchanged. The type and size of the registers in the
422   // 'other' list must match those in this list.
423   void Combine(const CPURegList& other);
424 
425   // Remove every register in the other CPURegList from this one. Registers that
426   // do not exist in this list are ignored. The type of the registers in the
427   // 'other' list must match those in this list.
428   void Remove(const CPURegList& other);
429 
430   // Variants of Combine and Remove which take CPURegisters.
431   void Combine(const CPURegister& other);
432   void Remove(const CPURegister& other1,
433               const CPURegister& other2 = NoCPUReg,
434               const CPURegister& other3 = NoCPUReg,
435               const CPURegister& other4 = NoCPUReg);
436 
437   // Variants of Combine and Remove which take a single register by its code;
438   // the type and size of the register is inferred from this list.
439   void Combine(int code);
440   void Remove(int code);
441 
442   // Remove all callee-saved registers from the list. This can be useful when
443   // preparing registers for an AAPCS64 function call, for example.
444   void RemoveCalleeSaved();
445 
446   CPURegister PopLowestIndex();
447   CPURegister PopHighestIndex();
448 
449   // AAPCS64 callee-saved registers.
450   static CPURegList GetCalleeSaved(int size = kXRegSizeInBits);
451   static CPURegList GetCalleeSavedFP(int size = kDRegSizeInBits);
452 
453   // AAPCS64 caller-saved registers. Note that this includes lr.
454   static CPURegList GetCallerSaved(int size = kXRegSizeInBits);
455   static CPURegList GetCallerSavedFP(int size = kDRegSizeInBits);
456 
457   // Registers saved as safepoints.
458   static CPURegList GetSafepointSavedRegisters();
459 
IsEmpty()460   bool IsEmpty() const {
461     DCHECK(IsValid());
462     return list_ == 0;
463   }
464 
465   bool IncludesAliasOf(const CPURegister& other1,
466                        const CPURegister& other2 = NoCPUReg,
467                        const CPURegister& other3 = NoCPUReg,
468                        const CPURegister& other4 = NoCPUReg) const {
469     DCHECK(IsValid());
470     RegList list = 0;
471     if (!other1.IsNone() && (other1.type() == type_)) list |= other1.Bit();
472     if (!other2.IsNone() && (other2.type() == type_)) list |= other2.Bit();
473     if (!other3.IsNone() && (other3.type() == type_)) list |= other3.Bit();
474     if (!other4.IsNone() && (other4.type() == type_)) list |= other4.Bit();
475     return (list_ & list) != 0;
476   }
477 
Count()478   int Count() const {
479     DCHECK(IsValid());
480     return CountSetBits(list_, kRegListSizeInBits);
481   }
482 
RegisterSizeInBits()483   int RegisterSizeInBits() const {
484     DCHECK(IsValid());
485     return size_;
486   }
487 
RegisterSizeInBytes()488   int RegisterSizeInBytes() const {
489     int size_in_bits = RegisterSizeInBits();
490     DCHECK((size_in_bits % kBitsPerByte) == 0);
491     return size_in_bits / kBitsPerByte;
492   }
493 
TotalSizeInBytes()494   int TotalSizeInBytes() const {
495     DCHECK(IsValid());
496     return RegisterSizeInBytes() * Count();
497   }
498 
499  private:
500   RegList list_;
501   int size_;
502   CPURegister::RegisterType type_;
503 
IsValid()504   bool IsValid() const {
505     const RegList kValidRegisters = 0x8000000ffffffff;
506     const RegList kValidFPRegisters = 0x0000000ffffffff;
507     switch (type_) {
508       case CPURegister::kRegister:
509         return (list_ & kValidRegisters) == list_;
510       case CPURegister::kFPRegister:
511         return (list_ & kValidFPRegisters) == list_;
512       case CPURegister::kNoRegister:
513         return list_ == 0;
514       default:
515         UNREACHABLE();
516         return false;
517     }
518   }
519 };
520 
521 
522 // AAPCS64 callee-saved registers.
523 #define kCalleeSaved CPURegList::GetCalleeSaved()
524 #define kCalleeSavedFP CPURegList::GetCalleeSavedFP()
525 
526 
527 // AAPCS64 caller-saved registers. Note that this includes lr.
528 #define kCallerSaved CPURegList::GetCallerSaved()
529 #define kCallerSavedFP CPURegList::GetCallerSavedFP()
530 
531 // -----------------------------------------------------------------------------
532 // Immediates.
533 class Immediate {
534  public:
535   template<typename T>
536   inline explicit Immediate(Handle<T> handle);
537 
538   // This is allowed to be an implicit constructor because Immediate is
539   // a wrapper class that doesn't normally perform any type conversion.
540   template<typename T>
541   inline Immediate(T value);  // NOLINT(runtime/explicit)
542 
543   template<typename T>
544   inline Immediate(T value, RelocInfo::Mode rmode);
545 
value()546   int64_t value() const { return value_; }
rmode()547   RelocInfo::Mode rmode() const { return rmode_; }
548 
549  private:
550   void InitializeHandle(Handle<Object> value);
551 
552   int64_t value_;
553   RelocInfo::Mode rmode_;
554 };
555 
556 
557 // -----------------------------------------------------------------------------
558 // Operands.
559 const int kSmiShift = kSmiTagSize + kSmiShiftSize;
560 const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1;
561 
562 // Represents an operand in a machine instruction.
563 class Operand {
564   // TODO(all): If necessary, study more in details which methods
565   // TODO(all): should be inlined or not.
566  public:
567   // rm, {<shift> {#<shift_amount>}}
568   // where <shift> is one of {LSL, LSR, ASR, ROR}.
569   //       <shift_amount> is uint6_t.
570   // This is allowed to be an implicit constructor because Operand is
571   // a wrapper class that doesn't normally perform any type conversion.
572   inline Operand(Register reg,
573                  Shift shift = LSL,
574                  unsigned shift_amount = 0);  // NOLINT(runtime/explicit)
575 
576   // rm, <extend> {#<shift_amount>}
577   // where <extend> is one of {UXTB, UXTH, UXTW, UXTX, SXTB, SXTH, SXTW, SXTX}.
578   //       <shift_amount> is uint2_t.
579   inline Operand(Register reg,
580                  Extend extend,
581                  unsigned shift_amount = 0);
582 
583   template<typename T>
584   inline explicit Operand(Handle<T> handle);
585 
586   // Implicit constructor for all int types, ExternalReference, and Smi.
587   template<typename T>
588   inline Operand(T t);  // NOLINT(runtime/explicit)
589 
590   // Implicit constructor for int types.
591   template<typename T>
592   inline Operand(T t, RelocInfo::Mode rmode);
593 
594   inline bool IsImmediate() const;
595   inline bool IsShiftedRegister() const;
596   inline bool IsExtendedRegister() const;
597   inline bool IsZero() const;
598 
599   // This returns an LSL shift (<= 4) operand as an equivalent extend operand,
600   // which helps in the encoding of instructions that use the stack pointer.
601   inline Operand ToExtendedRegister() const;
602 
603   inline Immediate immediate() const;
604   inline int64_t ImmediateValue() const;
605   inline Register reg() const;
606   inline Shift shift() const;
607   inline Extend extend() const;
608   inline unsigned shift_amount() const;
609 
610   // Relocation information.
611   bool NeedsRelocation(const Assembler* assembler) const;
612 
613   // Helpers
614   inline static Operand UntagSmi(Register smi);
615   inline static Operand UntagSmiAndScale(Register smi, int scale);
616 
617  private:
618   Immediate immediate_;
619   Register reg_;
620   Shift shift_;
621   Extend extend_;
622   unsigned shift_amount_;
623 };
624 
625 
626 // MemOperand represents a memory operand in a load or store instruction.
627 class MemOperand {
628  public:
629   inline MemOperand();
630   inline explicit MemOperand(Register base,
631                              int64_t offset = 0,
632                              AddrMode addrmode = Offset);
633   inline explicit MemOperand(Register base,
634                              Register regoffset,
635                              Shift shift = LSL,
636                              unsigned shift_amount = 0);
637   inline explicit MemOperand(Register base,
638                              Register regoffset,
639                              Extend extend,
640                              unsigned shift_amount = 0);
641   inline explicit MemOperand(Register base,
642                              const Operand& offset,
643                              AddrMode addrmode = Offset);
644 
base()645   const Register& base() const { return base_; }
regoffset()646   const Register& regoffset() const { return regoffset_; }
offset()647   int64_t offset() const { return offset_; }
addrmode()648   AddrMode addrmode() const { return addrmode_; }
shift()649   Shift shift() const { return shift_; }
extend()650   Extend extend() const { return extend_; }
shift_amount()651   unsigned shift_amount() const { return shift_amount_; }
652   inline bool IsImmediateOffset() const;
653   inline bool IsRegisterOffset() const;
654   inline bool IsPreIndex() const;
655   inline bool IsPostIndex() const;
656 
657   // For offset modes, return the offset as an Operand. This helper cannot
658   // handle indexed modes.
659   inline Operand OffsetAsOperand() const;
660 
661   enum PairResult {
662     kNotPair,   // Can't use a pair instruction.
663     kPairAB,    // Can use a pair instruction (operandA has lower address).
664     kPairBA     // Can use a pair instruction (operandB has lower address).
665   };
666   // Check if two MemOperand are consistent for stp/ldp use.
667   static PairResult AreConsistentForPair(const MemOperand& operandA,
668                                          const MemOperand& operandB,
669                                          int access_size_log2 = kXRegSizeLog2);
670 
671  private:
672   Register base_;
673   Register regoffset_;
674   int64_t offset_;
675   AddrMode addrmode_;
676   Shift shift_;
677   Extend extend_;
678   unsigned shift_amount_;
679 };
680 
681 
682 class ConstPool {
683  public:
ConstPool(Assembler * assm)684   explicit ConstPool(Assembler* assm)
685       : assm_(assm),
686         first_use_(-1),
687         shared_entries_count(0) {}
688   void RecordEntry(intptr_t data, RelocInfo::Mode mode);
EntryCount()689   int EntryCount() const {
690     return shared_entries_count + static_cast<int>(unique_entries_.size());
691   }
IsEmpty()692   bool IsEmpty() const {
693     return shared_entries_.empty() && unique_entries_.empty();
694   }
695   // Distance in bytes between the current pc and the first instruction
696   // using the pool. If there are no pending entries return kMaxInt.
697   int DistanceToFirstUse();
698   // Offset after which instructions using the pool will be out of range.
699   int MaxPcOffset();
700   // Maximum size the constant pool can be with current entries. It always
701   // includes alignment padding and branch over.
702   int WorstCaseSize();
703   // Size in bytes of the literal pool *if* it is emitted at the current
704   // pc. The size will include the branch over the pool if it was requested.
705   int SizeIfEmittedAtCurrentPc(bool require_jump);
706   // Emit the literal pool at the current pc with a branch over the pool if
707   // requested.
708   void Emit(bool require_jump);
709   // Discard any pending pool entries.
710   void Clear();
711 
712  private:
713   bool CanBeShared(RelocInfo::Mode mode);
714   void EmitMarker();
715   void EmitGuard();
716   void EmitEntries();
717 
718   Assembler* assm_;
719   // Keep track of the first instruction requiring a constant pool entry
720   // since the previous constant pool was emitted.
721   int first_use_;
722   // values, pc offset(s) of entries which can be shared.
723   std::multimap<uint64_t, int> shared_entries_;
724   // Number of distinct literal in shared entries.
725   int shared_entries_count;
726   // values, pc offset of entries which cannot be shared.
727   std::vector<std::pair<uint64_t, int> > unique_entries_;
728 };
729 
730 
731 // -----------------------------------------------------------------------------
732 // Assembler.
733 
734 class Assembler : public AssemblerBase {
735  public:
736   // Create an assembler. Instructions and relocation information are emitted
737   // into a buffer, with the instructions starting from the beginning and the
738   // relocation information starting from the end of the buffer. See CodeDesc
739   // for a detailed comment on the layout (globals.h).
740   //
741   // If the provided buffer is NULL, the assembler allocates and grows its own
742   // buffer, and buffer_size determines the initial buffer size. The buffer is
743   // owned by the assembler and deallocated upon destruction of the assembler.
744   //
745   // If the provided buffer is not NULL, the assembler uses the provided buffer
746   // for code generation and assumes its size to be buffer_size. If the buffer
747   // is too small, a fatal error occurs. No deallocation of the buffer is done
748   // upon destruction of the assembler.
749   Assembler(Isolate* arg_isolate, void* buffer, int buffer_size);
750 
751   virtual ~Assembler();
752 
AbortedCodeGeneration()753   virtual void AbortedCodeGeneration() {
754     constpool_.Clear();
755   }
756 
757   // System functions ---------------------------------------------------------
758   // Start generating code from the beginning of the buffer, discarding any code
759   // and data that has already been emitted into the buffer.
760   //
761   // In order to avoid any accidental transfer of state, Reset DCHECKs that the
762   // constant pool is not blocked.
763   void Reset();
764 
765   // GetCode emits any pending (non-emitted) code and fills the descriptor
766   // desc. GetCode() is idempotent; it returns the same result if no other
767   // Assembler functions are invoked in between GetCode() calls.
768   //
769   // The descriptor (desc) can be NULL. In that case, the code is finalized as
770   // usual, but the descriptor is not populated.
771   void GetCode(CodeDesc* desc);
772 
773   // Insert the smallest number of nop instructions
774   // possible to align the pc offset to a multiple
775   // of m. m must be a power of 2 (>= 4).
776   void Align(int m);
777   // Insert the smallest number of zero bytes possible to align the pc offset
778   // to a mulitple of m. m must be a power of 2 (>= 2).
779   void DataAlign(int m);
780 
781   inline void Unreachable();
782 
783   // Label --------------------------------------------------------------------
784   // Bind a label to the current pc. Note that labels can only be bound once,
785   // and if labels are linked to other instructions, they _must_ be bound
786   // before they go out of scope.
787   void bind(Label* label);
788 
789 
790   // RelocInfo and pools ------------------------------------------------------
791 
792   // Record relocation information for current pc_.
793   void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
794 
795   // Return the address in the constant pool of the code target address used by
796   // the branch/call instruction at pc.
797   inline static Address target_pointer_address_at(Address pc);
798 
799   // Read/Modify the code target address in the branch/call instruction at pc.
800   inline static Address target_address_at(Address pc, Address constant_pool);
801   inline static void set_target_address_at(
802       Isolate* isolate, Address pc, Address constant_pool, Address target,
803       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
804   static inline Address target_address_at(Address pc, Code* code);
805   static inline void set_target_address_at(
806       Isolate* isolate, Address pc, Code* code, Address target,
807       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
808 
809   // Return the code target address at a call site from the return address of
810   // that call in the instruction stream.
811   inline static Address target_address_from_return_address(Address pc);
812 
813   // Given the address of the beginning of a call, return the address in the
814   // instruction stream that call will return from.
815   inline static Address return_address_from_call_start(Address pc);
816 
817   // This sets the branch destination (which is in the constant pool on ARM).
818   // This is for calls and branches within generated code.
819   inline static void deserialization_set_special_target_at(
820       Isolate* isolate, Address constant_pool_entry, Code* code,
821       Address target);
822 
823   // This sets the internal reference at the pc.
824   inline static void deserialization_set_target_internal_reference_at(
825       Isolate* isolate, Address pc, Address target,
826       RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
827 
828   // All addresses in the constant pool are the same size as pointers.
829   static const int kSpecialTargetSize = kPointerSize;
830 
831   // The sizes of the call sequences emitted by MacroAssembler::Call.
832   // Wherever possible, use MacroAssembler::CallSize instead of these constants,
833   // as it will choose the correct value for a given relocation mode.
834   //
835   // Without relocation:
836   //  movz  temp, #(target & 0x000000000000ffff)
837   //  movk  temp, #(target & 0x00000000ffff0000)
838   //  movk  temp, #(target & 0x0000ffff00000000)
839   //  blr   temp
840   //
841   // With relocation:
842   //  ldr   temp, =target
843   //  blr   temp
844   static const int kCallSizeWithoutRelocation = 4 * kInstructionSize;
845   static const int kCallSizeWithRelocation = 2 * kInstructionSize;
846 
847   // Size of the generated code in bytes
SizeOfGeneratedCode()848   uint64_t SizeOfGeneratedCode() const {
849     DCHECK((pc_ >= buffer_) && (pc_ < (buffer_ + buffer_size_)));
850     return pc_ - buffer_;
851   }
852 
853   // Return the code size generated from label to the current position.
SizeOfCodeGeneratedSince(const Label * label)854   uint64_t SizeOfCodeGeneratedSince(const Label* label) {
855     DCHECK(label->is_bound());
856     DCHECK(pc_offset() >= label->pos());
857     DCHECK(pc_offset() < buffer_size_);
858     return pc_offset() - label->pos();
859   }
860 
861   // Check the size of the code generated since the given label. This function
862   // is used primarily to work around comparisons between signed and unsigned
863   // quantities, since V8 uses both.
864   // TODO(jbramley): Work out what sign to use for these things and if possible,
865   // change things to be consistent.
AssertSizeOfCodeGeneratedSince(const Label * label,ptrdiff_t size)866   void AssertSizeOfCodeGeneratedSince(const Label* label, ptrdiff_t size) {
867     DCHECK(size >= 0);
868     DCHECK(static_cast<uint64_t>(size) == SizeOfCodeGeneratedSince(label));
869   }
870 
871   // Return the number of instructions generated from label to the
872   // current position.
InstructionsGeneratedSince(const Label * label)873   uint64_t InstructionsGeneratedSince(const Label* label) {
874     return SizeOfCodeGeneratedSince(label) / kInstructionSize;
875   }
876 
877   static const int kPatchDebugBreakSlotAddressOffset =  0;
878 
879   // Number of instructions necessary to be able to later patch it to a call.
880   static const int kDebugBreakSlotInstructions = 5;
881   static const int kDebugBreakSlotLength =
882     kDebugBreakSlotInstructions * kInstructionSize;
883 
884   // Prevent contant pool emission until EndBlockConstPool is called.
885   // Call to this function can be nested but must be followed by an equal
886   // number of call to EndBlockConstpool.
887   void StartBlockConstPool();
888 
889   // Resume constant pool emission. Need to be called as many time as
890   // StartBlockConstPool to have an effect.
891   void EndBlockConstPool();
892 
893   bool is_const_pool_blocked() const;
894   static bool IsConstantPoolAt(Instruction* instr);
895   static int ConstantPoolSizeAt(Instruction* instr);
896   // See Assembler::CheckConstPool for more info.
897   void EmitPoolGuard();
898 
899   // Prevent veneer pool emission until EndBlockVeneerPool is called.
900   // Call to this function can be nested but must be followed by an equal
901   // number of call to EndBlockConstpool.
902   void StartBlockVeneerPool();
903 
904   // Resume constant pool emission. Need to be called as many time as
905   // StartBlockVeneerPool to have an effect.
906   void EndBlockVeneerPool();
907 
is_veneer_pool_blocked()908   bool is_veneer_pool_blocked() const {
909     return veneer_pool_blocked_nesting_ > 0;
910   }
911 
912   // Block/resume emission of constant pools and veneer pools.
StartBlockPools()913   void StartBlockPools() {
914     StartBlockConstPool();
915     StartBlockVeneerPool();
916   }
EndBlockPools()917   void EndBlockPools() {
918     EndBlockConstPool();
919     EndBlockVeneerPool();
920   }
921 
922   // Debugging ----------------------------------------------------------------
positions_recorder()923   PositionsRecorder* positions_recorder() { return &positions_recorder_; }
924   void RecordComment(const char* msg);
925 
926   // Record a deoptimization reason that can be used by a log or cpu profiler.
927   // Use --trace-deopt to enable.
928   void RecordDeoptReason(const int reason, const SourcePosition position);
929 
930   int buffer_space() const;
931 
932   // Mark generator continuation.
933   void RecordGeneratorContinuation();
934 
935   // Mark address of a debug break slot.
936   void RecordDebugBreakSlot(RelocInfo::Mode mode);
937 
938   // Record the emission of a constant pool.
939   //
940   // The emission of constant and veneer pools depends on the size of the code
941   // generated and the number of RelocInfo recorded.
942   // The Debug mechanism needs to map code offsets between two versions of a
943   // function, compiled with and without debugger support (see for example
944   // Debug::PrepareForBreakPoints()).
945   // Compiling functions with debugger support generates additional code
946   // (DebugCodegen::GenerateSlot()). This may affect the emission of the pools
947   // and cause the version of the code with debugger support to have pools
948   // generated in different places.
949   // Recording the position and size of emitted pools allows to correctly
950   // compute the offset mappings between the different versions of a function in
951   // all situations.
952   //
953   // The parameter indicates the size of the pool (in bytes), including
954   // the marker and branch over the data.
955   void RecordConstPool(int size);
956 
957 
958   // Instruction set functions ------------------------------------------------
959 
960   // Branch / Jump instructions.
961   // For branches offsets are scaled, i.e. they in instrcutions not in bytes.
962   // Branch to register.
963   void br(const Register& xn);
964 
965   // Branch-link to register.
966   void blr(const Register& xn);
967 
968   // Branch to register with return hint.
969   void ret(const Register& xn = lr);
970 
971   // Unconditional branch to label.
972   void b(Label* label);
973 
974   // Conditional branch to label.
975   void b(Label* label, Condition cond);
976 
977   // Unconditional branch to PC offset.
978   void b(int imm26);
979 
980   // Conditional branch to PC offset.
981   void b(int imm19, Condition cond);
982 
983   // Branch-link to label / pc offset.
984   void bl(Label* label);
985   void bl(int imm26);
986 
987   // Compare and branch to label / pc offset if zero.
988   void cbz(const Register& rt, Label* label);
989   void cbz(const Register& rt, int imm19);
990 
991   // Compare and branch to label / pc offset if not zero.
992   void cbnz(const Register& rt, Label* label);
993   void cbnz(const Register& rt, int imm19);
994 
995   // Test bit and branch to label / pc offset if zero.
996   void tbz(const Register& rt, unsigned bit_pos, Label* label);
997   void tbz(const Register& rt, unsigned bit_pos, int imm14);
998 
999   // Test bit and branch to label / pc offset if not zero.
1000   void tbnz(const Register& rt, unsigned bit_pos, Label* label);
1001   void tbnz(const Register& rt, unsigned bit_pos, int imm14);
1002 
1003   // Address calculation instructions.
1004   // Calculate a PC-relative address. Unlike for branches the offset in adr is
1005   // unscaled (i.e. the result can be unaligned).
1006   void adr(const Register& rd, Label* label);
1007   void adr(const Register& rd, int imm21);
1008 
1009   // Data Processing instructions.
1010   // Add.
1011   void add(const Register& rd,
1012            const Register& rn,
1013            const Operand& operand);
1014 
1015   // Add and update status flags.
1016   void adds(const Register& rd,
1017             const Register& rn,
1018             const Operand& operand);
1019 
1020   // Compare negative.
1021   void cmn(const Register& rn, const Operand& operand);
1022 
1023   // Subtract.
1024   void sub(const Register& rd,
1025            const Register& rn,
1026            const Operand& operand);
1027 
1028   // Subtract and update status flags.
1029   void subs(const Register& rd,
1030             const Register& rn,
1031             const Operand& operand);
1032 
1033   // Compare.
1034   void cmp(const Register& rn, const Operand& operand);
1035 
1036   // Negate.
1037   void neg(const Register& rd,
1038            const Operand& operand);
1039 
1040   // Negate and update status flags.
1041   void negs(const Register& rd,
1042             const Operand& operand);
1043 
1044   // Add with carry bit.
1045   void adc(const Register& rd,
1046            const Register& rn,
1047            const Operand& operand);
1048 
1049   // Add with carry bit and update status flags.
1050   void adcs(const Register& rd,
1051             const Register& rn,
1052             const Operand& operand);
1053 
1054   // Subtract with carry bit.
1055   void sbc(const Register& rd,
1056            const Register& rn,
1057            const Operand& operand);
1058 
1059   // Subtract with carry bit and update status flags.
1060   void sbcs(const Register& rd,
1061             const Register& rn,
1062             const Operand& operand);
1063 
1064   // Negate with carry bit.
1065   void ngc(const Register& rd,
1066            const Operand& operand);
1067 
1068   // Negate with carry bit and update status flags.
1069   void ngcs(const Register& rd,
1070             const Operand& operand);
1071 
1072   // Logical instructions.
1073   // Bitwise and (A & B).
1074   void and_(const Register& rd,
1075             const Register& rn,
1076             const Operand& operand);
1077 
1078   // Bitwise and (A & B) and update status flags.
1079   void ands(const Register& rd,
1080             const Register& rn,
1081             const Operand& operand);
1082 
1083   // Bit test, and set flags.
1084   void tst(const Register& rn, const Operand& operand);
1085 
1086   // Bit clear (A & ~B).
1087   void bic(const Register& rd,
1088            const Register& rn,
1089            const Operand& operand);
1090 
1091   // Bit clear (A & ~B) and update status flags.
1092   void bics(const Register& rd,
1093             const Register& rn,
1094             const Operand& operand);
1095 
1096   // Bitwise or (A | B).
1097   void orr(const Register& rd, const Register& rn, const Operand& operand);
1098 
1099   // Bitwise nor (A | ~B).
1100   void orn(const Register& rd, const Register& rn, const Operand& operand);
1101 
1102   // Bitwise eor/xor (A ^ B).
1103   void eor(const Register& rd, const Register& rn, const Operand& operand);
1104 
1105   // Bitwise enor/xnor (A ^ ~B).
1106   void eon(const Register& rd, const Register& rn, const Operand& operand);
1107 
1108   // Logical shift left variable.
1109   void lslv(const Register& rd, const Register& rn, const Register& rm);
1110 
1111   // Logical shift right variable.
1112   void lsrv(const Register& rd, const Register& rn, const Register& rm);
1113 
1114   // Arithmetic shift right variable.
1115   void asrv(const Register& rd, const Register& rn, const Register& rm);
1116 
1117   // Rotate right variable.
1118   void rorv(const Register& rd, const Register& rn, const Register& rm);
1119 
1120   // Bitfield instructions.
1121   // Bitfield move.
1122   void bfm(const Register& rd, const Register& rn, int immr, int imms);
1123 
1124   // Signed bitfield move.
1125   void sbfm(const Register& rd, const Register& rn, int immr, int imms);
1126 
1127   // Unsigned bitfield move.
1128   void ubfm(const Register& rd, const Register& rn, int immr, int imms);
1129 
1130   // Bfm aliases.
1131   // Bitfield insert.
bfi(const Register & rd,const Register & rn,int lsb,int width)1132   void bfi(const Register& rd, const Register& rn, int lsb, int width) {
1133     DCHECK(width >= 1);
1134     DCHECK(lsb + width <= rn.SizeInBits());
1135     bfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1);
1136   }
1137 
1138   // Bitfield extract and insert low.
bfxil(const Register & rd,const Register & rn,int lsb,int width)1139   void bfxil(const Register& rd, const Register& rn, int lsb, int width) {
1140     DCHECK(width >= 1);
1141     DCHECK(lsb + width <= rn.SizeInBits());
1142     bfm(rd, rn, lsb, lsb + width - 1);
1143   }
1144 
1145   // Sbfm aliases.
1146   // Arithmetic shift right.
asr(const Register & rd,const Register & rn,int shift)1147   void asr(const Register& rd, const Register& rn, int shift) {
1148     DCHECK(shift < rd.SizeInBits());
1149     sbfm(rd, rn, shift, rd.SizeInBits() - 1);
1150   }
1151 
1152   // Signed bitfield insert in zero.
sbfiz(const Register & rd,const Register & rn,int lsb,int width)1153   void sbfiz(const Register& rd, const Register& rn, int lsb, int width) {
1154     DCHECK(width >= 1);
1155     DCHECK(lsb + width <= rn.SizeInBits());
1156     sbfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1);
1157   }
1158 
1159   // Signed bitfield extract.
sbfx(const Register & rd,const Register & rn,int lsb,int width)1160   void sbfx(const Register& rd, const Register& rn, int lsb, int width) {
1161     DCHECK(width >= 1);
1162     DCHECK(lsb + width <= rn.SizeInBits());
1163     sbfm(rd, rn, lsb, lsb + width - 1);
1164   }
1165 
1166   // Signed extend byte.
sxtb(const Register & rd,const Register & rn)1167   void sxtb(const Register& rd, const Register& rn) {
1168     sbfm(rd, rn, 0, 7);
1169   }
1170 
1171   // Signed extend halfword.
sxth(const Register & rd,const Register & rn)1172   void sxth(const Register& rd, const Register& rn) {
1173     sbfm(rd, rn, 0, 15);
1174   }
1175 
1176   // Signed extend word.
sxtw(const Register & rd,const Register & rn)1177   void sxtw(const Register& rd, const Register& rn) {
1178     sbfm(rd, rn, 0, 31);
1179   }
1180 
1181   // Ubfm aliases.
1182   // Logical shift left.
lsl(const Register & rd,const Register & rn,int shift)1183   void lsl(const Register& rd, const Register& rn, int shift) {
1184     int reg_size = rd.SizeInBits();
1185     DCHECK(shift < reg_size);
1186     ubfm(rd, rn, (reg_size - shift) % reg_size, reg_size - shift - 1);
1187   }
1188 
1189   // Logical shift right.
lsr(const Register & rd,const Register & rn,int shift)1190   void lsr(const Register& rd, const Register& rn, int shift) {
1191     DCHECK(shift < rd.SizeInBits());
1192     ubfm(rd, rn, shift, rd.SizeInBits() - 1);
1193   }
1194 
1195   // Unsigned bitfield insert in zero.
ubfiz(const Register & rd,const Register & rn,int lsb,int width)1196   void ubfiz(const Register& rd, const Register& rn, int lsb, int width) {
1197     DCHECK(width >= 1);
1198     DCHECK(lsb + width <= rn.SizeInBits());
1199     ubfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1);
1200   }
1201 
1202   // Unsigned bitfield extract.
ubfx(const Register & rd,const Register & rn,int lsb,int width)1203   void ubfx(const Register& rd, const Register& rn, int lsb, int width) {
1204     DCHECK(width >= 1);
1205     DCHECK(lsb + width <= rn.SizeInBits());
1206     ubfm(rd, rn, lsb, lsb + width - 1);
1207   }
1208 
1209   // Unsigned extend byte.
uxtb(const Register & rd,const Register & rn)1210   void uxtb(const Register& rd, const Register& rn) {
1211     ubfm(rd, rn, 0, 7);
1212   }
1213 
1214   // Unsigned extend halfword.
uxth(const Register & rd,const Register & rn)1215   void uxth(const Register& rd, const Register& rn) {
1216     ubfm(rd, rn, 0, 15);
1217   }
1218 
1219   // Unsigned extend word.
uxtw(const Register & rd,const Register & rn)1220   void uxtw(const Register& rd, const Register& rn) {
1221     ubfm(rd, rn, 0, 31);
1222   }
1223 
1224   // Extract.
1225   void extr(const Register& rd, const Register& rn, const Register& rm,
1226             int lsb);
1227 
1228   // Conditional select: rd = cond ? rn : rm.
1229   void csel(const Register& rd,
1230             const Register& rn,
1231             const Register& rm,
1232             Condition cond);
1233 
1234   // Conditional select increment: rd = cond ? rn : rm + 1.
1235   void csinc(const Register& rd,
1236              const Register& rn,
1237              const Register& rm,
1238              Condition cond);
1239 
1240   // Conditional select inversion: rd = cond ? rn : ~rm.
1241   void csinv(const Register& rd,
1242              const Register& rn,
1243              const Register& rm,
1244              Condition cond);
1245 
1246   // Conditional select negation: rd = cond ? rn : -rm.
1247   void csneg(const Register& rd,
1248              const Register& rn,
1249              const Register& rm,
1250              Condition cond);
1251 
1252   // Conditional set: rd = cond ? 1 : 0.
1253   void cset(const Register& rd, Condition cond);
1254 
1255   // Conditional set minus: rd = cond ? -1 : 0.
1256   void csetm(const Register& rd, Condition cond);
1257 
1258   // Conditional increment: rd = cond ? rn + 1 : rn.
1259   void cinc(const Register& rd, const Register& rn, Condition cond);
1260 
1261   // Conditional invert: rd = cond ? ~rn : rn.
1262   void cinv(const Register& rd, const Register& rn, Condition cond);
1263 
1264   // Conditional negate: rd = cond ? -rn : rn.
1265   void cneg(const Register& rd, const Register& rn, Condition cond);
1266 
1267   // Extr aliases.
ror(const Register & rd,const Register & rs,unsigned shift)1268   void ror(const Register& rd, const Register& rs, unsigned shift) {
1269     extr(rd, rs, rs, shift);
1270   }
1271 
1272   // Conditional comparison.
1273   // Conditional compare negative.
1274   void ccmn(const Register& rn,
1275             const Operand& operand,
1276             StatusFlags nzcv,
1277             Condition cond);
1278 
1279   // Conditional compare.
1280   void ccmp(const Register& rn,
1281             const Operand& operand,
1282             StatusFlags nzcv,
1283             Condition cond);
1284 
1285   // Multiplication.
1286   // 32 x 32 -> 32-bit and 64 x 64 -> 64-bit multiply.
1287   void mul(const Register& rd, const Register& rn, const Register& rm);
1288 
1289   // 32 + 32 x 32 -> 32-bit and 64 + 64 x 64 -> 64-bit multiply accumulate.
1290   void madd(const Register& rd,
1291             const Register& rn,
1292             const Register& rm,
1293             const Register& ra);
1294 
1295   // -(32 x 32) -> 32-bit and -(64 x 64) -> 64-bit multiply.
1296   void mneg(const Register& rd, const Register& rn, const Register& rm);
1297 
1298   // 32 - 32 x 32 -> 32-bit and 64 - 64 x 64 -> 64-bit multiply subtract.
1299   void msub(const Register& rd,
1300             const Register& rn,
1301             const Register& rm,
1302             const Register& ra);
1303 
1304   // 32 x 32 -> 64-bit multiply.
1305   void smull(const Register& rd, const Register& rn, const Register& rm);
1306 
1307   // Xd = bits<127:64> of Xn * Xm.
1308   void smulh(const Register& rd, const Register& rn, const Register& rm);
1309 
1310   // Signed 32 x 32 -> 64-bit multiply and accumulate.
1311   void smaddl(const Register& rd,
1312               const Register& rn,
1313               const Register& rm,
1314               const Register& ra);
1315 
1316   // Unsigned 32 x 32 -> 64-bit multiply and accumulate.
1317   void umaddl(const Register& rd,
1318               const Register& rn,
1319               const Register& rm,
1320               const Register& ra);
1321 
1322   // Signed 32 x 32 -> 64-bit multiply and subtract.
1323   void smsubl(const Register& rd,
1324               const Register& rn,
1325               const Register& rm,
1326               const Register& ra);
1327 
1328   // Unsigned 32 x 32 -> 64-bit multiply and subtract.
1329   void umsubl(const Register& rd,
1330               const Register& rn,
1331               const Register& rm,
1332               const Register& ra);
1333 
1334   // Signed integer divide.
1335   void sdiv(const Register& rd, const Register& rn, const Register& rm);
1336 
1337   // Unsigned integer divide.
1338   void udiv(const Register& rd, const Register& rn, const Register& rm);
1339 
1340   // Bit count, bit reverse and endian reverse.
1341   void rbit(const Register& rd, const Register& rn);
1342   void rev16(const Register& rd, const Register& rn);
1343   void rev32(const Register& rd, const Register& rn);
1344   void rev(const Register& rd, const Register& rn);
1345   void clz(const Register& rd, const Register& rn);
1346   void cls(const Register& rd, const Register& rn);
1347 
1348   // Memory instructions.
1349 
1350   // Load integer or FP register.
1351   void ldr(const CPURegister& rt, const MemOperand& src);
1352 
1353   // Store integer or FP register.
1354   void str(const CPURegister& rt, const MemOperand& dst);
1355 
1356   // Load word with sign extension.
1357   void ldrsw(const Register& rt, const MemOperand& src);
1358 
1359   // Load byte.
1360   void ldrb(const Register& rt, const MemOperand& src);
1361 
1362   // Store byte.
1363   void strb(const Register& rt, const MemOperand& dst);
1364 
1365   // Load byte with sign extension.
1366   void ldrsb(const Register& rt, const MemOperand& src);
1367 
1368   // Load half-word.
1369   void ldrh(const Register& rt, const MemOperand& src);
1370 
1371   // Store half-word.
1372   void strh(const Register& rt, const MemOperand& dst);
1373 
1374   // Load half-word with sign extension.
1375   void ldrsh(const Register& rt, const MemOperand& src);
1376 
1377   // Load integer or FP register pair.
1378   void ldp(const CPURegister& rt, const CPURegister& rt2,
1379            const MemOperand& src);
1380 
1381   // Store integer or FP register pair.
1382   void stp(const CPURegister& rt, const CPURegister& rt2,
1383            const MemOperand& dst);
1384 
1385   // Load word pair with sign extension.
1386   void ldpsw(const Register& rt, const Register& rt2, const MemOperand& src);
1387 
1388   // Load literal to register from a pc relative address.
1389   void ldr_pcrel(const CPURegister& rt, int imm19);
1390 
1391   // Load literal to register.
1392   void ldr(const CPURegister& rt, const Immediate& imm);
1393 
1394   // Move instructions. The default shift of -1 indicates that the move
1395   // instruction will calculate an appropriate 16-bit immediate and left shift
1396   // that is equal to the 64-bit immediate argument. If an explicit left shift
1397   // is specified (0, 16, 32 or 48), the immediate must be a 16-bit value.
1398   //
1399   // For movk, an explicit shift can be used to indicate which half word should
1400   // be overwritten, eg. movk(x0, 0, 0) will overwrite the least-significant
1401   // half word with zero, whereas movk(x0, 0, 48) will overwrite the
1402   // most-significant.
1403 
1404   // Move and keep.
1405   void movk(const Register& rd, uint64_t imm, int shift = -1) {
1406     MoveWide(rd, imm, shift, MOVK);
1407   }
1408 
1409   // Move with non-zero.
1410   void movn(const Register& rd, uint64_t imm, int shift = -1) {
1411     MoveWide(rd, imm, shift, MOVN);
1412   }
1413 
1414   // Move with zero.
1415   void movz(const Register& rd, uint64_t imm, int shift = -1) {
1416     MoveWide(rd, imm, shift, MOVZ);
1417   }
1418 
1419   // Misc instructions.
1420   // Monitor debug-mode breakpoint.
1421   void brk(int code);
1422 
1423   // Halting debug-mode breakpoint.
1424   void hlt(int code);
1425 
1426   // Move register to register.
1427   void mov(const Register& rd, const Register& rn);
1428 
1429   // Move NOT(operand) to register.
1430   void mvn(const Register& rd, const Operand& operand);
1431 
1432   // System instructions.
1433   // Move to register from system register.
1434   void mrs(const Register& rt, SystemRegister sysreg);
1435 
1436   // Move from register to system register.
1437   void msr(SystemRegister sysreg, const Register& rt);
1438 
1439   // System hint.
1440   void hint(SystemHint code);
1441 
1442   // Data memory barrier
1443   void dmb(BarrierDomain domain, BarrierType type);
1444 
1445   // Data synchronization barrier
1446   void dsb(BarrierDomain domain, BarrierType type);
1447 
1448   // Instruction synchronization barrier
1449   void isb();
1450 
1451   // Alias for system instructions.
nop()1452   void nop() { hint(NOP); }
1453 
1454   // Different nop operations are used by the code generator to detect certain
1455   // states of the generated code.
1456   enum NopMarkerTypes {
1457     DEBUG_BREAK_NOP,
1458     INTERRUPT_CODE_NOP,
1459     ADR_FAR_NOP,
1460     FIRST_NOP_MARKER = DEBUG_BREAK_NOP,
1461     LAST_NOP_MARKER = ADR_FAR_NOP
1462   };
1463 
nop(NopMarkerTypes n)1464   void nop(NopMarkerTypes n) {
1465     DCHECK((FIRST_NOP_MARKER <= n) && (n <= LAST_NOP_MARKER));
1466     mov(Register::XRegFromCode(n), Register::XRegFromCode(n));
1467   }
1468 
1469   // FP instructions.
1470   // Move immediate to FP register.
1471   void fmov(FPRegister fd, double imm);
1472   void fmov(FPRegister fd, float imm);
1473 
1474   // Move FP register to register.
1475   void fmov(Register rd, FPRegister fn);
1476 
1477   // Move register to FP register.
1478   void fmov(FPRegister fd, Register rn);
1479 
1480   // Move FP register to FP register.
1481   void fmov(FPRegister fd, FPRegister fn);
1482 
1483   // FP add.
1484   void fadd(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm);
1485 
1486   // FP subtract.
1487   void fsub(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm);
1488 
1489   // FP multiply.
1490   void fmul(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm);
1491 
1492   // FP fused multiply and add.
1493   void fmadd(const FPRegister& fd,
1494              const FPRegister& fn,
1495              const FPRegister& fm,
1496              const FPRegister& fa);
1497 
1498   // FP fused multiply and subtract.
1499   void fmsub(const FPRegister& fd,
1500              const FPRegister& fn,
1501              const FPRegister& fm,
1502              const FPRegister& fa);
1503 
1504   // FP fused multiply, add and negate.
1505   void fnmadd(const FPRegister& fd,
1506               const FPRegister& fn,
1507               const FPRegister& fm,
1508               const FPRegister& fa);
1509 
1510   // FP fused multiply, subtract and negate.
1511   void fnmsub(const FPRegister& fd,
1512               const FPRegister& fn,
1513               const FPRegister& fm,
1514               const FPRegister& fa);
1515 
1516   // FP divide.
1517   void fdiv(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm);
1518 
1519   // FP maximum.
1520   void fmax(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm);
1521 
1522   // FP minimum.
1523   void fmin(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm);
1524 
1525   // FP maximum.
1526   void fmaxnm(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm);
1527 
1528   // FP minimum.
1529   void fminnm(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm);
1530 
1531   // FP absolute.
1532   void fabs(const FPRegister& fd, const FPRegister& fn);
1533 
1534   // FP negate.
1535   void fneg(const FPRegister& fd, const FPRegister& fn);
1536 
1537   // FP square root.
1538   void fsqrt(const FPRegister& fd, const FPRegister& fn);
1539 
1540   // FP round to integer (nearest with ties to away).
1541   void frinta(const FPRegister& fd, const FPRegister& fn);
1542 
1543   // FP round to integer (toward minus infinity).
1544   void frintm(const FPRegister& fd, const FPRegister& fn);
1545 
1546   // FP round to integer (nearest with ties to even).
1547   void frintn(const FPRegister& fd, const FPRegister& fn);
1548 
1549   // FP round to integer (towards plus infinity).
1550   void frintp(const FPRegister& fd, const FPRegister& fn);
1551 
1552   // FP round to integer (towards zero.)
1553   void frintz(const FPRegister& fd, const FPRegister& fn);
1554 
1555   // FP compare registers.
1556   void fcmp(const FPRegister& fn, const FPRegister& fm);
1557 
1558   // FP compare immediate.
1559   void fcmp(const FPRegister& fn, double value);
1560 
1561   // FP conditional compare.
1562   void fccmp(const FPRegister& fn,
1563              const FPRegister& fm,
1564              StatusFlags nzcv,
1565              Condition cond);
1566 
1567   // FP conditional select.
1568   void fcsel(const FPRegister& fd,
1569              const FPRegister& fn,
1570              const FPRegister& fm,
1571              Condition cond);
1572 
1573   // Common FP Convert function
1574   void FPConvertToInt(const Register& rd,
1575                       const FPRegister& fn,
1576                       FPIntegerConvertOp op);
1577 
1578   // FP convert between single and double precision.
1579   void fcvt(const FPRegister& fd, const FPRegister& fn);
1580 
1581   // Convert FP to unsigned integer (nearest with ties to away).
1582   void fcvtau(const Register& rd, const FPRegister& fn);
1583 
1584   // Convert FP to signed integer (nearest with ties to away).
1585   void fcvtas(const Register& rd, const FPRegister& fn);
1586 
1587   // Convert FP to unsigned integer (round towards -infinity).
1588   void fcvtmu(const Register& rd, const FPRegister& fn);
1589 
1590   // Convert FP to signed integer (round towards -infinity).
1591   void fcvtms(const Register& rd, const FPRegister& fn);
1592 
1593   // Convert FP to unsigned integer (nearest with ties to even).
1594   void fcvtnu(const Register& rd, const FPRegister& fn);
1595 
1596   // Convert FP to signed integer (nearest with ties to even).
1597   void fcvtns(const Register& rd, const FPRegister& fn);
1598 
1599   // Convert FP to unsigned integer (round towards zero).
1600   void fcvtzu(const Register& rd, const FPRegister& fn);
1601 
1602   // Convert FP to signed integer (rounf towards zero).
1603   void fcvtzs(const Register& rd, const FPRegister& fn);
1604 
1605   // Convert signed integer or fixed point to FP.
1606   void scvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0);
1607 
1608   // Convert unsigned integer or fixed point to FP.
1609   void ucvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0);
1610 
1611   // Instruction functions used only for test, debug, and patching.
1612   // Emit raw instructions in the instruction stream.
dci(Instr raw_inst)1613   void dci(Instr raw_inst) { Emit(raw_inst); }
1614 
1615   // Emit 8 bits of data in the instruction stream.
dc8(uint8_t data)1616   void dc8(uint8_t data) { EmitData(&data, sizeof(data)); }
1617 
1618   // Emit 32 bits of data in the instruction stream.
dc32(uint32_t data)1619   void dc32(uint32_t data) { EmitData(&data, sizeof(data)); }
1620 
1621   // Emit 64 bits of data in the instruction stream.
dc64(uint64_t data)1622   void dc64(uint64_t data) { EmitData(&data, sizeof(data)); }
1623 
1624   // Emit an address in the instruction stream.
1625   void dcptr(Label* label);
1626 
1627   // Copy a string into the instruction stream, including the terminating NULL
1628   // character. The instruction pointer (pc_) is then aligned correctly for
1629   // subsequent instructions.
1630   void EmitStringData(const char* string);
1631 
1632   // Pseudo-instructions ------------------------------------------------------
1633 
1634   // Parameters are described in arm64/instructions-arm64.h.
1635   void debug(const char* message, uint32_t code, Instr params = BREAK);
1636 
1637   // Required by V8.
dd(uint32_t data)1638   void dd(uint32_t data) { dc32(data); }
db(uint8_t data)1639   void db(uint8_t data) { dc8(data); }
dq(uint64_t data)1640   void dq(uint64_t data) { dc64(data); }
dp(uintptr_t data)1641   void dp(uintptr_t data) { dc64(data); }
1642 
1643   // Code generation helpers --------------------------------------------------
1644 
IsConstPoolEmpty()1645   bool IsConstPoolEmpty() const { return constpool_.IsEmpty(); }
1646 
pc()1647   Instruction* pc() const { return Instruction::Cast(pc_); }
1648 
InstructionAt(ptrdiff_t offset)1649   Instruction* InstructionAt(ptrdiff_t offset) const {
1650     return reinterpret_cast<Instruction*>(buffer_ + offset);
1651   }
1652 
InstructionOffset(Instruction * instr)1653   ptrdiff_t InstructionOffset(Instruction* instr) const {
1654     return reinterpret_cast<byte*>(instr) - buffer_;
1655   }
1656 
1657   // Register encoding.
Rd(CPURegister rd)1658   static Instr Rd(CPURegister rd) {
1659     DCHECK(rd.code() != kSPRegInternalCode);
1660     return rd.code() << Rd_offset;
1661   }
1662 
Rn(CPURegister rn)1663   static Instr Rn(CPURegister rn) {
1664     DCHECK(rn.code() != kSPRegInternalCode);
1665     return rn.code() << Rn_offset;
1666   }
1667 
Rm(CPURegister rm)1668   static Instr Rm(CPURegister rm) {
1669     DCHECK(rm.code() != kSPRegInternalCode);
1670     return rm.code() << Rm_offset;
1671   }
1672 
Ra(CPURegister ra)1673   static Instr Ra(CPURegister ra) {
1674     DCHECK(ra.code() != kSPRegInternalCode);
1675     return ra.code() << Ra_offset;
1676   }
1677 
Rt(CPURegister rt)1678   static Instr Rt(CPURegister rt) {
1679     DCHECK(rt.code() != kSPRegInternalCode);
1680     return rt.code() << Rt_offset;
1681   }
1682 
Rt2(CPURegister rt2)1683   static Instr Rt2(CPURegister rt2) {
1684     DCHECK(rt2.code() != kSPRegInternalCode);
1685     return rt2.code() << Rt2_offset;
1686   }
1687 
1688   // These encoding functions allow the stack pointer to be encoded, and
1689   // disallow the zero register.
RdSP(Register rd)1690   static Instr RdSP(Register rd) {
1691     DCHECK(!rd.IsZero());
1692     return (rd.code() & kRegCodeMask) << Rd_offset;
1693   }
1694 
RnSP(Register rn)1695   static Instr RnSP(Register rn) {
1696     DCHECK(!rn.IsZero());
1697     return (rn.code() & kRegCodeMask) << Rn_offset;
1698   }
1699 
1700   // Flags encoding.
1701   inline static Instr Flags(FlagsUpdate S);
1702   inline static Instr Cond(Condition cond);
1703 
1704   // PC-relative address encoding.
1705   inline static Instr ImmPCRelAddress(int imm21);
1706 
1707   // Branch encoding.
1708   inline static Instr ImmUncondBranch(int imm26);
1709   inline static Instr ImmCondBranch(int imm19);
1710   inline static Instr ImmCmpBranch(int imm19);
1711   inline static Instr ImmTestBranch(int imm14);
1712   inline static Instr ImmTestBranchBit(unsigned bit_pos);
1713 
1714   // Data Processing encoding.
1715   inline static Instr SF(Register rd);
1716   inline static Instr ImmAddSub(int imm);
1717   inline static Instr ImmS(unsigned imms, unsigned reg_size);
1718   inline static Instr ImmR(unsigned immr, unsigned reg_size);
1719   inline static Instr ImmSetBits(unsigned imms, unsigned reg_size);
1720   inline static Instr ImmRotate(unsigned immr, unsigned reg_size);
1721   inline static Instr ImmLLiteral(int imm19);
1722   inline static Instr BitN(unsigned bitn, unsigned reg_size);
1723   inline static Instr ShiftDP(Shift shift);
1724   inline static Instr ImmDPShift(unsigned amount);
1725   inline static Instr ExtendMode(Extend extend);
1726   inline static Instr ImmExtendShift(unsigned left_shift);
1727   inline static Instr ImmCondCmp(unsigned imm);
1728   inline static Instr Nzcv(StatusFlags nzcv);
1729 
1730   static bool IsImmAddSub(int64_t immediate);
1731   static bool IsImmLogical(uint64_t value,
1732                            unsigned width,
1733                            unsigned* n,
1734                            unsigned* imm_s,
1735                            unsigned* imm_r);
1736 
1737   // MemOperand offset encoding.
1738   inline static Instr ImmLSUnsigned(int imm12);
1739   inline static Instr ImmLS(int imm9);
1740   inline static Instr ImmLSPair(int imm7, LSDataSize size);
1741   inline static Instr ImmShiftLS(unsigned shift_amount);
1742   inline static Instr ImmException(int imm16);
1743   inline static Instr ImmSystemRegister(int imm15);
1744   inline static Instr ImmHint(int imm7);
1745   inline static Instr ImmBarrierDomain(int imm2);
1746   inline static Instr ImmBarrierType(int imm2);
1747   inline static LSDataSize CalcLSDataSize(LoadStoreOp op);
1748 
1749   static bool IsImmLSUnscaled(int64_t offset);
1750   static bool IsImmLSScaled(int64_t offset, LSDataSize size);
1751   static bool IsImmLLiteral(int64_t offset);
1752 
1753   // Move immediates encoding.
1754   inline static Instr ImmMoveWide(int imm);
1755   inline static Instr ShiftMoveWide(int shift);
1756 
1757   // FP Immediates.
1758   static Instr ImmFP32(float imm);
1759   static Instr ImmFP64(double imm);
1760   inline static Instr FPScale(unsigned scale);
1761 
1762   // FP register type.
1763   inline static Instr FPType(FPRegister fd);
1764 
1765   // Class for scoping postponing the constant pool generation.
1766   class BlockConstPoolScope {
1767    public:
BlockConstPoolScope(Assembler * assem)1768     explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) {
1769       assem_->StartBlockConstPool();
1770     }
~BlockConstPoolScope()1771     ~BlockConstPoolScope() {
1772       assem_->EndBlockConstPool();
1773     }
1774 
1775    private:
1776     Assembler* assem_;
1777 
1778     DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope);
1779   };
1780 
1781   // Check if is time to emit a constant pool.
1782   void CheckConstPool(bool force_emit, bool require_jump);
1783 
PatchConstantPoolAccessInstruction(int pc_offset,int offset,ConstantPoolEntry::Access access,ConstantPoolEntry::Type type)1784   void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1785                                           ConstantPoolEntry::Access access,
1786                                           ConstantPoolEntry::Type type) {
1787     // No embedded constant pool support.
1788     UNREACHABLE();
1789   }
1790 
1791   // Returns true if we should emit a veneer as soon as possible for a branch
1792   // which can at most reach to specified pc.
1793   bool ShouldEmitVeneer(int max_reachable_pc,
1794                         int margin = kVeneerDistanceMargin);
1795   bool ShouldEmitVeneers(int margin = kVeneerDistanceMargin) {
1796     return ShouldEmitVeneer(unresolved_branches_first_limit(), margin);
1797   }
1798 
1799   // The maximum code size generated for a veneer. Currently one branch
1800   // instruction. This is for code size checking purposes, and can be extended
1801   // in the future for example if we decide to add nops between the veneers.
1802   static const int kMaxVeneerCodeSize = 1 * kInstructionSize;
1803 
1804   void RecordVeneerPool(int location_offset, int size);
1805   // Emits veneers for branches that are approaching their maximum range.
1806   // If need_protection is true, the veneers are protected by a branch jumping
1807   // over the code.
1808   void EmitVeneers(bool force_emit, bool need_protection,
1809                    int margin = kVeneerDistanceMargin);
EmitVeneersGuard()1810   void EmitVeneersGuard() { EmitPoolGuard(); }
1811   // Checks whether veneers need to be emitted at this point.
1812   // If force_emit is set, a veneer is generated for *all* unresolved branches.
1813   void CheckVeneerPool(bool force_emit, bool require_jump,
1814                        int margin = kVeneerDistanceMargin);
1815 
1816   class BlockPoolsScope {
1817    public:
BlockPoolsScope(Assembler * assem)1818     explicit BlockPoolsScope(Assembler* assem) : assem_(assem) {
1819       assem_->StartBlockPools();
1820     }
~BlockPoolsScope()1821     ~BlockPoolsScope() {
1822       assem_->EndBlockPools();
1823     }
1824 
1825    private:
1826     Assembler* assem_;
1827 
1828     DISALLOW_IMPLICIT_CONSTRUCTORS(BlockPoolsScope);
1829   };
1830 
1831  protected:
1832   inline const Register& AppropriateZeroRegFor(const CPURegister& reg) const;
1833 
1834   void LoadStore(const CPURegister& rt,
1835                  const MemOperand& addr,
1836                  LoadStoreOp op);
1837 
1838   void LoadStorePair(const CPURegister& rt, const CPURegister& rt2,
1839                      const MemOperand& addr, LoadStorePairOp op);
1840   static bool IsImmLSPair(int64_t offset, LSDataSize size);
1841 
1842   void Logical(const Register& rd,
1843                const Register& rn,
1844                const Operand& operand,
1845                LogicalOp op);
1846   void LogicalImmediate(const Register& rd,
1847                         const Register& rn,
1848                         unsigned n,
1849                         unsigned imm_s,
1850                         unsigned imm_r,
1851                         LogicalOp op);
1852 
1853   void ConditionalCompare(const Register& rn,
1854                           const Operand& operand,
1855                           StatusFlags nzcv,
1856                           Condition cond,
1857                           ConditionalCompareOp op);
1858   static bool IsImmConditionalCompare(int64_t immediate);
1859 
1860   void AddSubWithCarry(const Register& rd,
1861                        const Register& rn,
1862                        const Operand& operand,
1863                        FlagsUpdate S,
1864                        AddSubWithCarryOp op);
1865 
1866   // Functions for emulating operands not directly supported by the instruction
1867   // set.
1868   void EmitShift(const Register& rd,
1869                  const Register& rn,
1870                  Shift shift,
1871                  unsigned amount);
1872   void EmitExtendShift(const Register& rd,
1873                        const Register& rn,
1874                        Extend extend,
1875                        unsigned left_shift);
1876 
1877   void AddSub(const Register& rd,
1878               const Register& rn,
1879               const Operand& operand,
1880               FlagsUpdate S,
1881               AddSubOp op);
1882 
1883   static bool IsImmFP32(float imm);
1884   static bool IsImmFP64(double imm);
1885 
1886   // Find an appropriate LoadStoreOp or LoadStorePairOp for the specified
1887   // registers. Only simple loads are supported; sign- and zero-extension (such
1888   // as in LDPSW_x or LDRB_w) are not supported.
1889   static inline LoadStoreOp LoadOpFor(const CPURegister& rt);
1890   static inline LoadStorePairOp LoadPairOpFor(const CPURegister& rt,
1891                                               const CPURegister& rt2);
1892   static inline LoadStoreOp StoreOpFor(const CPURegister& rt);
1893   static inline LoadStorePairOp StorePairOpFor(const CPURegister& rt,
1894                                                const CPURegister& rt2);
1895   static inline LoadLiteralOp LoadLiteralOpFor(const CPURegister& rt);
1896 
1897   // Remove the specified branch from the unbound label link chain.
1898   // If available, a veneer for this label can be used for other branches in the
1899   // chain if the link chain cannot be fixed up without this branch.
1900   void RemoveBranchFromLabelLinkChain(Instruction* branch,
1901                                       Label* label,
1902                                       Instruction* label_veneer = NULL);
1903 
1904  private:
1905   // Instruction helpers.
1906   void MoveWide(const Register& rd,
1907                 uint64_t imm,
1908                 int shift,
1909                 MoveWideImmediateOp mov_op);
1910   void DataProcShiftedRegister(const Register& rd,
1911                                const Register& rn,
1912                                const Operand& operand,
1913                                FlagsUpdate S,
1914                                Instr op);
1915   void DataProcExtendedRegister(const Register& rd,
1916                                 const Register& rn,
1917                                 const Operand& operand,
1918                                 FlagsUpdate S,
1919                                 Instr op);
1920   void ConditionalSelect(const Register& rd,
1921                          const Register& rn,
1922                          const Register& rm,
1923                          Condition cond,
1924                          ConditionalSelectOp op);
1925   void DataProcessing1Source(const Register& rd,
1926                              const Register& rn,
1927                              DataProcessing1SourceOp op);
1928   void DataProcessing3Source(const Register& rd,
1929                              const Register& rn,
1930                              const Register& rm,
1931                              const Register& ra,
1932                              DataProcessing3SourceOp op);
1933   void FPDataProcessing1Source(const FPRegister& fd,
1934                                const FPRegister& fn,
1935                                FPDataProcessing1SourceOp op);
1936   void FPDataProcessing2Source(const FPRegister& fd,
1937                                const FPRegister& fn,
1938                                const FPRegister& fm,
1939                                FPDataProcessing2SourceOp op);
1940   void FPDataProcessing3Source(const FPRegister& fd,
1941                                const FPRegister& fn,
1942                                const FPRegister& fm,
1943                                const FPRegister& fa,
1944                                FPDataProcessing3SourceOp op);
1945 
1946   // Label helpers.
1947 
1948   // Return an offset for a label-referencing instruction, typically a branch.
1949   int LinkAndGetByteOffsetTo(Label* label);
1950 
1951   // This is the same as LinkAndGetByteOffsetTo, but return an offset
1952   // suitable for fields that take instruction offsets.
1953   inline int LinkAndGetInstructionOffsetTo(Label* label);
1954 
1955   static const int kStartOfLabelLinkChain = 0;
1956 
1957   // Verify that a label's link chain is intact.
1958   void CheckLabelLinkChain(Label const * label);
1959 
1960   void RecordLiteral(int64_t imm, unsigned size);
1961 
1962   // Postpone the generation of the constant pool for the specified number of
1963   // instructions.
1964   void BlockConstPoolFor(int instructions);
1965 
1966   // Set how far from current pc the next constant pool check will be.
SetNextConstPoolCheckIn(int instructions)1967   void SetNextConstPoolCheckIn(int instructions) {
1968     next_constant_pool_check_ = pc_offset() + instructions * kInstructionSize;
1969   }
1970 
1971   // Emit the instruction at pc_.
Emit(Instr instruction)1972   void Emit(Instr instruction) {
1973     STATIC_ASSERT(sizeof(*pc_) == 1);
1974     STATIC_ASSERT(sizeof(instruction) == kInstructionSize);
1975     DCHECK((pc_ + sizeof(instruction)) <= (buffer_ + buffer_size_));
1976 
1977     memcpy(pc_, &instruction, sizeof(instruction));
1978     pc_ += sizeof(instruction);
1979     CheckBuffer();
1980   }
1981 
1982   // Emit data inline in the instruction stream.
EmitData(void const * data,unsigned size)1983   void EmitData(void const * data, unsigned size) {
1984     DCHECK(sizeof(*pc_) == 1);
1985     DCHECK((pc_ + size) <= (buffer_ + buffer_size_));
1986 
1987     // TODO(all): Somehow register we have some data here. Then we can
1988     // disassemble it correctly.
1989     memcpy(pc_, data, size);
1990     pc_ += size;
1991     CheckBuffer();
1992   }
1993 
1994   void GrowBuffer();
1995   void CheckBufferSpace();
1996   void CheckBuffer();
1997 
1998   // Pc offset of the next constant pool check.
1999   int next_constant_pool_check_;
2000 
2001   // Constant pool generation
2002   // Pools are emitted in the instruction stream. They are emitted when:
2003   //  * the distance to the first use is above a pre-defined distance or
2004   //  * the numbers of entries in the pool is above a pre-defined size or
2005   //  * code generation is finished
2006   // If a pool needs to be emitted before code generation is finished a branch
2007   // over the emitted pool will be inserted.
2008 
2009   // Constants in the pool may be addresses of functions that gets relocated;
2010   // if so, a relocation info entry is associated to the constant pool entry.
2011 
2012   // Repeated checking whether the constant pool should be emitted is rather
2013   // expensive. By default we only check again once a number of instructions
2014   // has been generated. That also means that the sizing of the buffers is not
2015   // an exact science, and that we rely on some slop to not overrun buffers.
2016   static const int kCheckConstPoolInterval = 128;
2017 
2018   // Distance to first use after a which a pool will be emitted. Pool entries
2019   // are accessed with pc relative load therefore this cannot be more than
2020   // 1 * MB. Since constant pool emission checks are interval based this value
2021   // is an approximation.
2022   static const int kApproxMaxDistToConstPool = 64 * KB;
2023 
2024   // Number of pool entries after which a pool will be emitted. Since constant
2025   // pool emission checks are interval based this value is an approximation.
2026   static const int kApproxMaxPoolEntryCount = 512;
2027 
2028   // Emission of the constant pool may be blocked in some code sequences.
2029   int const_pool_blocked_nesting_;  // Block emission if this is not zero.
2030   int no_const_pool_before_;  // Block emission before this pc offset.
2031 
2032   // Emission of the veneer pools may be blocked in some code sequences.
2033   int veneer_pool_blocked_nesting_;  // Block emission if this is not zero.
2034 
2035   // Relocation info generation
2036   // Each relocation is encoded as a variable size value
2037   static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
2038   RelocInfoWriter reloc_info_writer;
2039   // Internal reference positions, required for (potential) patching in
2040   // GrowBuffer(); contains only those internal references whose labels
2041   // are already bound.
2042   std::deque<int> internal_reference_positions_;
2043 
2044   // Relocation info records are also used during code generation as temporary
2045   // containers for constants and code target addresses until they are emitted
2046   // to the constant pool. These pending relocation info records are temporarily
2047   // stored in a separate buffer until a constant pool is emitted.
2048   // If every instruction in a long sequence is accessing the pool, we need one
2049   // pending relocation entry per instruction.
2050 
2051   // The pending constant pool.
2052   ConstPool constpool_;
2053 
2054   // Relocation for a type-recording IC has the AST id added to it.  This
2055   // member variable is a way to pass the information from the call site to
2056   // the relocation info.
2057   TypeFeedbackId recorded_ast_id_;
2058 
2059   inline TypeFeedbackId RecordedAstId();
2060   inline void ClearRecordedAstId();
2061 
2062  protected:
2063   // Record the AST id of the CallIC being compiled, so that it can be placed
2064   // in the relocation information.
SetRecordedAstId(TypeFeedbackId ast_id)2065   void SetRecordedAstId(TypeFeedbackId ast_id) {
2066     DCHECK(recorded_ast_id_.IsNone());
2067     recorded_ast_id_ = ast_id;
2068   }
2069 
2070   // Code generation
2071   // The relocation writer's position is at least kGap bytes below the end of
2072   // the generated instructions. This is so that multi-instruction sequences do
2073   // not have to check for overflow. The same is true for writes of large
2074   // relocation info entries, and debug strings encoded in the instruction
2075   // stream.
2076   static const int kGap = 128;
2077 
2078  public:
2079   class FarBranchInfo {
2080    public:
FarBranchInfo(int offset,Label * label)2081     FarBranchInfo(int offset, Label* label)
2082         : pc_offset_(offset), label_(label) {}
2083     // Offset of the branch in the code generation buffer.
2084     int pc_offset_;
2085     // The label branched to.
2086     Label* label_;
2087   };
2088 
2089  protected:
2090   // Information about unresolved (forward) branches.
2091   // The Assembler is only allowed to delete out-of-date information from here
2092   // after a label is bound. The MacroAssembler uses this information to
2093   // generate veneers.
2094   //
2095   // The second member gives information about the unresolved branch. The first
2096   // member of the pair is the maximum offset that the branch can reach in the
2097   // buffer. The map is sorted according to this reachable offset, allowing to
2098   // easily check when veneers need to be emitted.
2099   // Note that the maximum reachable offset (first member of the pairs) should
2100   // always be positive but has the same type as the return value for
2101   // pc_offset() for convenience.
2102   std::multimap<int, FarBranchInfo> unresolved_branches_;
2103 
2104   // We generate a veneer for a branch if we reach within this distance of the
2105   // limit of the range.
2106   static const int kVeneerDistanceMargin = 1 * KB;
2107   // The factor of 2 is a finger in the air guess. With a default margin of
2108   // 1KB, that leaves us an addional 256 instructions to avoid generating a
2109   // protective branch.
2110   static const int kVeneerNoProtectionFactor = 2;
2111   static const int kVeneerDistanceCheckMargin =
2112     kVeneerNoProtectionFactor * kVeneerDistanceMargin;
unresolved_branches_first_limit()2113   int unresolved_branches_first_limit() const {
2114     DCHECK(!unresolved_branches_.empty());
2115     return unresolved_branches_.begin()->first;
2116   }
2117   // This is similar to next_constant_pool_check_ and helps reduce the overhead
2118   // of checking for veneer pools.
2119   // It is maintained to the closest unresolved branch limit minus the maximum
2120   // veneer margin (or kMaxInt if there are no unresolved branches).
2121   int next_veneer_pool_check_;
2122 
2123  private:
2124   // If a veneer is emitted for a branch instruction, that instruction must be
2125   // removed from the associated label's link chain so that the assembler does
2126   // not later attempt (likely unsuccessfully) to patch it to branch directly to
2127   // the label.
2128   void DeleteUnresolvedBranchInfoForLabel(Label* label);
2129   // This function deletes the information related to the label by traversing
2130   // the label chain, and for each PC-relative instruction in the chain checking
2131   // if pending unresolved information exists. Its complexity is proportional to
2132   // the length of the label chain.
2133   void DeleteUnresolvedBranchInfoForLabelTraverse(Label* label);
2134 
2135  private:
2136   PositionsRecorder positions_recorder_;
2137   friend class PositionsRecorder;
2138   friend class EnsureSpace;
2139   friend class ConstPool;
2140 };
2141 
2142 class PatchingAssembler : public Assembler {
2143  public:
2144   // Create an Assembler with a buffer starting at 'start'.
2145   // The buffer size is
2146   //   size of instructions to patch + kGap
2147   // Where kGap is the distance from which the Assembler tries to grow the
2148   // buffer.
2149   // If more or fewer instructions than expected are generated or if some
2150   // relocation information takes space in the buffer, the PatchingAssembler
2151   // will crash trying to grow the buffer.
PatchingAssembler(Isolate * isolate,Instruction * start,unsigned count)2152   PatchingAssembler(Isolate* isolate, Instruction* start, unsigned count)
2153       : Assembler(isolate, reinterpret_cast<byte*>(start),
2154                   count * kInstructionSize + kGap) {
2155     StartBlockPools();
2156   }
2157 
PatchingAssembler(Isolate * isolate,byte * start,unsigned count)2158   PatchingAssembler(Isolate* isolate, byte* start, unsigned count)
2159       : Assembler(isolate, start, count * kInstructionSize + kGap) {
2160     // Block constant pool emission.
2161     StartBlockPools();
2162   }
2163 
~PatchingAssembler()2164   ~PatchingAssembler() {
2165     // Const pool should still be blocked.
2166     DCHECK(is_const_pool_blocked());
2167     EndBlockPools();
2168     // Verify we have generated the number of instruction we expected.
2169     DCHECK((pc_offset() + kGap) == buffer_size_);
2170     // Verify no relocation information has been emitted.
2171     DCHECK(IsConstPoolEmpty());
2172     // Flush the Instruction cache.
2173     size_t length = buffer_size_ - kGap;
2174     Assembler::FlushICache(isolate(), buffer_, length);
2175   }
2176 
2177   // See definition of PatchAdrFar() for details.
2178   static const int kAdrFarPatchableNNops = 2;
2179   static const int kAdrFarPatchableNInstrs = kAdrFarPatchableNNops + 2;
2180   void PatchAdrFar(int64_t target_offset);
2181 };
2182 
2183 
2184 class EnsureSpace BASE_EMBEDDED {
2185  public:
EnsureSpace(Assembler * assembler)2186   explicit EnsureSpace(Assembler* assembler) {
2187     assembler->CheckBufferSpace();
2188   }
2189 };
2190 
2191 }  // namespace internal
2192 }  // namespace v8
2193 
2194 #endif  // V8_ARM64_ASSEMBLER_ARM64_H_
2195