Home | History | Annotate | Download | only in arm
      1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
      2 // All Rights Reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions
      6 // are met:
      7 //
      8 // - Redistributions of source code must retain the above copyright notice,
      9 // this list of conditions and the following disclaimer.
     10 //
     11 // - Redistribution in binary form must reproduce the above copyright
     12 // notice, this list of conditions and the following disclaimer in the
     13 // documentation and/or other materials provided with the
     14 // distribution.
     15 //
     16 // - Neither the name of Sun Microsystems or the names of contributors may
     17 // be used to endorse or promote products derived from this software without
     18 // specific prior written permission.
     19 //
     20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     31 // OF THE POSSIBILITY OF SUCH DAMAGE.
     32 
     33 // The original source code covered by the above license above has been
     34 // modified significantly by Google Inc.
     35 // Copyright 2012 the V8 project authors. All rights reserved.
     36 
     37 // A light-weight ARM Assembler
     38 // Generates user mode instructions for the ARM architecture up to version 5
     39 
     40 #ifndef V8_ARM_ASSEMBLER_ARM_H_
     41 #define V8_ARM_ASSEMBLER_ARM_H_
     42 
     43 #include <stdio.h>
     44 #include <vector>
     45 
     46 #include "src/arm/constants-arm.h"
     47 #include "src/assembler.h"
     48 
     49 namespace v8 {
     50 namespace internal {
     51 
     52 // clang-format off
     53 #define GENERAL_REGISTERS(V)                              \
     54   V(r0)  V(r1)  V(r2)  V(r3)  V(r4)  V(r5)  V(r6)  V(r7)  \
     55   V(r8)  V(r9)  V(r10) V(fp)  V(ip)  V(sp)  V(lr)  V(pc)
     56 
     57 #define ALLOCATABLE_GENERAL_REGISTERS(V) \
     58   V(r0)  V(r1)  V(r2)  V(r3)  V(r4)  V(r5)  V(r6)  V(r7)  V(r8)
     59 
     60 #define FLOAT_REGISTERS(V)                                \
     61   V(s0)  V(s1)  V(s2)  V(s3)  V(s4)  V(s5)  V(s6)  V(s7)  \
     62   V(s8)  V(s9)  V(s10) V(s11) V(s12) V(s13) V(s14) V(s15) \
     63   V(s16) V(s17) V(s18) V(s19) V(s20) V(s21) V(s22) V(s23) \
     64   V(s24) V(s25) V(s26) V(s27) V(s28) V(s29) V(s30) V(s31)
     65 
     66 #define DOUBLE_REGISTERS(V)                               \
     67   V(d0)  V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)  \
     68   V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d13) V(d14) V(d15) \
     69   V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \
     70   V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
     71 
     72 #define SIMD128_REGISTERS(V)                              \
     73   V(q0)  V(q1)  V(q2)  V(q3)  V(q4)  V(q5)  V(q6)  V(q7)  \
     74   V(q8)  V(q9)  V(q10) V(q11) V(q12) V(q13) V(q14) V(q15)
     75 
     76 #define ALLOCATABLE_DOUBLE_REGISTERS(V)                   \
     77   V(d0)  V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)  \
     78   V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d13)               \
     79   V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \
     80   V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
     81 
     82 #define ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(V)          \
     83   V(d0)  V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)  \
     84   V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d13)               \
     85 // clang-format on
     86 
     87 // CPU Registers.
     88 //
     89 // 1) We would prefer to use an enum, but enum values are assignment-
     90 // compatible with int, which has caused code-generation bugs.
     91 //
     92 // 2) We would prefer to use a class instead of a struct but we don't like
     93 // the register initialization to depend on the particular initialization
     94 // order (which appears to be different on OS X, Linux, and Windows for the
     95 // installed versions of C++ we tried). Using a struct permits C-style
     96 // "initialization". Also, the Register objects cannot be const as this
     97 // forces initialization stubs in MSVC, making us dependent on initialization
     98 // order.
     99 //
    100 // 3) By not using an enum, we are possibly preventing the compiler from
    101 // doing certain constant folds, which may significantly reduce the
    102 // code generated for some assembly instructions (because they boil down
    103 // to a few constants). If this is a problem, we could change the code
    104 // such that we use an enum in optimized mode, and the struct in debug
    105 // mode. This way we get the compile-time error checking in debug mode
    106 // and best performance in optimized code.
    107 
    108 struct Register {
    109   enum Code {
    110 #define REGISTER_CODE(R) kCode_##R,
    111     GENERAL_REGISTERS(REGISTER_CODE)
    112 #undef REGISTER_CODE
    113         kAfterLast,
    114     kCode_no_reg = -1
    115   };
    116 
    117   static const int kNumRegisters = Code::kAfterLast;
    118 
    119   static Register from_code(int code) {
    120     DCHECK(code >= 0);
    121     DCHECK(code < kNumRegisters);
    122     Register r = {code};
    123     return r;
    124   }
    125   bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
    126   bool is(Register reg) const { return reg_code == reg.reg_code; }
    127   int code() const {
    128     DCHECK(is_valid());
    129     return reg_code;
    130   }
    131   int bit() const {
    132     DCHECK(is_valid());
    133     return 1 << reg_code;
    134   }
    135   void set_code(int code) {
    136     reg_code = code;
    137     DCHECK(is_valid());
    138   }
    139 
    140   // Unfortunately we can't make this private in a struct.
    141   int reg_code;
    142 };
    143 
    144 // r7: context register
    145 // r8: constant pool pointer register if FLAG_enable_embedded_constant_pool.
    146 // r9: lithium scratch
    147 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
    148 GENERAL_REGISTERS(DECLARE_REGISTER)
    149 #undef DECLARE_REGISTER
    150 const Register no_reg = {Register::kCode_no_reg};
    151 
    152 static const bool kSimpleFPAliasing = false;
    153 static const bool kSimdMaskRegisters = false;
    154 
    155 // Single word VFP register.
    156 struct SwVfpRegister {
    157   enum Code {
    158 #define REGISTER_CODE(R) kCode_##R,
    159     FLOAT_REGISTERS(REGISTER_CODE)
    160 #undef REGISTER_CODE
    161         kAfterLast,
    162     kCode_no_reg = -1
    163   };
    164 
    165   static const int kMaxNumRegisters = Code::kAfterLast;
    166 
    167   static const int kSizeInBytes = 4;
    168 
    169   bool is_valid() const { return 0 <= reg_code && reg_code < 32; }
    170   bool is(SwVfpRegister reg) const { return reg_code == reg.reg_code; }
    171   int code() const {
    172     DCHECK(is_valid());
    173     return reg_code;
    174   }
    175   int bit() const {
    176     DCHECK(is_valid());
    177     return 1 << reg_code;
    178   }
    179   static SwVfpRegister from_code(int code) {
    180     SwVfpRegister r = {code};
    181     return r;
    182   }
    183   void split_code(int* vm, int* m) const {
    184     DCHECK(is_valid());
    185     *m = reg_code & 0x1;
    186     *vm = reg_code >> 1;
    187   }
    188 
    189   int reg_code;
    190 };
    191 
    192 typedef SwVfpRegister FloatRegister;
    193 
    194 // Double word VFP register.
    195 struct DwVfpRegister {
    196   enum Code {
    197 #define REGISTER_CODE(R) kCode_##R,
    198     DOUBLE_REGISTERS(REGISTER_CODE)
    199 #undef REGISTER_CODE
    200         kAfterLast,
    201     kCode_no_reg = -1
    202   };
    203 
    204   static const int kMaxNumRegisters = Code::kAfterLast;
    205 
    206   inline static int NumRegisters();
    207 
    208   // A few double registers are reserved: one as a scratch register and one to
    209   // hold 0.0, that does not fit in the immediate field of vmov instructions.
    210   //  d14: 0.0
    211   //  d15: scratch register.
    212   static const int kSizeInBytes = 8;
    213 
    214   bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
    215   bool is(DwVfpRegister reg) const { return reg_code == reg.reg_code; }
    216   int code() const {
    217     DCHECK(is_valid());
    218     return reg_code;
    219   }
    220   int bit() const {
    221     DCHECK(is_valid());
    222     return 1 << reg_code;
    223   }
    224 
    225   static DwVfpRegister from_code(int code) {
    226     DwVfpRegister r = {code};
    227     return r;
    228   }
    229   void split_code(int* vm, int* m) const {
    230     DCHECK(is_valid());
    231     *m = (reg_code & 0x10) >> 4;
    232     *vm = reg_code & 0x0F;
    233   }
    234 
    235   int reg_code;
    236 };
    237 
    238 
    239 typedef DwVfpRegister DoubleRegister;
    240 
    241 
    242 // Double word VFP register d0-15.
    243 struct LowDwVfpRegister {
    244  public:
    245   static const int kMaxNumLowRegisters = 16;
    246   operator DwVfpRegister() const {
    247     DwVfpRegister r = { reg_code };
    248     return r;
    249   }
    250   static LowDwVfpRegister from_code(int code) {
    251     LowDwVfpRegister r = { code };
    252     return r;
    253   }
    254 
    255   bool is_valid() const {
    256     return 0 <= reg_code && reg_code < kMaxNumLowRegisters;
    257   }
    258   bool is(DwVfpRegister reg) const { return reg_code == reg.reg_code; }
    259   bool is(LowDwVfpRegister reg) const { return reg_code == reg.reg_code; }
    260   int code() const {
    261     DCHECK(is_valid());
    262     return reg_code;
    263   }
    264   SwVfpRegister low() const {
    265     SwVfpRegister reg;
    266     reg.reg_code = reg_code * 2;
    267 
    268     DCHECK(reg.is_valid());
    269     return reg;
    270   }
    271   SwVfpRegister high() const {
    272     SwVfpRegister reg;
    273     reg.reg_code = (reg_code * 2) + 1;
    274 
    275     DCHECK(reg.is_valid());
    276     return reg;
    277   }
    278 
    279   int reg_code;
    280 };
    281 
    282 
    283 // Quad word NEON register.
    284 struct QwNeonRegister {
    285   static const int kMaxNumRegisters = 16;
    286 
    287   static QwNeonRegister from_code(int code) {
    288     QwNeonRegister r = { code };
    289     return r;
    290   }
    291 
    292   bool is_valid() const {
    293     return (0 <= reg_code) && (reg_code < kMaxNumRegisters);
    294   }
    295   bool is(QwNeonRegister reg) const { return reg_code == reg.reg_code; }
    296   int code() const {
    297     DCHECK(is_valid());
    298     return reg_code;
    299   }
    300   void split_code(int* vm, int* m) const {
    301     DCHECK(is_valid());
    302     int encoded_code = reg_code << 1;
    303     *m = (encoded_code & 0x10) >> 4;
    304     *vm = encoded_code & 0x0F;
    305   }
    306   DwVfpRegister low() const {
    307     DwVfpRegister reg;
    308     reg.reg_code = reg_code * 2;
    309 
    310     DCHECK(reg.is_valid());
    311     return reg;
    312   }
    313   DwVfpRegister high() const {
    314     DwVfpRegister reg;
    315     reg.reg_code = reg_code * 2 + 1;
    316 
    317     DCHECK(reg.is_valid());
    318     return reg;
    319   }
    320 
    321   int reg_code;
    322 };
    323 
    324 
    325 typedef QwNeonRegister QuadRegister;
    326 
    327 typedef QwNeonRegister Simd128Register;
    328 
    329 // Support for the VFP registers s0 to s31 (d0 to d15).
    330 // Note that "s(N):s(N+1)" is the same as "d(N/2)".
    331 const SwVfpRegister s0  = {  0 };
    332 const SwVfpRegister s1  = {  1 };
    333 const SwVfpRegister s2  = {  2 };
    334 const SwVfpRegister s3  = {  3 };
    335 const SwVfpRegister s4  = {  4 };
    336 const SwVfpRegister s5  = {  5 };
    337 const SwVfpRegister s6  = {  6 };
    338 const SwVfpRegister s7  = {  7 };
    339 const SwVfpRegister s8  = {  8 };
    340 const SwVfpRegister s9  = {  9 };
    341 const SwVfpRegister s10 = { 10 };
    342 const SwVfpRegister s11 = { 11 };
    343 const SwVfpRegister s12 = { 12 };
    344 const SwVfpRegister s13 = { 13 };
    345 const SwVfpRegister s14 = { 14 };
    346 const SwVfpRegister s15 = { 15 };
    347 const SwVfpRegister s16 = { 16 };
    348 const SwVfpRegister s17 = { 17 };
    349 const SwVfpRegister s18 = { 18 };
    350 const SwVfpRegister s19 = { 19 };
    351 const SwVfpRegister s20 = { 20 };
    352 const SwVfpRegister s21 = { 21 };
    353 const SwVfpRegister s22 = { 22 };
    354 const SwVfpRegister s23 = { 23 };
    355 const SwVfpRegister s24 = { 24 };
    356 const SwVfpRegister s25 = { 25 };
    357 const SwVfpRegister s26 = { 26 };
    358 const SwVfpRegister s27 = { 27 };
    359 const SwVfpRegister s28 = { 28 };
    360 const SwVfpRegister s29 = { 29 };
    361 const SwVfpRegister s30 = { 30 };
    362 const SwVfpRegister s31 = { 31 };
    363 
    364 const DwVfpRegister no_dreg = { -1 };
    365 const LowDwVfpRegister d0 = { 0 };
    366 const LowDwVfpRegister d1 = { 1 };
    367 const LowDwVfpRegister d2 = { 2 };
    368 const LowDwVfpRegister d3 = { 3 };
    369 const LowDwVfpRegister d4 = { 4 };
    370 const LowDwVfpRegister d5 = { 5 };
    371 const LowDwVfpRegister d6 = { 6 };
    372 const LowDwVfpRegister d7 = { 7 };
    373 const LowDwVfpRegister d8 = { 8 };
    374 const LowDwVfpRegister d9 = { 9 };
    375 const LowDwVfpRegister d10 = { 10 };
    376 const LowDwVfpRegister d11 = { 11 };
    377 const LowDwVfpRegister d12 = { 12 };
    378 const LowDwVfpRegister d13 = { 13 };
    379 const LowDwVfpRegister d14 = { 14 };
    380 const LowDwVfpRegister d15 = { 15 };
    381 const DwVfpRegister d16 = { 16 };
    382 const DwVfpRegister d17 = { 17 };
    383 const DwVfpRegister d18 = { 18 };
    384 const DwVfpRegister d19 = { 19 };
    385 const DwVfpRegister d20 = { 20 };
    386 const DwVfpRegister d21 = { 21 };
    387 const DwVfpRegister d22 = { 22 };
    388 const DwVfpRegister d23 = { 23 };
    389 const DwVfpRegister d24 = { 24 };
    390 const DwVfpRegister d25 = { 25 };
    391 const DwVfpRegister d26 = { 26 };
    392 const DwVfpRegister d27 = { 27 };
    393 const DwVfpRegister d28 = { 28 };
    394 const DwVfpRegister d29 = { 29 };
    395 const DwVfpRegister d30 = { 30 };
    396 const DwVfpRegister d31 = { 31 };
    397 
    398 const QwNeonRegister q0  = {  0 };
    399 const QwNeonRegister q1  = {  1 };
    400 const QwNeonRegister q2  = {  2 };
    401 const QwNeonRegister q3  = {  3 };
    402 const QwNeonRegister q4  = {  4 };
    403 const QwNeonRegister q5  = {  5 };
    404 const QwNeonRegister q6  = {  6 };
    405 const QwNeonRegister q7  = {  7 };
    406 const QwNeonRegister q8  = {  8 };
    407 const QwNeonRegister q9  = {  9 };
    408 const QwNeonRegister q10 = { 10 };
    409 const QwNeonRegister q11 = { 11 };
    410 const QwNeonRegister q12 = { 12 };
    411 const QwNeonRegister q13 = { 13 };
    412 const QwNeonRegister q14 = { 14 };
    413 const QwNeonRegister q15 = { 15 };
    414 
    415 
    416 // Aliases for double registers.  Defined using #define instead of
    417 // "static const DwVfpRegister&" because Clang complains otherwise when a
    418 // compilation unit that includes this header doesn't use the variables.
    419 #define kFirstCalleeSavedDoubleReg d8
    420 #define kLastCalleeSavedDoubleReg d15
    421 // kDoubleRegZero and kScratchDoubleReg must pair to form kScratchQuadReg.
    422 #define kDoubleRegZero d14
    423 #define kScratchDoubleReg d15
    424 // After using kScratchQuadReg, kDoubleRegZero must be reset to 0.
    425 #define kScratchQuadReg q7
    426 
    427 // Coprocessor register
    428 struct CRegister {
    429   bool is_valid() const { return 0 <= reg_code && reg_code < 16; }
    430   bool is(CRegister creg) const { return reg_code == creg.reg_code; }
    431   int code() const {
    432     DCHECK(is_valid());
    433     return reg_code;
    434   }
    435   int bit() const {
    436     DCHECK(is_valid());
    437     return 1 << reg_code;
    438   }
    439 
    440   // Unfortunately we can't make this private in a struct.
    441   int reg_code;
    442 };
    443 
    444 
    445 const CRegister no_creg = { -1 };
    446 
    447 const CRegister cr0  = {  0 };
    448 const CRegister cr1  = {  1 };
    449 const CRegister cr2  = {  2 };
    450 const CRegister cr3  = {  3 };
    451 const CRegister cr4  = {  4 };
    452 const CRegister cr5  = {  5 };
    453 const CRegister cr6  = {  6 };
    454 const CRegister cr7  = {  7 };
    455 const CRegister cr8  = {  8 };
    456 const CRegister cr9  = {  9 };
    457 const CRegister cr10 = { 10 };
    458 const CRegister cr11 = { 11 };
    459 const CRegister cr12 = { 12 };
    460 const CRegister cr13 = { 13 };
    461 const CRegister cr14 = { 14 };
    462 const CRegister cr15 = { 15 };
    463 
    464 
    465 // Coprocessor number
    466 enum Coprocessor {
    467   p0  = 0,
    468   p1  = 1,
    469   p2  = 2,
    470   p3  = 3,
    471   p4  = 4,
    472   p5  = 5,
    473   p6  = 6,
    474   p7  = 7,
    475   p8  = 8,
    476   p9  = 9,
    477   p10 = 10,
    478   p11 = 11,
    479   p12 = 12,
    480   p13 = 13,
    481   p14 = 14,
    482   p15 = 15
    483 };
    484 
    485 
    486 // -----------------------------------------------------------------------------
    487 // Machine instruction Operands
    488 
    489 // Class Operand represents a shifter operand in data processing instructions
    490 class Operand BASE_EMBEDDED {
    491  public:
    492   // immediate
    493   INLINE(explicit Operand(int32_t immediate,
    494          RelocInfo::Mode rmode = RelocInfo::NONE32));
    495   INLINE(static Operand Zero()) {
    496     return Operand(static_cast<int32_t>(0));
    497   }
    498   INLINE(explicit Operand(const ExternalReference& f));
    499   explicit Operand(Handle<Object> handle);
    500   INLINE(explicit Operand(Smi* value));
    501 
    502   // rm
    503   INLINE(explicit Operand(Register rm));
    504 
    505   // rm <shift_op> shift_imm
    506   explicit Operand(Register rm, ShiftOp shift_op, int shift_imm);
    507   INLINE(static Operand SmiUntag(Register rm)) {
    508     return Operand(rm, ASR, kSmiTagSize);
    509   }
    510   INLINE(static Operand PointerOffsetFromSmiKey(Register key)) {
    511     STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
    512     return Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize);
    513   }
    514   INLINE(static Operand DoubleOffsetFromSmiKey(Register key)) {
    515     STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kDoubleSizeLog2);
    516     return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize);
    517   }
    518 
    519   // rm <shift_op> rs
    520   explicit Operand(Register rm, ShiftOp shift_op, Register rs);
    521 
    522   // Return true if this is a register operand.
    523   INLINE(bool is_reg() const);
    524 
    525   // Return the number of actual instructions required to implement the given
    526   // instruction for this particular operand. This can be a single instruction,
    527   // if no load into the ip register is necessary, or anything between 2 and 4
    528   // instructions when we need to load from the constant pool (depending upon
    529   // whether the constant pool entry is in the small or extended section). If
    530   // the instruction this operand is used for is a MOV or MVN instruction the
    531   // actual instruction to use is required for this calculation. For other
    532   // instructions instr is ignored.
    533   //
    534   // The value returned is only valid as long as no entries are added to the
    535   // constant pool between this call and the actual instruction being emitted.
    536   int instructions_required(const Assembler* assembler, Instr instr = 0) const;
    537   bool must_output_reloc_info(const Assembler* assembler) const;
    538 
    539   inline int32_t immediate() const {
    540     DCHECK(!rm_.is_valid());
    541     return imm32_;
    542   }
    543 
    544   Register rm() const { return rm_; }
    545   Register rs() const { return rs_; }
    546   ShiftOp shift_op() const { return shift_op_; }
    547 
    548  private:
    549   Register rm_;
    550   Register rs_;
    551   ShiftOp shift_op_;
    552   int shift_imm_;  // valid if rm_ != no_reg && rs_ == no_reg
    553   int32_t imm32_;  // valid if rm_ == no_reg
    554   RelocInfo::Mode rmode_;
    555 
    556   friend class Assembler;
    557 };
    558 
    559 
    560 // Class MemOperand represents a memory operand in load and store instructions
    561 class MemOperand BASE_EMBEDDED {
    562  public:
    563   // [rn +/- offset]      Offset/NegOffset
    564   // [rn +/- offset]!     PreIndex/NegPreIndex
    565   // [rn], +/- offset     PostIndex/NegPostIndex
    566   // offset is any signed 32-bit value; offset is first loaded to register ip if
    567   // it does not fit the addressing mode (12-bit unsigned and sign bit)
    568   explicit MemOperand(Register rn, int32_t offset = 0, AddrMode am = Offset);
    569 
    570   // [rn +/- rm]          Offset/NegOffset
    571   // [rn +/- rm]!         PreIndex/NegPreIndex
    572   // [rn], +/- rm         PostIndex/NegPostIndex
    573   explicit MemOperand(Register rn, Register rm, AddrMode am = Offset);
    574 
    575   // [rn +/- rm <shift_op> shift_imm]      Offset/NegOffset
    576   // [rn +/- rm <shift_op> shift_imm]!     PreIndex/NegPreIndex
    577   // [rn], +/- rm <shift_op> shift_imm     PostIndex/NegPostIndex
    578   explicit MemOperand(Register rn, Register rm,
    579                       ShiftOp shift_op, int shift_imm, AddrMode am = Offset);
    580   INLINE(static MemOperand PointerAddressFromSmiKey(Register array,
    581                                                     Register key,
    582                                                     AddrMode am = Offset)) {
    583     STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
    584     return MemOperand(array, key, LSL, kPointerSizeLog2 - kSmiTagSize, am);
    585   }
    586 
    587   void set_offset(int32_t offset) {
    588       DCHECK(rm_.is(no_reg));
    589       offset_ = offset;
    590   }
    591 
    592   uint32_t offset() const {
    593       DCHECK(rm_.is(no_reg));
    594       return offset_;
    595   }
    596 
    597   Register rn() const { return rn_; }
    598   Register rm() const { return rm_; }
    599   AddrMode am() const { return am_; }
    600 
    601   bool OffsetIsUint12Encodable() const {
    602     return offset_ >= 0 ? is_uint12(offset_) : is_uint12(-offset_);
    603   }
    604 
    605  private:
    606   Register rn_;  // base
    607   Register rm_;  // register offset
    608   int32_t offset_;  // valid if rm_ == no_reg
    609   ShiftOp shift_op_;
    610   int shift_imm_;  // valid if rm_ != no_reg && rs_ == no_reg
    611   AddrMode am_;  // bits P, U, and W
    612 
    613   friend class Assembler;
    614 };
    615 
    616 
    617 // Class NeonMemOperand represents a memory operand in load and
    618 // store NEON instructions
    619 class NeonMemOperand BASE_EMBEDDED {
    620  public:
    621   // [rn {:align}]       Offset
    622   // [rn {:align}]!      PostIndex
    623   explicit NeonMemOperand(Register rn, AddrMode am = Offset, int align = 0);
    624 
    625   // [rn {:align}], rm   PostIndex
    626   explicit NeonMemOperand(Register rn, Register rm, int align = 0);
    627 
    628   Register rn() const { return rn_; }
    629   Register rm() const { return rm_; }
    630   int align() const { return align_; }
    631 
    632  private:
    633   void SetAlignment(int align);
    634 
    635   Register rn_;  // base
    636   Register rm_;  // register increment
    637   int align_;
    638 };
    639 
    640 
    641 // Class NeonListOperand represents a list of NEON registers
    642 class NeonListOperand BASE_EMBEDDED {
    643  public:
    644   explicit NeonListOperand(DoubleRegister base, int register_count = 1)
    645     : base_(base), register_count_(register_count) {}
    646   explicit NeonListOperand(QwNeonRegister q_reg)
    647     : base_(q_reg.low()), register_count_(2) {}
    648   DoubleRegister base() const { return base_; }
    649   int register_count() { return register_count_; }
    650   int length() const { return register_count_ - 1; }
    651   NeonListType type() const {
    652     switch (register_count_) {
    653       default: UNREACHABLE();
    654       // Fall through.
    655       case 1: return nlt_1;
    656       case 2: return nlt_2;
    657       case 3: return nlt_3;
    658       case 4: return nlt_4;
    659     }
    660   }
    661  private:
    662   DoubleRegister base_;
    663   int register_count_;
    664 };
    665 
    666 
    667 struct VmovIndex {
    668   unsigned char index;
    669 };
    670 const VmovIndex VmovIndexLo = { 0 };
    671 const VmovIndex VmovIndexHi = { 1 };
    672 
    673 class Assembler : public AssemblerBase {
    674  public:
    675   // Create an assembler. Instructions and relocation information are emitted
    676   // into a buffer, with the instructions starting from the beginning and the
    677   // relocation information starting from the end of the buffer. See CodeDesc
    678   // for a detailed comment on the layout (globals.h).
    679   //
    680   // If the provided buffer is NULL, the assembler allocates and grows its own
    681   // buffer, and buffer_size determines the initial buffer size. The buffer is
    682   // owned by the assembler and deallocated upon destruction of the assembler.
    683   //
    684   // If the provided buffer is not NULL, the assembler uses the provided buffer
    685   // for code generation and assumes its size to be buffer_size. If the buffer
    686   // is too small, a fatal error occurs. No deallocation of the buffer is done
    687   // upon destruction of the assembler.
    688   Assembler(Isolate* isolate, void* buffer, int buffer_size);
    689   virtual ~Assembler();
    690 
    691   // GetCode emits any pending (non-emitted) code and fills the descriptor
    692   // desc. GetCode() is idempotent; it returns the same result if no other
    693   // Assembler functions are invoked in between GetCode() calls.
    694   void GetCode(CodeDesc* desc);
    695 
    696   // Label operations & relative jumps (PPUM Appendix D)
    697   //
    698   // Takes a branch opcode (cc) and a label (L) and generates
    699   // either a backward branch or a forward branch and links it
    700   // to the label fixup chain. Usage:
    701   //
    702   // Label L;    // unbound label
    703   // j(cc, &L);  // forward branch to unbound label
    704   // bind(&L);   // bind label to the current pc
    705   // j(cc, &L);  // backward branch to bound label
    706   // bind(&L);   // illegal: a label may be bound only once
    707   //
    708   // Note: The same Label can be used for forward and backward branches
    709   // but it may be bound only once.
    710 
    711   void bind(Label* L);  // binds an unbound label L to the current code position
    712 
    713   // Returns the branch offset to the given label from the current code position
    714   // Links the label to the current position if it is still unbound
    715   // Manages the jump elimination optimization if the second parameter is true.
    716   int branch_offset(Label* L);
    717 
    718   // Returns true if the given pc address is the start of a constant pool load
    719   // instruction sequence.
    720   INLINE(static bool is_constant_pool_load(Address pc));
    721 
    722   // Return the address in the constant pool of the code target address used by
    723   // the branch/call instruction at pc, or the object in a mov.
    724   INLINE(static Address constant_pool_entry_address(Address pc,
    725                                                     Address constant_pool));
    726 
    727   // Read/Modify the code target address in the branch/call instruction at pc.
    728   INLINE(static Address target_address_at(Address pc, Address constant_pool));
    729   INLINE(static void set_target_address_at(
    730       Isolate* isolate, Address pc, Address constant_pool, Address target,
    731       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
    732   INLINE(static Address target_address_at(Address pc, Code* code));
    733   INLINE(static void set_target_address_at(
    734       Isolate* isolate, Address pc, Code* code, Address target,
    735       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
    736 
    737   // Return the code target address at a call site from the return address
    738   // of that call in the instruction stream.
    739   INLINE(static Address target_address_from_return_address(Address pc));
    740 
    741   // Given the address of the beginning of a call, return the address
    742   // in the instruction stream that the call will return from.
    743   INLINE(static Address return_address_from_call_start(Address pc));
    744 
    745   // This sets the branch destination (which is in the constant pool on ARM).
    746   // This is for calls and branches within generated code.
    747   inline static void deserialization_set_special_target_at(
    748       Isolate* isolate, Address constant_pool_entry, Code* code,
    749       Address target);
    750 
    751   // This sets the internal reference at the pc.
    752   inline static void deserialization_set_target_internal_reference_at(
    753       Isolate* isolate, Address pc, Address target,
    754       RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
    755 
    756   // Here we are patching the address in the constant pool, not the actual call
    757   // instruction.  The address in the constant pool is the same size as a
    758   // pointer.
    759   static const int kSpecialTargetSize = kPointerSize;
    760 
    761   // Size of an instruction.
    762   static const int kInstrSize = sizeof(Instr);
    763 
    764   // Distance between start of patched debug break slot and the emitted address
    765   // to jump to.
    766   // Patched debug break slot code is:
    767   //  ldr  ip, [pc, #0]   @ emited address and start
    768   //  blx  ip
    769   static const int kPatchDebugBreakSlotAddressOffset = 2 * kInstrSize;
    770 
    771   // Difference between address of current opcode and value read from pc
    772   // register.
    773   static const int kPcLoadDelta = 8;
    774 
    775   static const int kDebugBreakSlotInstructions = 4;
    776   static const int kDebugBreakSlotLength =
    777       kDebugBreakSlotInstructions * kInstrSize;
    778 
    779   // ---------------------------------------------------------------------------
    780   // Code generation
    781 
    782   // Insert the smallest number of nop instructions
    783   // possible to align the pc offset to a multiple
    784   // of m. m must be a power of 2 (>= 4).
    785   void Align(int m);
    786   // Insert the smallest number of zero bytes possible to align the pc offset
    787   // to a mulitple of m. m must be a power of 2 (>= 2).
    788   void DataAlign(int m);
    789   // Aligns code to something that's optimal for a jump target for the platform.
    790   void CodeTargetAlign();
    791 
    792   // Branch instructions
    793   void b(int branch_offset, Condition cond = al);
    794   void bl(int branch_offset, Condition cond = al);
    795   void blx(int branch_offset);  // v5 and above
    796   void blx(Register target, Condition cond = al);  // v5 and above
    797   void bx(Register target, Condition cond = al);  // v5 and above, plus v4t
    798 
    799   // Convenience branch instructions using labels
    800   void b(Label* L, Condition cond = al);
    801   void b(Condition cond, Label* L) { b(L, cond); }
    802   void bl(Label* L, Condition cond = al);
    803   void bl(Condition cond, Label* L) { bl(L, cond); }
    804   void blx(Label* L);  // v5 and above
    805 
    806   // Data-processing instructions
    807 
    808   void and_(Register dst, Register src1, const Operand& src2,
    809             SBit s = LeaveCC, Condition cond = al);
    810 
    811   void eor(Register dst, Register src1, const Operand& src2,
    812            SBit s = LeaveCC, Condition cond = al);
    813 
    814   void sub(Register dst, Register src1, const Operand& src2,
    815            SBit s = LeaveCC, Condition cond = al);
    816   void sub(Register dst, Register src1, Register src2,
    817            SBit s = LeaveCC, Condition cond = al) {
    818     sub(dst, src1, Operand(src2), s, cond);
    819   }
    820 
    821   void rsb(Register dst, Register src1, const Operand& src2,
    822            SBit s = LeaveCC, Condition cond = al);
    823 
    824   void add(Register dst, Register src1, const Operand& src2,
    825            SBit s = LeaveCC, Condition cond = al);
    826   void add(Register dst, Register src1, Register src2,
    827            SBit s = LeaveCC, Condition cond = al) {
    828     add(dst, src1, Operand(src2), s, cond);
    829   }
    830 
    831   void adc(Register dst, Register src1, const Operand& src2,
    832            SBit s = LeaveCC, Condition cond = al);
    833 
    834   void sbc(Register dst, Register src1, const Operand& src2,
    835            SBit s = LeaveCC, Condition cond = al);
    836 
    837   void rsc(Register dst, Register src1, const Operand& src2,
    838            SBit s = LeaveCC, Condition cond = al);
    839 
    840   void tst(Register src1, const Operand& src2, Condition cond = al);
    841   void tst(Register src1, Register src2, Condition cond = al) {
    842     tst(src1, Operand(src2), cond);
    843   }
    844 
    845   void teq(Register src1, const Operand& src2, Condition cond = al);
    846 
    847   void cmp(Register src1, const Operand& src2, Condition cond = al);
    848   void cmp(Register src1, Register src2, Condition cond = al) {
    849     cmp(src1, Operand(src2), cond);
    850   }
    851   void cmp_raw_immediate(Register src1, int raw_immediate, Condition cond = al);
    852 
    853   void cmn(Register src1, const Operand& src2, Condition cond = al);
    854 
    855   void orr(Register dst, Register src1, const Operand& src2,
    856            SBit s = LeaveCC, Condition cond = al);
    857   void orr(Register dst, Register src1, Register src2,
    858            SBit s = LeaveCC, Condition cond = al) {
    859     orr(dst, src1, Operand(src2), s, cond);
    860   }
    861 
    862   void mov(Register dst, const Operand& src,
    863            SBit s = LeaveCC, Condition cond = al);
    864   void mov(Register dst, Register src, SBit s = LeaveCC, Condition cond = al) {
    865     mov(dst, Operand(src), s, cond);
    866   }
    867 
    868   // Load the position of the label relative to the generated code object
    869   // pointer in a register.
    870   void mov_label_offset(Register dst, Label* label);
    871 
    872   // ARMv7 instructions for loading a 32 bit immediate in two instructions.
    873   // The constant for movw and movt should be in the range 0-0xffff.
    874   void movw(Register reg, uint32_t immediate, Condition cond = al);
    875   void movt(Register reg, uint32_t immediate, Condition cond = al);
    876 
    877   void bic(Register dst, Register src1, const Operand& src2,
    878            SBit s = LeaveCC, Condition cond = al);
    879 
    880   void mvn(Register dst, const Operand& src,
    881            SBit s = LeaveCC, Condition cond = al);
    882 
    883   // Shift instructions
    884 
    885   void asr(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC,
    886            Condition cond = al) {
    887     if (src2.is_reg()) {
    888       mov(dst, Operand(src1, ASR, src2.rm()), s, cond);
    889     } else {
    890       mov(dst, Operand(src1, ASR, src2.immediate()), s, cond);
    891     }
    892   }
    893 
    894   void lsl(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC,
    895            Condition cond = al) {
    896     if (src2.is_reg()) {
    897       mov(dst, Operand(src1, LSL, src2.rm()), s, cond);
    898     } else {
    899       mov(dst, Operand(src1, LSL, src2.immediate()), s, cond);
    900     }
    901   }
    902 
    903   void lsr(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC,
    904            Condition cond = al) {
    905     if (src2.is_reg()) {
    906       mov(dst, Operand(src1, LSR, src2.rm()), s, cond);
    907     } else {
    908       mov(dst, Operand(src1, LSR, src2.immediate()), s, cond);
    909     }
    910   }
    911 
    912   // Multiply instructions
    913 
    914   void mla(Register dst, Register src1, Register src2, Register srcA,
    915            SBit s = LeaveCC, Condition cond = al);
    916 
    917   void mls(Register dst, Register src1, Register src2, Register srcA,
    918            Condition cond = al);
    919 
    920   void sdiv(Register dst, Register src1, Register src2,
    921             Condition cond = al);
    922 
    923   void udiv(Register dst, Register src1, Register src2, Condition cond = al);
    924 
    925   void mul(Register dst, Register src1, Register src2,
    926            SBit s = LeaveCC, Condition cond = al);
    927 
    928   void smmla(Register dst, Register src1, Register src2, Register srcA,
    929              Condition cond = al);
    930 
    931   void smmul(Register dst, Register src1, Register src2, Condition cond = al);
    932 
    933   void smlal(Register dstL, Register dstH, Register src1, Register src2,
    934              SBit s = LeaveCC, Condition cond = al);
    935 
    936   void smull(Register dstL, Register dstH, Register src1, Register src2,
    937              SBit s = LeaveCC, Condition cond = al);
    938 
    939   void umlal(Register dstL, Register dstH, Register src1, Register src2,
    940              SBit s = LeaveCC, Condition cond = al);
    941 
    942   void umull(Register dstL, Register dstH, Register src1, Register src2,
    943              SBit s = LeaveCC, Condition cond = al);
    944 
    945   // Miscellaneous arithmetic instructions
    946 
    947   void clz(Register dst, Register src, Condition cond = al);  // v5 and above
    948 
    949   // Saturating instructions. v6 and above.
    950 
    951   // Unsigned saturate.
    952   //
    953   // Saturate an optionally shifted signed value to an unsigned range.
    954   //
    955   //   usat dst, #satpos, src
    956   //   usat dst, #satpos, src, lsl #sh
    957   //   usat dst, #satpos, src, asr #sh
    958   //
    959   // Register dst will contain:
    960   //
    961   //   0,                 if s < 0
    962   //   (1 << satpos) - 1, if s > ((1 << satpos) - 1)
    963   //   s,                 otherwise
    964   //
    965   // where s is the contents of src after shifting (if used.)
    966   void usat(Register dst, int satpos, const Operand& src, Condition cond = al);
    967 
    968   // Bitfield manipulation instructions. v7 and above.
    969 
    970   void ubfx(Register dst, Register src, int lsb, int width,
    971             Condition cond = al);
    972 
    973   void sbfx(Register dst, Register src, int lsb, int width,
    974             Condition cond = al);
    975 
    976   void bfc(Register dst, int lsb, int width, Condition cond = al);
    977 
    978   void bfi(Register dst, Register src, int lsb, int width,
    979            Condition cond = al);
    980 
    981   void pkhbt(Register dst, Register src1, const Operand& src2,
    982              Condition cond = al);
    983 
    984   void pkhtb(Register dst, Register src1, const Operand& src2,
    985              Condition cond = al);
    986 
    987   void sxtb(Register dst, Register src, int rotate = 0, Condition cond = al);
    988   void sxtab(Register dst, Register src1, Register src2, int rotate = 0,
    989              Condition cond = al);
    990   void sxth(Register dst, Register src, int rotate = 0, Condition cond = al);
    991   void sxtah(Register dst, Register src1, Register src2, int rotate = 0,
    992              Condition cond = al);
    993 
    994   void uxtb(Register dst, Register src, int rotate = 0, Condition cond = al);
    995   void uxtab(Register dst, Register src1, Register src2, int rotate = 0,
    996              Condition cond = al);
    997   void uxtb16(Register dst, Register src, int rotate = 0, Condition cond = al);
    998   void uxth(Register dst, Register src, int rotate = 0, Condition cond = al);
    999   void uxtah(Register dst, Register src1, Register src2, int rotate = 0,
   1000              Condition cond = al);
   1001 
   1002   // Reverse the bits in a register.
   1003   void rbit(Register dst, Register src, Condition cond = al);
   1004 
   1005   // Status register access instructions
   1006 
   1007   void mrs(Register dst, SRegister s, Condition cond = al);
   1008   void msr(SRegisterFieldMask fields, const Operand& src, Condition cond = al);
   1009 
   1010   // Load/Store instructions
   1011   void ldr(Register dst, const MemOperand& src, Condition cond = al);
   1012   void str(Register src, const MemOperand& dst, Condition cond = al);
   1013   void ldrb(Register dst, const MemOperand& src, Condition cond = al);
   1014   void strb(Register src, const MemOperand& dst, Condition cond = al);
   1015   void ldrh(Register dst, const MemOperand& src, Condition cond = al);
   1016   void strh(Register src, const MemOperand& dst, Condition cond = al);
   1017   void ldrsb(Register dst, const MemOperand& src, Condition cond = al);
   1018   void ldrsh(Register dst, const MemOperand& src, Condition cond = al);
   1019   void ldrd(Register dst1,
   1020             Register dst2,
   1021             const MemOperand& src, Condition cond = al);
   1022   void strd(Register src1,
   1023             Register src2,
   1024             const MemOperand& dst, Condition cond = al);
   1025 
   1026   // Load/Store exclusive instructions
   1027   void ldrex(Register dst, Register src, Condition cond = al);
   1028   void strex(Register src1, Register src2, Register dst, Condition cond = al);
   1029   void ldrexb(Register dst, Register src, Condition cond = al);
   1030   void strexb(Register src1, Register src2, Register dst, Condition cond = al);
   1031   void ldrexh(Register dst, Register src, Condition cond = al);
   1032   void strexh(Register src1, Register src2, Register dst, Condition cond = al);
   1033 
   1034   // Preload instructions
   1035   void pld(const MemOperand& address);
   1036 
   1037   // Load/Store multiple instructions
   1038   void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al);
   1039   void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al);
   1040 
   1041   // Exception-generating instructions and debugging support
   1042   void stop(const char* msg,
   1043             Condition cond = al,
   1044             int32_t code = kDefaultStopCode);
   1045 
   1046   void bkpt(uint32_t imm16);  // v5 and above
   1047   void svc(uint32_t imm24, Condition cond = al);
   1048 
   1049   // Synchronization instructions.
   1050   // On ARMv6, an equivalent CP15 operation will be used.
   1051   void dmb(BarrierOption option);
   1052   void dsb(BarrierOption option);
   1053   void isb(BarrierOption option);
   1054 
   1055   // Coprocessor instructions
   1056 
   1057   void cdp(Coprocessor coproc, int opcode_1,
   1058            CRegister crd, CRegister crn, CRegister crm,
   1059            int opcode_2, Condition cond = al);
   1060 
   1061   void cdp2(Coprocessor coproc, int opcode_1,
   1062             CRegister crd, CRegister crn, CRegister crm,
   1063             int opcode_2);  // v5 and above
   1064 
   1065   void mcr(Coprocessor coproc, int opcode_1,
   1066            Register rd, CRegister crn, CRegister crm,
   1067            int opcode_2 = 0, Condition cond = al);
   1068 
   1069   void mcr2(Coprocessor coproc, int opcode_1,
   1070             Register rd, CRegister crn, CRegister crm,
   1071             int opcode_2 = 0);  // v5 and above
   1072 
   1073   void mrc(Coprocessor coproc, int opcode_1,
   1074            Register rd, CRegister crn, CRegister crm,
   1075            int opcode_2 = 0, Condition cond = al);
   1076 
   1077   void mrc2(Coprocessor coproc, int opcode_1,
   1078             Register rd, CRegister crn, CRegister crm,
   1079             int opcode_2 = 0);  // v5 and above
   1080 
   1081   void ldc(Coprocessor coproc, CRegister crd, const MemOperand& src,
   1082            LFlag l = Short, Condition cond = al);
   1083   void ldc(Coprocessor coproc, CRegister crd, Register base, int option,
   1084            LFlag l = Short, Condition cond = al);
   1085 
   1086   void ldc2(Coprocessor coproc, CRegister crd, const MemOperand& src,
   1087             LFlag l = Short);  // v5 and above
   1088   void ldc2(Coprocessor coproc, CRegister crd, Register base, int option,
   1089             LFlag l = Short);  // v5 and above
   1090 
   1091   // Support for VFP.
   1092   // All these APIs support S0 to S31 and D0 to D31.
   1093 
   1094   void vldr(const DwVfpRegister dst,
   1095             const Register base,
   1096             int offset,
   1097             const Condition cond = al);
   1098   void vldr(const DwVfpRegister dst,
   1099             const MemOperand& src,
   1100             const Condition cond = al);
   1101 
   1102   void vldr(const SwVfpRegister dst,
   1103             const Register base,
   1104             int offset,
   1105             const Condition cond = al);
   1106   void vldr(const SwVfpRegister dst,
   1107             const MemOperand& src,
   1108             const Condition cond = al);
   1109 
   1110   void vstr(const DwVfpRegister src,
   1111             const Register base,
   1112             int offset,
   1113             const Condition cond = al);
   1114   void vstr(const DwVfpRegister src,
   1115             const MemOperand& dst,
   1116             const Condition cond = al);
   1117 
   1118   void vstr(const SwVfpRegister src,
   1119             const Register base,
   1120             int offset,
   1121             const Condition cond = al);
   1122   void vstr(const SwVfpRegister src,
   1123             const MemOperand& dst,
   1124             const Condition cond = al);
   1125 
   1126   void vldm(BlockAddrMode am,
   1127             Register base,
   1128             DwVfpRegister first,
   1129             DwVfpRegister last,
   1130             Condition cond = al);
   1131 
   1132   void vstm(BlockAddrMode am,
   1133             Register base,
   1134             DwVfpRegister first,
   1135             DwVfpRegister last,
   1136             Condition cond = al);
   1137 
   1138   void vldm(BlockAddrMode am,
   1139             Register base,
   1140             SwVfpRegister first,
   1141             SwVfpRegister last,
   1142             Condition cond = al);
   1143 
   1144   void vstm(BlockAddrMode am,
   1145             Register base,
   1146             SwVfpRegister first,
   1147             SwVfpRegister last,
   1148             Condition cond = al);
   1149 
   1150   void vmov(const SwVfpRegister dst, float imm);
   1151   void vmov(const DwVfpRegister dst,
   1152             double imm,
   1153             const Register scratch = no_reg);
   1154   void vmov(const SwVfpRegister dst,
   1155             const SwVfpRegister src,
   1156             const Condition cond = al);
   1157   void vmov(const DwVfpRegister dst,
   1158             const DwVfpRegister src,
   1159             const Condition cond = al);
   1160   // TODO(bbudge) Replace uses of these with the more general core register to
   1161   // scalar register vmov's.
   1162   void vmov(const DwVfpRegister dst,
   1163             const VmovIndex index,
   1164             const Register src,
   1165             const Condition cond = al);
   1166   void vmov(const Register dst,
   1167             const VmovIndex index,
   1168             const DwVfpRegister src,
   1169             const Condition cond = al);
   1170   void vmov(const DwVfpRegister dst,
   1171             const Register src1,
   1172             const Register src2,
   1173             const Condition cond = al);
   1174   void vmov(const Register dst1,
   1175             const Register dst2,
   1176             const DwVfpRegister src,
   1177             const Condition cond = al);
   1178   void vmov(const SwVfpRegister dst,
   1179             const Register src,
   1180             const Condition cond = al);
   1181   void vmov(const Register dst,
   1182             const SwVfpRegister src,
   1183             const Condition cond = al);
   1184   void vcvt_f64_s32(const DwVfpRegister dst,
   1185                     const SwVfpRegister src,
   1186                     VFPConversionMode mode = kDefaultRoundToZero,
   1187                     const Condition cond = al);
   1188   void vcvt_f32_s32(const SwVfpRegister dst,
   1189                     const SwVfpRegister src,
   1190                     VFPConversionMode mode = kDefaultRoundToZero,
   1191                     const Condition cond = al);
   1192   void vcvt_f64_u32(const DwVfpRegister dst,
   1193                     const SwVfpRegister src,
   1194                     VFPConversionMode mode = kDefaultRoundToZero,
   1195                     const Condition cond = al);
   1196   void vcvt_f32_u32(const SwVfpRegister dst,
   1197                     const SwVfpRegister src,
   1198                     VFPConversionMode mode = kDefaultRoundToZero,
   1199                     const Condition cond = al);
   1200   void vcvt_s32_f32(const SwVfpRegister dst,
   1201                     const SwVfpRegister src,
   1202                     VFPConversionMode mode = kDefaultRoundToZero,
   1203                     const Condition cond = al);
   1204   void vcvt_u32_f32(const SwVfpRegister dst,
   1205                     const SwVfpRegister src,
   1206                     VFPConversionMode mode = kDefaultRoundToZero,
   1207                     const Condition cond = al);
   1208   void vcvt_s32_f64(const SwVfpRegister dst,
   1209                     const DwVfpRegister src,
   1210                     VFPConversionMode mode = kDefaultRoundToZero,
   1211                     const Condition cond = al);
   1212   void vcvt_u32_f64(const SwVfpRegister dst,
   1213                     const DwVfpRegister src,
   1214                     VFPConversionMode mode = kDefaultRoundToZero,
   1215                     const Condition cond = al);
   1216   void vcvt_f64_f32(const DwVfpRegister dst,
   1217                     const SwVfpRegister src,
   1218                     VFPConversionMode mode = kDefaultRoundToZero,
   1219                     const Condition cond = al);
   1220   void vcvt_f32_f64(const SwVfpRegister dst,
   1221                     const DwVfpRegister src,
   1222                     VFPConversionMode mode = kDefaultRoundToZero,
   1223                     const Condition cond = al);
   1224   void vcvt_f64_s32(const DwVfpRegister dst,
   1225                     int fraction_bits,
   1226                     const Condition cond = al);
   1227 
   1228   void vmrs(const Register dst, const Condition cond = al);
   1229   void vmsr(const Register dst, const Condition cond = al);
   1230 
   1231   void vneg(const DwVfpRegister dst,
   1232             const DwVfpRegister src,
   1233             const Condition cond = al);
   1234   void vneg(const SwVfpRegister dst, const SwVfpRegister src,
   1235             const Condition cond = al);
   1236   void vabs(const DwVfpRegister dst,
   1237             const DwVfpRegister src,
   1238             const Condition cond = al);
   1239   void vabs(const SwVfpRegister dst, const SwVfpRegister src,
   1240             const Condition cond = al);
   1241   void vadd(const DwVfpRegister dst,
   1242             const DwVfpRegister src1,
   1243             const DwVfpRegister src2,
   1244             const Condition cond = al);
   1245   void vadd(const SwVfpRegister dst, const SwVfpRegister src1,
   1246             const SwVfpRegister src2, const Condition cond = al);
   1247   void vsub(const DwVfpRegister dst,
   1248             const DwVfpRegister src1,
   1249             const DwVfpRegister src2,
   1250             const Condition cond = al);
   1251   void vsub(const SwVfpRegister dst, const SwVfpRegister src1,
   1252             const SwVfpRegister src2, const Condition cond = al);
   1253   void vmul(const DwVfpRegister dst,
   1254             const DwVfpRegister src1,
   1255             const DwVfpRegister src2,
   1256             const Condition cond = al);
   1257   void vmul(const SwVfpRegister dst, const SwVfpRegister src1,
   1258             const SwVfpRegister src2, const Condition cond = al);
   1259   void vmla(const DwVfpRegister dst,
   1260             const DwVfpRegister src1,
   1261             const DwVfpRegister src2,
   1262             const Condition cond = al);
   1263   void vmla(const SwVfpRegister dst, const SwVfpRegister src1,
   1264             const SwVfpRegister src2, const Condition cond = al);
   1265   void vmls(const DwVfpRegister dst,
   1266             const DwVfpRegister src1,
   1267             const DwVfpRegister src2,
   1268             const Condition cond = al);
   1269   void vmls(const SwVfpRegister dst, const SwVfpRegister src1,
   1270             const SwVfpRegister src2, const Condition cond = al);
   1271   void vdiv(const DwVfpRegister dst,
   1272             const DwVfpRegister src1,
   1273             const DwVfpRegister src2,
   1274             const Condition cond = al);
   1275   void vdiv(const SwVfpRegister dst, const SwVfpRegister src1,
   1276             const SwVfpRegister src2, const Condition cond = al);
   1277   void vcmp(const DwVfpRegister src1,
   1278             const DwVfpRegister src2,
   1279             const Condition cond = al);
   1280   void vcmp(const SwVfpRegister src1, const SwVfpRegister src2,
   1281             const Condition cond = al);
   1282   void vcmp(const DwVfpRegister src1,
   1283             const double src2,
   1284             const Condition cond = al);
   1285   void vcmp(const SwVfpRegister src1, const float src2,
   1286             const Condition cond = al);
   1287 
   1288   void vmaxnm(const DwVfpRegister dst,
   1289               const DwVfpRegister src1,
   1290               const DwVfpRegister src2);
   1291   void vmaxnm(const SwVfpRegister dst,
   1292               const SwVfpRegister src1,
   1293               const SwVfpRegister src2);
   1294   void vminnm(const DwVfpRegister dst,
   1295               const DwVfpRegister src1,
   1296               const DwVfpRegister src2);
   1297   void vminnm(const SwVfpRegister dst,
   1298               const SwVfpRegister src1,
   1299               const SwVfpRegister src2);
   1300 
   1301   // VSEL supports cond in {eq, ne, ge, lt, gt, le, vs, vc}.
   1302   void vsel(const Condition cond,
   1303             const DwVfpRegister dst,
   1304             const DwVfpRegister src1,
   1305             const DwVfpRegister src2);
   1306   void vsel(const Condition cond,
   1307             const SwVfpRegister dst,
   1308             const SwVfpRegister src1,
   1309             const SwVfpRegister src2);
   1310 
   1311   void vsqrt(const DwVfpRegister dst,
   1312              const DwVfpRegister src,
   1313              const Condition cond = al);
   1314   void vsqrt(const SwVfpRegister dst, const SwVfpRegister src,
   1315              const Condition cond = al);
   1316 
   1317   // ARMv8 rounding instructions.
   1318   void vrinta(const SwVfpRegister dst, const SwVfpRegister src);
   1319   void vrinta(const DwVfpRegister dst, const DwVfpRegister src);
   1320   void vrintn(const SwVfpRegister dst, const SwVfpRegister src);
   1321   void vrintn(const DwVfpRegister dst, const DwVfpRegister src);
   1322   void vrintm(const SwVfpRegister dst, const SwVfpRegister src);
   1323   void vrintm(const DwVfpRegister dst, const DwVfpRegister src);
   1324   void vrintp(const SwVfpRegister dst, const SwVfpRegister src);
   1325   void vrintp(const DwVfpRegister dst, const DwVfpRegister src);
   1326   void vrintz(const SwVfpRegister dst, const SwVfpRegister src,
   1327               const Condition cond = al);
   1328   void vrintz(const DwVfpRegister dst, const DwVfpRegister src,
   1329               const Condition cond = al);
   1330 
   1331   // Support for NEON.
   1332 
   1333   // All these APIs support D0 to D31 and Q0 to Q15.
   1334   void vld1(NeonSize size,
   1335             const NeonListOperand& dst,
   1336             const NeonMemOperand& src);
   1337   void vst1(NeonSize size,
   1338             const NeonListOperand& src,
   1339             const NeonMemOperand& dst);
   1340   void vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src);
   1341 
   1342   // Only unconditional core <-> scalar moves are currently supported.
   1343   void vmov(NeonDataType dt, DwVfpRegister dst, int index, Register src);
   1344   void vmov(NeonDataType dt, Register dst, DwVfpRegister src, int index);
   1345 
   1346   void vmov(const QwNeonRegister dst, const QwNeonRegister src);
   1347   void vmvn(const QwNeonRegister dst, const QwNeonRegister src);
   1348   void vswp(DwVfpRegister dst, DwVfpRegister src);
   1349   void vswp(QwNeonRegister dst, QwNeonRegister src);
   1350   // vdup conditional execution isn't supported.
   1351   void vdup(NeonSize size, const QwNeonRegister dst, const Register src);
   1352   void vdup(const QwNeonRegister dst, const SwVfpRegister src);
   1353 
   1354   void vcvt_f32_s32(const QwNeonRegister dst, const QwNeonRegister src);
   1355   void vcvt_f32_u32(const QwNeonRegister dst, const QwNeonRegister src);
   1356   void vcvt_s32_f32(const QwNeonRegister dst, const QwNeonRegister src);
   1357   void vcvt_u32_f32(const QwNeonRegister dst, const QwNeonRegister src);
   1358 
   1359   void vabs(const QwNeonRegister dst, const QwNeonRegister src);
   1360   void vabs(NeonSize size, const QwNeonRegister dst, const QwNeonRegister src);
   1361   void vneg(const QwNeonRegister dst, const QwNeonRegister src);
   1362   void vneg(NeonSize size, const QwNeonRegister dst, const QwNeonRegister src);
   1363   void veor(DwVfpRegister dst, DwVfpRegister src1, DwVfpRegister src2);
   1364   void vand(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
   1365   void vbsl(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
   1366   void veor(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
   1367   void vorr(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
   1368   void vadd(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
   1369   void vadd(NeonSize size, QwNeonRegister dst, QwNeonRegister src1,
   1370             QwNeonRegister src2);
   1371   void vqadd(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1,
   1372              QwNeonRegister src2);
   1373   void vsub(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
   1374   void vsub(NeonSize size, QwNeonRegister dst, QwNeonRegister src1,
   1375             QwNeonRegister src2);
   1376   void vqsub(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1,
   1377              QwNeonRegister src2);
   1378   void vmul(QwNeonRegister dst, QwNeonRegister src1,
   1379             QwNeonRegister src2);
   1380   void vmul(NeonSize size, QwNeonRegister dst, QwNeonRegister src1,
   1381             QwNeonRegister src2);
   1382   void vmin(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
   1383   void vmin(NeonDataType dt, QwNeonRegister dst,
   1384             QwNeonRegister src1, QwNeonRegister src2);
   1385   void vmax(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
   1386   void vmax(NeonDataType dt, QwNeonRegister dst,
   1387             QwNeonRegister src1, QwNeonRegister src2);
   1388   void vshl(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src, int shift);
   1389   void vshr(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src, int shift);
   1390   // vrecpe and vrsqrte only support floating point lanes.
   1391   void vrecpe(QwNeonRegister dst, QwNeonRegister src);
   1392   void vrsqrte(QwNeonRegister dst, QwNeonRegister src);
   1393   void vrecps(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
   1394   void vrsqrts(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
   1395   void vtst(NeonSize size, QwNeonRegister dst, QwNeonRegister src1,
   1396             QwNeonRegister src2);
   1397   void vceq(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
   1398   void vceq(NeonSize size, QwNeonRegister dst, QwNeonRegister src1,
   1399             QwNeonRegister src2);
   1400   void vcge(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
   1401   void vcge(NeonDataType dt, QwNeonRegister dst,
   1402             QwNeonRegister src1, QwNeonRegister src2);
   1403   void vcgt(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
   1404   void vcgt(NeonDataType dt, QwNeonRegister dst,
   1405             QwNeonRegister src1, QwNeonRegister src2);
   1406   void vext(const QwNeonRegister dst, const QwNeonRegister src1,
   1407             const QwNeonRegister src2, int bytes);
   1408   void vzip(NeonSize size, const QwNeonRegister dst, const QwNeonRegister src);
   1409   void vrev16(NeonSize size, const QwNeonRegister dst,
   1410             const QwNeonRegister src);
   1411   void vrev32(NeonSize size, const QwNeonRegister dst,
   1412             const QwNeonRegister src);
   1413   void vrev64(NeonSize size, const QwNeonRegister dst,
   1414             const QwNeonRegister src);
   1415   void vtbl(const DwVfpRegister dst, const NeonListOperand& list,
   1416             const DwVfpRegister index);
   1417   void vtbx(const DwVfpRegister dst, const NeonListOperand& list,
   1418             const DwVfpRegister index);
   1419 
   1420   // Pseudo instructions
   1421 
   1422   // Different nop operations are used by the code generator to detect certain
   1423   // states of the generated code.
   1424   enum NopMarkerTypes {
   1425     NON_MARKING_NOP = 0,
   1426     DEBUG_BREAK_NOP,
   1427     // IC markers.
   1428     PROPERTY_ACCESS_INLINED,
   1429     PROPERTY_ACCESS_INLINED_CONTEXT,
   1430     PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
   1431     // Helper values.
   1432     LAST_CODE_MARKER,
   1433     FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
   1434   };
   1435 
   1436   void nop(int type = 0);   // 0 is the default non-marking type.
   1437 
   1438   void push(Register src, Condition cond = al) {
   1439     str(src, MemOperand(sp, 4, NegPreIndex), cond);
   1440   }
   1441 
   1442   void pop(Register dst, Condition cond = al) {
   1443     ldr(dst, MemOperand(sp, 4, PostIndex), cond);
   1444   }
   1445 
   1446   void pop() {
   1447     add(sp, sp, Operand(kPointerSize));
   1448   }
   1449 
   1450   void vpush(DwVfpRegister src, Condition cond = al) {
   1451     vstm(db_w, sp, src, src, cond);
   1452   }
   1453 
   1454   void vpush(SwVfpRegister src, Condition cond = al) {
   1455     vstm(db_w, sp, src, src, cond);
   1456   }
   1457 
   1458   void vpop(DwVfpRegister dst, Condition cond = al) {
   1459     vldm(ia_w, sp, dst, dst, cond);
   1460   }
   1461 
   1462   // Jump unconditionally to given label.
   1463   void jmp(Label* L) { b(L, al); }
   1464 
   1465   // Check the code size generated from label to here.
   1466   int SizeOfCodeGeneratedSince(Label* label) {
   1467     return pc_offset() - label->pos();
   1468   }
   1469 
   1470   // Check the number of instructions generated from label to here.
   1471   int InstructionsGeneratedSince(Label* label) {
   1472     return SizeOfCodeGeneratedSince(label) / kInstrSize;
   1473   }
   1474 
   1475   // Check whether an immediate fits an addressing mode 1 instruction.
   1476   static bool ImmediateFitsAddrMode1Instruction(int32_t imm32);
   1477 
   1478   // Check whether an immediate fits an addressing mode 2 instruction.
   1479   bool ImmediateFitsAddrMode2Instruction(int32_t imm32);
   1480 
   1481   // Class for scoping postponing the constant pool generation.
   1482   class BlockConstPoolScope {
   1483    public:
   1484     explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) {
   1485       assem_->StartBlockConstPool();
   1486     }
   1487     ~BlockConstPoolScope() {
   1488       assem_->EndBlockConstPool();
   1489     }
   1490 
   1491    private:
   1492     Assembler* assem_;
   1493 
   1494     DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope);
   1495   };
   1496 
   1497   // Debugging
   1498 
   1499   // Mark address of a debug break slot.
   1500   void RecordDebugBreakSlot(RelocInfo::Mode mode);
   1501 
   1502   // Record the AST id of the CallIC being compiled, so that it can be placed
   1503   // in the relocation information.
   1504   void SetRecordedAstId(TypeFeedbackId ast_id) {
   1505     DCHECK(recorded_ast_id_.IsNone());
   1506     recorded_ast_id_ = ast_id;
   1507   }
   1508 
   1509   TypeFeedbackId RecordedAstId() {
   1510     DCHECK(!recorded_ast_id_.IsNone());
   1511     return recorded_ast_id_;
   1512   }
   1513 
   1514   void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); }
   1515 
   1516   // Record a comment relocation entry that can be used by a disassembler.
   1517   // Use --code-comments to enable.
   1518   void RecordComment(const char* msg);
   1519 
   1520   // Record a deoptimization reason that can be used by a log or cpu profiler.
   1521   // Use --trace-deopt to enable.
   1522   void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
   1523                          int id);
   1524 
   1525   // Record the emission of a constant pool.
   1526   //
   1527   // The emission of constant pool depends on the size of the code generated and
   1528   // the number of RelocInfo recorded.
   1529   // The Debug mechanism needs to map code offsets between two versions of a
   1530   // function, compiled with and without debugger support (see for example
   1531   // Debug::PrepareForBreakPoints()).
   1532   // Compiling functions with debugger support generates additional code
   1533   // (DebugCodegen::GenerateSlot()). This may affect the emission of the
   1534   // constant pools and cause the version of the code with debugger support to
   1535   // have constant pools generated in different places.
   1536   // Recording the position and size of emitted constant pools allows to
   1537   // correctly compute the offset mappings between the different versions of a
   1538   // function in all situations.
   1539   //
   1540   // The parameter indicates the size of the constant pool (in bytes), including
   1541   // the marker and branch over the data.
   1542   void RecordConstPool(int size);
   1543 
   1544   // Writes a single byte or word of data in the code stream.  Used
   1545   // for inline tables, e.g., jump-tables. CheckConstantPool() should be
   1546   // called before any use of db/dd/dq/dp to ensure that constant pools
   1547   // are not emitted as part of the tables generated.
   1548   void db(uint8_t data);
   1549   void dd(uint32_t data);
   1550   void dq(uint64_t data);
   1551   void dp(uintptr_t data) { dd(data); }
   1552 
   1553   // Emits the address of the code stub's first instruction.
   1554   void emit_code_stub_address(Code* stub);
   1555 
   1556   // Read/patch instructions
   1557   Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
   1558   void instr_at_put(int pos, Instr instr) {
   1559     *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
   1560   }
   1561   static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
   1562   static void instr_at_put(byte* pc, Instr instr) {
   1563     *reinterpret_cast<Instr*>(pc) = instr;
   1564   }
   1565   static Condition GetCondition(Instr instr);
   1566   static bool IsBranch(Instr instr);
   1567   static int GetBranchOffset(Instr instr);
   1568   static bool IsLdrRegisterImmediate(Instr instr);
   1569   static bool IsVldrDRegisterImmediate(Instr instr);
   1570   static Instr GetConsantPoolLoadPattern();
   1571   static Instr GetConsantPoolLoadMask();
   1572   static bool IsLdrPpRegOffset(Instr instr);
   1573   static Instr GetLdrPpRegOffsetPattern();
   1574   static bool IsLdrPpImmediateOffset(Instr instr);
   1575   static bool IsVldrDPpImmediateOffset(Instr instr);
   1576   static int GetLdrRegisterImmediateOffset(Instr instr);
   1577   static int GetVldrDRegisterImmediateOffset(Instr instr);
   1578   static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset);
   1579   static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset);
   1580   static bool IsStrRegisterImmediate(Instr instr);
   1581   static Instr SetStrRegisterImmediateOffset(Instr instr, int offset);
   1582   static bool IsAddRegisterImmediate(Instr instr);
   1583   static Instr SetAddRegisterImmediateOffset(Instr instr, int offset);
   1584   static Register GetRd(Instr instr);
   1585   static Register GetRn(Instr instr);
   1586   static Register GetRm(Instr instr);
   1587   static bool IsPush(Instr instr);
   1588   static bool IsPop(Instr instr);
   1589   static bool IsStrRegFpOffset(Instr instr);
   1590   static bool IsLdrRegFpOffset(Instr instr);
   1591   static bool IsStrRegFpNegOffset(Instr instr);
   1592   static bool IsLdrRegFpNegOffset(Instr instr);
   1593   static bool IsLdrPcImmediateOffset(Instr instr);
   1594   static bool IsVldrDPcImmediateOffset(Instr instr);
   1595   static bool IsBlxReg(Instr instr);
   1596   static bool IsBlxIp(Instr instr);
   1597   static bool IsTstImmediate(Instr instr);
   1598   static bool IsCmpRegister(Instr instr);
   1599   static bool IsCmpImmediate(Instr instr);
   1600   static Register GetCmpImmediateRegister(Instr instr);
   1601   static int GetCmpImmediateRawImmediate(Instr instr);
   1602   static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
   1603   static bool IsMovImmed(Instr instr);
   1604   static bool IsOrrImmed(Instr instr);
   1605   static bool IsMovT(Instr instr);
   1606   static Instr GetMovTPattern();
   1607   static bool IsMovW(Instr instr);
   1608   static Instr GetMovWPattern();
   1609   static Instr EncodeMovwImmediate(uint32_t immediate);
   1610   static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate);
   1611   static int DecodeShiftImm(Instr instr);
   1612   static Instr PatchShiftImm(Instr instr, int immed);
   1613 
   1614   // Constants in pools are accessed via pc relative addressing, which can
   1615   // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point
   1616   // PC-relative loads, thereby defining a maximum distance between the
   1617   // instruction and the accessed constant.
   1618   static const int kMaxDistToIntPool = 4*KB;
   1619   static const int kMaxDistToFPPool = 1*KB;
   1620   // All relocations could be integer, it therefore acts as the limit.
   1621   static const int kMinNumPendingConstants = 4;
   1622   static const int kMaxNumPending32Constants = kMaxDistToIntPool / kInstrSize;
   1623   static const int kMaxNumPending64Constants = kMaxDistToFPPool / kInstrSize;
   1624 
   1625   // Postpone the generation of the constant pool for the specified number of
   1626   // instructions.
   1627   void BlockConstPoolFor(int instructions);
   1628 
   1629   // Check if is time to emit a constant pool.
   1630   void CheckConstPool(bool force_emit, bool require_jump);
   1631 
   1632   void MaybeCheckConstPool() {
   1633     if (pc_offset() >= next_buffer_check_) {
   1634       CheckConstPool(false, true);
   1635     }
   1636   }
   1637 
   1638   int EmitEmbeddedConstantPool() {
   1639     DCHECK(FLAG_enable_embedded_constant_pool);
   1640     return constant_pool_builder_.Emit(this);
   1641   }
   1642 
   1643   bool ConstantPoolAccessIsInOverflow() const {
   1644     return constant_pool_builder_.NextAccess(ConstantPoolEntry::INTPTR) ==
   1645            ConstantPoolEntry::OVERFLOWED;
   1646   }
   1647 
   1648   void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
   1649                                           ConstantPoolEntry::Access access,
   1650                                           ConstantPoolEntry::Type type);
   1651 
   1652  protected:
   1653   // Relocation for a type-recording IC has the AST id added to it.  This
   1654   // member variable is a way to pass the information from the call site to
   1655   // the relocation info.
   1656   TypeFeedbackId recorded_ast_id_;
   1657 
   1658   int buffer_space() const { return reloc_info_writer.pos() - pc_; }
   1659 
   1660   // Decode branch instruction at pos and return branch target pos
   1661   int target_at(int pos);
   1662 
   1663   // Patch branch instruction at pos to branch to given branch target pos
   1664   void target_at_put(int pos, int target_pos);
   1665 
   1666   // Prevent contant pool emission until EndBlockConstPool is called.
   1667   // Call to this function can be nested but must be followed by an equal
   1668   // number of call to EndBlockConstpool.
   1669   void StartBlockConstPool() {
   1670     if (const_pool_blocked_nesting_++ == 0) {
   1671       // Prevent constant pool checks happening by setting the next check to
   1672       // the biggest possible offset.
   1673       next_buffer_check_ = kMaxInt;
   1674     }
   1675   }
   1676 
   1677   // Resume constant pool emission. Need to be called as many time as
   1678   // StartBlockConstPool to have an effect.
   1679   void EndBlockConstPool() {
   1680     if (--const_pool_blocked_nesting_ == 0) {
   1681 #ifdef DEBUG
   1682       // Max pool start (if we need a jump and an alignment).
   1683       int start = pc_offset() + kInstrSize + 2 * kPointerSize;
   1684       // Check the constant pool hasn't been blocked for too long.
   1685       DCHECK(pending_32_bit_constants_.empty() ||
   1686              (start + pending_64_bit_constants_.size() * kDoubleSize <
   1687               static_cast<size_t>(first_const_pool_32_use_ +
   1688                                   kMaxDistToIntPool)));
   1689       DCHECK(pending_64_bit_constants_.empty() ||
   1690              (start < (first_const_pool_64_use_ + kMaxDistToFPPool)));
   1691 #endif
   1692       // Two cases:
   1693       //  * no_const_pool_before_ >= next_buffer_check_ and the emission is
   1694       //    still blocked
   1695       //  * no_const_pool_before_ < next_buffer_check_ and the next emit will
   1696       //    trigger a check.
   1697       next_buffer_check_ = no_const_pool_before_;
   1698     }
   1699   }
   1700 
   1701   bool is_const_pool_blocked() const {
   1702     return (const_pool_blocked_nesting_ > 0) ||
   1703            (pc_offset() < no_const_pool_before_);
   1704   }
   1705 
   1706   bool VfpRegisterIsAvailable(DwVfpRegister reg) {
   1707     DCHECK(reg.is_valid());
   1708     return IsEnabled(VFP32DREGS) ||
   1709            (reg.reg_code < LowDwVfpRegister::kMaxNumLowRegisters);
   1710   }
   1711 
   1712   bool VfpRegisterIsAvailable(QwNeonRegister reg) {
   1713     DCHECK(reg.is_valid());
   1714     return IsEnabled(VFP32DREGS) ||
   1715            (reg.reg_code < LowDwVfpRegister::kMaxNumLowRegisters / 2);
   1716   }
   1717 
   1718  private:
   1719   int next_buffer_check_;  // pc offset of next buffer check
   1720 
   1721   // Code generation
   1722   // The relocation writer's position is at least kGap bytes below the end of
   1723   // the generated instructions. This is so that multi-instruction sequences do
   1724   // not have to check for overflow. The same is true for writes of large
   1725   // relocation info entries.
   1726   static const int kGap = 32;
   1727 
   1728   // Constant pool generation
   1729   // Pools are emitted in the instruction stream, preferably after unconditional
   1730   // jumps or after returns from functions (in dead code locations).
   1731   // If a long code sequence does not contain unconditional jumps, it is
   1732   // necessary to emit the constant pool before the pool gets too far from the
   1733   // location it is accessed from. In this case, we emit a jump over the emitted
   1734   // constant pool.
   1735   // Constants in the pool may be addresses of functions that gets relocated;
   1736   // if so, a relocation info entry is associated to the constant pool entry.
   1737 
   1738   // Repeated checking whether the constant pool should be emitted is rather
   1739   // expensive. By default we only check again once a number of instructions
   1740   // has been generated. That also means that the sizing of the buffers is not
   1741   // an exact science, and that we rely on some slop to not overrun buffers.
   1742   static const int kCheckPoolIntervalInst = 32;
   1743   static const int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize;
   1744 
   1745 
   1746   // Emission of the constant pool may be blocked in some code sequences.
   1747   int const_pool_blocked_nesting_;  // Block emission if this is not zero.
   1748   int no_const_pool_before_;  // Block emission before this pc offset.
   1749 
   1750   // Keep track of the first instruction requiring a constant pool entry
   1751   // since the previous constant pool was emitted.
   1752   int first_const_pool_32_use_;
   1753   int first_const_pool_64_use_;
   1754 
   1755   // Relocation info generation
   1756   // Each relocation is encoded as a variable size value
   1757   static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
   1758   RelocInfoWriter reloc_info_writer;
   1759 
   1760   // ConstantPoolEntry records are used during code generation as temporary
   1761   // containers for constants and code target addresses until they are emitted
   1762   // to the constant pool. These records are temporarily stored in a separate
   1763   // buffer until a constant pool is emitted.
   1764   // If every instruction in a long sequence is accessing the pool, we need one
   1765   // pending relocation entry per instruction.
   1766 
   1767   // The buffers of pending constant pool entries.
   1768   std::vector<ConstantPoolEntry> pending_32_bit_constants_;
   1769   std::vector<ConstantPoolEntry> pending_64_bit_constants_;
   1770 
   1771   ConstantPoolBuilder constant_pool_builder_;
   1772 
   1773   // The bound position, before this we cannot do instruction elimination.
   1774   int last_bound_pos_;
   1775 
   1776   // Code emission
   1777   inline void CheckBuffer();
   1778   void GrowBuffer();
   1779   inline void emit(Instr x);
   1780 
   1781   // 32-bit immediate values
   1782   void move_32_bit_immediate(Register rd,
   1783                              const Operand& x,
   1784                              Condition cond = al);
   1785 
   1786   // Instruction generation
   1787   void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
   1788   void addrmod2(Instr instr, Register rd, const MemOperand& x);
   1789   void addrmod3(Instr instr, Register rd, const MemOperand& x);
   1790   void addrmod4(Instr instr, Register rn, RegList rl);
   1791   void addrmod5(Instr instr, CRegister crd, const MemOperand& x);
   1792 
   1793   // Labels
   1794   void print(Label* L);
   1795   void bind_to(Label* L, int pos);
   1796   void next(Label* L);
   1797 
   1798   // Record reloc info for current pc_
   1799   void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
   1800   ConstantPoolEntry::Access ConstantPoolAddEntry(int position,
   1801                                                  RelocInfo::Mode rmode,
   1802                                                  intptr_t value);
   1803   ConstantPoolEntry::Access ConstantPoolAddEntry(int position, double value);
   1804 
   1805   friend class RelocInfo;
   1806   friend class CodePatcher;
   1807   friend class BlockConstPoolScope;
   1808   friend class EnsureSpace;
   1809 };
   1810 
   1811 
   1812 class EnsureSpace BASE_EMBEDDED {
   1813  public:
   1814   explicit EnsureSpace(Assembler* assembler) {
   1815     assembler->CheckBuffer();
   1816   }
   1817 };
   1818 
   1819 
   1820 }  // namespace internal
   1821 }  // namespace v8
   1822 
   1823 #endif  // V8_ARM_ASSEMBLER_ARM_H_
   1824