Home | History | Annotate | Download | only in arm64
      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 
     93   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.
    127   bool is(const CPURegister& other) const { return Is(other); }
    128   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 {
    137   static Register Create(int code, int size) {
    138     return Register(CPURegister::Create(code, size, CPURegister::kRegister));
    139   }
    140 
    141   Register() {
    142     reg_code = 0;
    143     reg_size = 0;
    144     reg_type = CPURegister::kNoRegister;
    145   }
    146 
    147   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 
    154   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 
    161   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);
    175   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 
    192   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 
    212   static FPRegister Create(int code, int size) {
    213     return FPRegister(
    214         CPURegister::Create(code, size, CPURegister::kFPRegister));
    215   }
    216 
    217   FPRegister() {
    218     reg_code = 0;
    219     reg_size = 0;
    220     reg_type = CPURegister::kNoRegister;
    221   }
    222 
    223   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 
    230   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 
    237   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
    253   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 
    397   CPURegList(CPURegister::RegisterType type, int size, RegList list)
    398       : list_(list), size_(size), type_(type) {
    399     DCHECK(IsValid());
    400   }
    401 
    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 
    415   CPURegister::RegisterType type() const {
    416     DCHECK(IsValid());
    417     return type_;
    418   }
    419 
    420   RegList list() const {
    421     DCHECK(IsValid());
    422     return list_;
    423   }
    424 
    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 
    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 
    488   int Count() const {
    489     DCHECK(IsValid());
    490     return CountSetBits(list_, kRegListSizeInBits);
    491   }
    492 
    493   int RegisterSizeInBits() const {
    494     DCHECK(IsValid());
    495     return size_;
    496   }
    497 
    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 
    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 
    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 
    556   int64_t value() const { return value_; }
    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 
    655   const Register& base() const { return base_; }
    656   const Register& regoffset() const { return regoffset_; }
    657   int64_t offset() const { return offset_; }
    658   AddrMode addrmode() const { return addrmode_; }
    659   Shift shift() const { return shift_; }
    660   Extend extend() const { return extend_; }
    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:
    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);
    699   int EntryCount() const {
    700     return shared_entries_count + static_cast<int>(unique_entries_.size());
    701   }
    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 
    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
    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.
    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.
    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.
    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 
    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.
    923   void StartBlockPools() {
    924     StartBlockConstPool();
    925     StartBlockVeneerPool();
    926   }
    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.
   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.
   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.
   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.
   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.
   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.
   1174   void sxtb(const Register& rd, const Register& rn) {
   1175     sbfm(rd, rn, 0, 7);
   1176   }
   1177 
   1178   // Signed extend halfword.
   1179   void sxth(const Register& rd, const Register& rn) {
   1180     sbfm(rd, rn, 0, 15);
   1181   }
   1182 
   1183   // Signed extend word.
   1184   void sxtw(const Register& rd, const Register& rn) {
   1185     sbfm(rd, rn, 0, 31);
   1186   }
   1187 
   1188   // Ubfm aliases.
   1189   // Logical shift left.
   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.
   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.
   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.
   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.
   1217   void uxtb(const Register& rd, const Register& rn) {
   1218     ubfm(rd, rn, 0, 7);
   1219   }
   1220 
   1221   // Unsigned extend halfword.
   1222   void uxth(const Register& rd, const Register& rn) {
   1223     ubfm(rd, rn, 0, 15);
   1224   }
   1225 
   1226   // Unsigned extend word.
   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.
   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.
   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 
   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.
   1656   void dci(Instr raw_inst) { Emit(raw_inst); }
   1657 
   1658   // Emit 8 bits of data in the instruction stream.
   1659   void dc8(uint8_t data) { EmitData(&data, sizeof(data)); }
   1660 
   1661   // Emit 32 bits of data in the instruction stream.
   1662   void dc32(uint32_t data) { EmitData(&data, sizeof(data)); }
   1663 
   1664   // Emit 64 bits of data in the instruction stream.
   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.
   1681   void dd(uint32_t data) { dc32(data); }
   1682   void db(uint8_t data) { dc8(data); }
   1683   void dq(uint64_t data) { dc64(data); }
   1684   void dp(uintptr_t data) { dc64(data); }
   1685 
   1686   // Code generation helpers --------------------------------------------------
   1687 
   1688   bool IsConstPoolEmpty() const { return constpool_.IsEmpty(); }
   1689 
   1690   Instruction* pc() const { return Instruction::Cast(pc_); }
   1691 
   1692   Instruction* InstructionAt(ptrdiff_t offset) const {
   1693     return reinterpret_cast<Instruction*>(buffer_ + offset);
   1694   }
   1695 
   1696   ptrdiff_t InstructionOffset(Instruction* instr) const {
   1697     return reinterpret_cast<byte*>(instr) - buffer_;
   1698   }
   1699 
   1700   // Register encoding.
   1701   static Instr Rd(CPURegister rd) {
   1702     DCHECK(rd.code() != kSPRegInternalCode);
   1703     return rd.code() << Rd_offset;
   1704   }
   1705 
   1706   static Instr Rn(CPURegister rn) {
   1707     DCHECK(rn.code() != kSPRegInternalCode);
   1708     return rn.code() << Rn_offset;
   1709   }
   1710 
   1711   static Instr Rm(CPURegister rm) {
   1712     DCHECK(rm.code() != kSPRegInternalCode);
   1713     return rm.code() << Rm_offset;
   1714   }
   1715 
   1716   static Instr Ra(CPURegister ra) {
   1717     DCHECK(ra.code() != kSPRegInternalCode);
   1718     return ra.code() << Ra_offset;
   1719   }
   1720 
   1721   static Instr Rt(CPURegister rt) {
   1722     DCHECK(rt.code() != kSPRegInternalCode);
   1723     return rt.code() << Rt_offset;
   1724   }
   1725 
   1726   static Instr Rt2(CPURegister rt2) {
   1727     DCHECK(rt2.code() != kSPRegInternalCode);
   1728     return rt2.code() << Rt2_offset;
   1729   }
   1730 
   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.
   1738   static Instr RdSP(Register rd) {
   1739     DCHECK(!rd.IsZero());
   1740     return (rd.code() & kRegCodeMask) << Rd_offset;
   1741   }
   1742 
   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:
   1816     explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) {
   1817       assem_->StartBlockConstPool();
   1818     }
   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 
   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);
   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:
   1866     explicit BlockPoolsScope(Assembler* assem) : assem_(assem) {
   1867       assem_->StartBlockPools();
   1868     }
   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.
   2015   void SetNextConstPoolCheckIn(int instructions) {
   2016     next_constant_pool_check_ = pc_offset() + instructions * kInstructionSize;
   2017   }
   2018 
   2019   // Emit the instruction at pc_.
   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.
   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.
   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:
   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;
   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.
   2198   PatchingAssembler(Isolate* isolate, Instruction* start, unsigned count)
   2199       : Assembler(isolate, reinterpret_cast<byte*>(start),
   2200                   count * kInstructionSize + kGap) {
   2201     StartBlockPools();
   2202   }
   2203 
   2204   PatchingAssembler(Isolate* isolate, byte* start, unsigned count)
   2205       : Assembler(isolate, start, count * kInstructionSize + kGap) {
   2206     // Block constant pool emission.
   2207     StartBlockPools();
   2208   }
   2209 
   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:
   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