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