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