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