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