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