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