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