Home | History | Annotate | Download | only in ppc
      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 2014 the V8 project authors. All rights reserved.
     36 
     37 // A light-weight PPC Assembler
     38 // Generates user mode instructions for the PPC architecture up
     39 
     40 #ifndef V8_PPC_ASSEMBLER_PPC_H_
     41 #define V8_PPC_ASSEMBLER_PPC_H_
     42 
     43 #include <stdio.h>
     44 #include <vector>
     45 
     46 #include "src/assembler.h"
     47 #include "src/double.h"
     48 #include "src/ppc/constants-ppc.h"
     49 
     50 #if V8_HOST_ARCH_PPC && \
     51     (V8_OS_AIX || (V8_TARGET_ARCH_PPC64 && V8_TARGET_BIG_ENDIAN))
     52 #define ABI_USES_FUNCTION_DESCRIPTORS 1
     53 #else
     54 #define ABI_USES_FUNCTION_DESCRIPTORS 0
     55 #endif
     56 
     57 #if !V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64
     58 #define ABI_PASSES_HANDLES_IN_REGS 1
     59 #else
     60 #define ABI_PASSES_HANDLES_IN_REGS 0
     61 #endif
     62 
     63 #if !V8_HOST_ARCH_PPC || !V8_TARGET_ARCH_PPC64 || V8_TARGET_LITTLE_ENDIAN
     64 #define ABI_RETURNS_OBJECT_PAIRS_IN_REGS 1
     65 #else
     66 #define ABI_RETURNS_OBJECT_PAIRS_IN_REGS 0
     67 #endif
     68 
     69 #if !V8_HOST_ARCH_PPC || (V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN)
     70 #define ABI_CALL_VIA_IP 1
     71 #else
     72 #define ABI_CALL_VIA_IP 0
     73 #endif
     74 
     75 #if !V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64
     76 #define ABI_TOC_REGISTER 2
     77 #else
     78 #define ABI_TOC_REGISTER 13
     79 #endif
     80 
     81 #define INSTR_AND_DATA_CACHE_COHERENCY LWSYNC
     82 
     83 namespace v8 {
     84 namespace internal {
     85 
     86 // clang-format off
     87 #define GENERAL_REGISTERS(V)                              \
     88   V(r0)  V(sp)  V(r2)  V(r3)  V(r4)  V(r5)  V(r6)  V(r7)  \
     89   V(r8)  V(r9)  V(r10) V(r11) V(ip) V(r13) V(r14) V(r15)  \
     90   V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \
     91   V(r24) V(r25) V(r26) V(r27) V(r28) V(r29) V(r30) V(fp)
     92 
     93 #if V8_EMBEDDED_CONSTANT_POOL
     94 #define ALLOCATABLE_GENERAL_REGISTERS(V)                  \
     95   V(r3)  V(r4)  V(r5)  V(r6)  V(r7)                       \
     96   V(r8)  V(r9)  V(r10) V(r14) V(r15)                      \
     97   V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \
     98   V(r24) V(r25) V(r26) V(r27) V(r30)
     99 #else
    100 #define ALLOCATABLE_GENERAL_REGISTERS(V)                  \
    101   V(r3)  V(r4)  V(r5)  V(r6)  V(r7)                       \
    102   V(r8)  V(r9)  V(r10) V(r14) V(r15)                      \
    103   V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \
    104   V(r24) V(r25) V(r26) V(r27) V(r28) V(r30)
    105 #endif
    106 
    107 #define LOW_DOUBLE_REGISTERS(V)                           \
    108   V(d0)  V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)  \
    109   V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d13) V(d14) V(d15)
    110 
    111 #define NON_LOW_DOUBLE_REGISTERS(V)                       \
    112   V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \
    113   V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
    114 
    115 #define DOUBLE_REGISTERS(V) \
    116   LOW_DOUBLE_REGISTERS(V) NON_LOW_DOUBLE_REGISTERS(V)
    117 
    118 #define FLOAT_REGISTERS DOUBLE_REGISTERS
    119 #define SIMD128_REGISTERS DOUBLE_REGISTERS
    120 
    121 #define ALLOCATABLE_DOUBLE_REGISTERS(V)                   \
    122   V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)         \
    123   V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d15)               \
    124   V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \
    125   V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
    126 
    127 #define C_REGISTERS(V)                                            \
    128   V(cr0)  V(cr1)  V(cr2)  V(cr3)  V(cr4)  V(cr5)  V(cr6)  V(cr7)  \
    129   V(cr8)  V(cr9)  V(cr10) V(cr11) V(cr12) V(cr15)
    130 // clang-format on
    131 
    132 // Register list in load/store instructions
    133 // Note that the bit values must match those used in actual instruction encoding
    134 const int kNumRegs = 32;
    135 
    136 // Caller-saved/arguments registers
    137 const RegList kJSCallerSaved = 1 << 3 |   // r3  a1
    138                                1 << 4 |   // r4  a2
    139                                1 << 5 |   // r5  a3
    140                                1 << 6 |   // r6  a4
    141                                1 << 7 |   // r7  a5
    142                                1 << 8 |   // r8  a6
    143                                1 << 9 |   // r9  a7
    144                                1 << 10 |  // r10 a8
    145                                1 << 11;
    146 
    147 const int kNumJSCallerSaved = 9;
    148 
    149 // Return the code of the n-th caller-saved register available to JavaScript
    150 // e.g. JSCallerSavedReg(0) returns r0.code() == 0
    151 int JSCallerSavedCode(int n);
    152 
    153 // Callee-saved registers preserved when switching from C to JavaScript
    154 const RegList kCalleeSaved = 1 << 14 |  // r14
    155                              1 << 15 |  // r15
    156                              1 << 16 |  // r16
    157                              1 << 17 |  // r17
    158                              1 << 18 |  // r18
    159                              1 << 19 |  // r19
    160                              1 << 20 |  // r20
    161                              1 << 21 |  // r21
    162                              1 << 22 |  // r22
    163                              1 << 23 |  // r23
    164                              1 << 24 |  // r24
    165                              1 << 25 |  // r25
    166                              1 << 26 |  // r26
    167                              1 << 27 |  // r27
    168                              1 << 28 |  // r28
    169                              1 << 29 |  // r29
    170                              1 << 30 |  // r20
    171                              1 << 31;   // r31
    172 
    173 const int kNumCalleeSaved = 18;
    174 
    175 const RegList kCallerSavedDoubles = 1 << 0 |   // d0
    176                                     1 << 1 |   // d1
    177                                     1 << 2 |   // d2
    178                                     1 << 3 |   // d3
    179                                     1 << 4 |   // d4
    180                                     1 << 5 |   // d5
    181                                     1 << 6 |   // d6
    182                                     1 << 7 |   // d7
    183                                     1 << 8 |   // d8
    184                                     1 << 9 |   // d9
    185                                     1 << 10 |  // d10
    186                                     1 << 11 |  // d11
    187                                     1 << 12 |  // d12
    188                                     1 << 13;   // d13
    189 
    190 const int kNumCallerSavedDoubles = 14;
    191 
    192 const RegList kCalleeSavedDoubles = 1 << 14 |  // d14
    193                                     1 << 15 |  // d15
    194                                     1 << 16 |  // d16
    195                                     1 << 17 |  // d17
    196                                     1 << 18 |  // d18
    197                                     1 << 19 |  // d19
    198                                     1 << 20 |  // d20
    199                                     1 << 21 |  // d21
    200                                     1 << 22 |  // d22
    201                                     1 << 23 |  // d23
    202                                     1 << 24 |  // d24
    203                                     1 << 25 |  // d25
    204                                     1 << 26 |  // d26
    205                                     1 << 27 |  // d27
    206                                     1 << 28 |  // d28
    207                                     1 << 29 |  // d29
    208                                     1 << 30 |  // d30
    209                                     1 << 31;   // d31
    210 
    211 const int kNumCalleeSavedDoubles = 18;
    212 
    213 // Number of registers for which space is reserved in safepoints. Must be a
    214 // multiple of 8.
    215 const int kNumSafepointRegisters = 32;
    216 
    217 // The following constants describe the stack frame linkage area as
    218 // defined by the ABI.  Note that kNumRequiredStackFrameSlots must
    219 // satisfy alignment requirements (rounding up if required).
    220 #if V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN
    221 // [0] back chain
    222 // [1] condition register save area
    223 // [2] link register save area
    224 // [3] TOC save area
    225 // [4] Parameter1 save area
    226 // ...
    227 // [11] Parameter8 save area
    228 // [12] Parameter9 slot (if necessary)
    229 // ...
    230 const int kNumRequiredStackFrameSlots = 12;
    231 const int kStackFrameLRSlot = 2;
    232 const int kStackFrameExtraParamSlot = 12;
    233 #elif V8_OS_AIX || V8_TARGET_ARCH_PPC64
    234 // [0] back chain
    235 // [1] condition register save area
    236 // [2] link register save area
    237 // [3] reserved for compiler
    238 // [4] reserved by binder
    239 // [5] TOC save area
    240 // [6] Parameter1 save area
    241 // ...
    242 // [13] Parameter8 save area
    243 // [14] Parameter9 slot (if necessary)
    244 // ...
    245 #if V8_TARGET_ARCH_PPC64
    246 const int kNumRequiredStackFrameSlots = 14;
    247 #else
    248 const int kNumRequiredStackFrameSlots = 16;
    249 #endif
    250 const int kStackFrameLRSlot = 2;
    251 const int kStackFrameExtraParamSlot = 14;
    252 #else
    253 // [0] back chain
    254 // [1] link register save area
    255 // [2] Parameter9 slot (if necessary)
    256 // ...
    257 const int kNumRequiredStackFrameSlots = 4;
    258 const int kStackFrameLRSlot = 1;
    259 const int kStackFrameExtraParamSlot = 2;
    260 #endif
    261 
    262 // Define the list of registers actually saved at safepoints.
    263 // Note that the number of saved registers may be smaller than the reserved
    264 // space, i.e. kNumSafepointSavedRegisters <= kNumSafepointRegisters.
    265 const RegList kSafepointSavedRegisters = kJSCallerSaved | kCalleeSaved;
    266 const int kNumSafepointSavedRegisters = kNumJSCallerSaved + kNumCalleeSaved;
    267 
    268 enum RegisterCode {
    269 #define REGISTER_CODE(R) kRegCode_##R,
    270   GENERAL_REGISTERS(REGISTER_CODE)
    271 #undef REGISTER_CODE
    272       kRegAfterLast
    273 };
    274 
    275 class Register : public RegisterBase<Register, kRegAfterLast> {
    276  public:
    277 #if V8_TARGET_LITTLE_ENDIAN
    278   static constexpr int kMantissaOffset = 0;
    279   static constexpr int kExponentOffset = 4;
    280 #else
    281   static constexpr int kMantissaOffset = 4;
    282   static constexpr int kExponentOffset = 0;
    283 #endif
    284 
    285  private:
    286   friend class RegisterBase;
    287   explicit constexpr Register(int code) : RegisterBase(code) {}
    288 };
    289 
    290 ASSERT_TRIVIALLY_COPYABLE(Register);
    291 static_assert(sizeof(Register) == sizeof(int),
    292               "Register can efficiently be passed by value");
    293 
    294 #define DEFINE_REGISTER(R) \
    295   constexpr Register R = Register::from_code<kRegCode_##R>();
    296 GENERAL_REGISTERS(DEFINE_REGISTER)
    297 #undef DEFINE_REGISTER
    298 constexpr Register no_reg = Register::no_reg();
    299 
    300 // Aliases
    301 constexpr Register kConstantPoolRegister = r28;  // Constant pool.
    302 constexpr Register kRootRegister = r29;          // Roots array pointer.
    303 constexpr Register cp = r30;                     // JavaScript context pointer.
    304 
    305 constexpr bool kPadArguments = false;
    306 constexpr bool kSimpleFPAliasing = true;
    307 constexpr bool kSimdMaskRegisters = false;
    308 
    309 enum DoubleRegisterCode {
    310 #define REGISTER_CODE(R) kDoubleCode_##R,
    311   DOUBLE_REGISTERS(REGISTER_CODE)
    312 #undef REGISTER_CODE
    313       kDoubleAfterLast
    314 };
    315 
    316 // Double word FP register.
    317 class DoubleRegister : public RegisterBase<DoubleRegister, kDoubleAfterLast> {
    318  public:
    319   // A few double registers are reserved: one as a scratch register and one to
    320   // hold 0.0, that does not fit in the immediate field of vmov instructions.
    321   // d14: 0.0
    322   // d15: scratch register.
    323   static constexpr int kSizeInBytes = 8;
    324   inline static int NumRegisters();
    325 
    326  private:
    327   friend class RegisterBase;
    328   explicit constexpr DoubleRegister(int code) : RegisterBase(code) {}
    329 };
    330 
    331 ASSERT_TRIVIALLY_COPYABLE(DoubleRegister);
    332 static_assert(sizeof(DoubleRegister) == sizeof(int),
    333               "DoubleRegister can efficiently be passed by value");
    334 
    335 typedef DoubleRegister FloatRegister;
    336 
    337 // TODO(ppc) Define SIMD registers.
    338 typedef DoubleRegister Simd128Register;
    339 
    340 #define DEFINE_REGISTER(R) \
    341   constexpr DoubleRegister R = DoubleRegister::from_code<kDoubleCode_##R>();
    342 DOUBLE_REGISTERS(DEFINE_REGISTER)
    343 #undef DEFINE_REGISTER
    344 constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
    345 
    346 constexpr DoubleRegister kFirstCalleeSavedDoubleReg = d14;
    347 constexpr DoubleRegister kLastCalleeSavedDoubleReg = d31;
    348 constexpr DoubleRegister kDoubleRegZero = d14;
    349 constexpr DoubleRegister kScratchDoubleReg = d13;
    350 
    351 Register ToRegister(int num);
    352 
    353 enum CRegisterCode {
    354 #define REGISTER_CODE(R) kCCode_##R,
    355   C_REGISTERS(REGISTER_CODE)
    356 #undef REGISTER_CODE
    357       kCAfterLast
    358 };
    359 
    360 // Coprocessor register
    361 class CRegister : public RegisterBase<CRegister, kCAfterLast> {
    362   friend class RegisterBase;
    363   explicit constexpr CRegister(int code) : RegisterBase(code) {}
    364 };
    365 
    366 constexpr CRegister no_creg = CRegister::no_reg();
    367 #define DECLARE_C_REGISTER(R) \
    368   constexpr CRegister R = CRegister::from_code<kCCode_##R>();
    369 C_REGISTERS(DECLARE_C_REGISTER)
    370 #undef DECLARE_C_REGISTER
    371 
    372 // -----------------------------------------------------------------------------
    373 // Machine instruction Operands
    374 
    375 // Class Operand represents a shifter operand in data processing instructions
    376 class Operand BASE_EMBEDDED {
    377  public:
    378   // immediate
    379   V8_INLINE explicit Operand(intptr_t immediate,
    380                              RelocInfo::Mode rmode = RelocInfo::NONE)
    381       : rmode_(rmode) {
    382     value_.immediate = immediate;
    383   }
    384   V8_INLINE static Operand Zero() { return Operand(static_cast<intptr_t>(0)); }
    385   V8_INLINE explicit Operand(const ExternalReference& f)
    386       : rmode_(RelocInfo::EXTERNAL_REFERENCE) {
    387     value_.immediate = static_cast<intptr_t>(f.address());
    388   }
    389   explicit Operand(Handle<HeapObject> handle);
    390   V8_INLINE explicit Operand(Smi* value) : rmode_(RelocInfo::NONE) {
    391     value_.immediate = reinterpret_cast<intptr_t>(value);
    392   }
    393   // rm
    394   V8_INLINE explicit Operand(Register rm);
    395 
    396   static Operand EmbeddedNumber(double number);  // Smi or HeapNumber.
    397   static Operand EmbeddedCode(CodeStub* stub);
    398 
    399   // Return true if this is a register operand.
    400   V8_INLINE bool is_reg() const { return rm_.is_valid(); }
    401 
    402   bool must_output_reloc_info(const Assembler* assembler) const;
    403 
    404   inline intptr_t immediate() const {
    405     DCHECK(IsImmediate());
    406     DCHECK(!IsHeapObjectRequest());
    407     return value_.immediate;
    408   }
    409   bool IsImmediate() const { return !rm_.is_valid(); }
    410 
    411   HeapObjectRequest heap_object_request() const {
    412     DCHECK(IsHeapObjectRequest());
    413     return value_.heap_object_request;
    414   }
    415 
    416   Register rm() const { return rm_; }
    417 
    418   bool IsHeapObjectRequest() const {
    419     DCHECK_IMPLIES(is_heap_object_request_, IsImmediate());
    420     DCHECK_IMPLIES(is_heap_object_request_,
    421                    rmode_ == RelocInfo::EMBEDDED_OBJECT ||
    422                        rmode_ == RelocInfo::CODE_TARGET);
    423     return is_heap_object_request_;
    424   }
    425 
    426  private:
    427   Register rm_ = no_reg;
    428   union Value {
    429     Value() {}
    430     HeapObjectRequest heap_object_request;  // if is_heap_object_request_
    431     intptr_t immediate;                     // otherwise
    432   } value_;                                 // valid if rm_ == no_reg
    433   bool is_heap_object_request_ = false;
    434 
    435   RelocInfo::Mode rmode_;
    436 
    437   friend class Assembler;
    438   friend class MacroAssembler;
    439 };
    440 
    441 
    442 // Class MemOperand represents a memory operand in load and store instructions
    443 // On PowerPC we have base register + 16bit signed value
    444 // Alternatively we can have a 16bit signed value immediate
    445 class MemOperand BASE_EMBEDDED {
    446  public:
    447   explicit MemOperand(Register rn, int32_t offset = 0);
    448 
    449   explicit MemOperand(Register ra, Register rb);
    450 
    451   int32_t offset() const {
    452     return offset_;
    453   }
    454 
    455   // PowerPC - base register
    456   Register ra() const {
    457     return ra_;
    458   }
    459 
    460   Register rb() const {
    461     return rb_;
    462   }
    463 
    464  private:
    465   Register ra_;     // base
    466   int32_t offset_;  // offset
    467   Register rb_;     // index
    468 
    469   friend class Assembler;
    470 };
    471 
    472 
    473 class DeferredRelocInfo {
    474  public:
    475   DeferredRelocInfo() {}
    476   DeferredRelocInfo(int position, RelocInfo::Mode rmode, intptr_t data)
    477       : position_(position), rmode_(rmode), data_(data) {}
    478 
    479   int position() const { return position_; }
    480   RelocInfo::Mode rmode() const { return rmode_; }
    481   intptr_t data() const { return data_; }
    482 
    483  private:
    484   int position_;
    485   RelocInfo::Mode rmode_;
    486   intptr_t data_;
    487 };
    488 
    489 
    490 class Assembler : public AssemblerBase {
    491  public:
    492   // Create an assembler. Instructions and relocation information are emitted
    493   // into a buffer, with the instructions starting from the beginning and the
    494   // relocation information starting from the end of the buffer. See CodeDesc
    495   // for a detailed comment on the layout (globals.h).
    496   //
    497   // If the provided buffer is nullptr, the assembler allocates and grows its
    498   // own buffer, and buffer_size determines the initial buffer size. The buffer
    499   // is owned by the assembler and deallocated upon destruction of the
    500   // assembler.
    501   //
    502   // If the provided buffer is not nullptr, the assembler uses the provided
    503   // buffer for code generation and assumes its size to be buffer_size. If the
    504   // buffer is too small, a fatal error occurs. No deallocation of the buffer is
    505   // done upon destruction of the assembler.
    506   Assembler(const AssemblerOptions& options, void* buffer, int buffer_size);
    507   virtual ~Assembler() {}
    508 
    509   // GetCode emits any pending (non-emitted) code and fills the descriptor
    510   // desc. GetCode() is idempotent; it returns the same result if no other
    511   // Assembler functions are invoked in between GetCode() calls.
    512   void GetCode(Isolate* isolate, CodeDesc* desc);
    513 
    514   // Label operations & relative jumps (PPUM Appendix D)
    515   //
    516   // Takes a branch opcode (cc) and a label (L) and generates
    517   // either a backward branch or a forward branch and links it
    518   // to the label fixup chain. Usage:
    519   //
    520   // Label L;    // unbound label
    521   // j(cc, &L);  // forward branch to unbound label
    522   // bind(&L);   // bind label to the current pc
    523   // j(cc, &L);  // backward branch to bound label
    524   // bind(&L);   // illegal: a label may be bound only once
    525   //
    526   // Note: The same Label can be used for forward and backward branches
    527   // but it may be bound only once.
    528 
    529   void bind(Label* L);  // binds an unbound label L to the current code position
    530 
    531   // Links a label at the current pc_offset().  If already bound, returns the
    532   // bound position.  If already linked, returns the position of the prior link.
    533   // Otherwise, returns the current pc_offset().
    534   int link(Label* L);
    535 
    536   // Determines if Label is bound and near enough so that a single
    537   // branch instruction can be used to reach it.
    538   bool is_near(Label* L, Condition cond);
    539 
    540   // Returns the branch offset to the given label from the current code position
    541   // Links the label to the current position if it is still unbound
    542   int branch_offset(Label* L) {
    543     if (L->is_unused() && !trampoline_emitted_) {
    544       TrackBranch();
    545     }
    546     return link(L) - pc_offset();
    547   }
    548 
    549   // Puts a labels target address at the given position.
    550   // The high 8 bits are set to zero.
    551   void label_at_put(Label* L, int at_offset);
    552 
    553   V8_INLINE static bool IsConstantPoolLoadStart(
    554       Address pc, ConstantPoolEntry::Access* access = nullptr);
    555   V8_INLINE static bool IsConstantPoolLoadEnd(
    556       Address pc, ConstantPoolEntry::Access* access = nullptr);
    557   V8_INLINE static int GetConstantPoolOffset(Address pc,
    558                                              ConstantPoolEntry::Access access,
    559                                              ConstantPoolEntry::Type type);
    560   V8_INLINE void PatchConstantPoolAccessInstruction(
    561       int pc_offset, int offset, ConstantPoolEntry::Access access,
    562       ConstantPoolEntry::Type type);
    563 
    564   // Return the address in the constant pool of the code target address used by
    565   // the branch/call instruction at pc, or the object in a mov.
    566   V8_INLINE static Address target_constant_pool_address_at(
    567       Address pc, Address constant_pool, ConstantPoolEntry::Access access,
    568       ConstantPoolEntry::Type type);
    569 
    570   // Read/Modify the code target address in the branch/call instruction at pc.
    571   // The isolate argument is unused (and may be nullptr) when skipping flushing.
    572   V8_INLINE static Address target_address_at(Address pc, Address constant_pool);
    573   V8_INLINE static void set_target_address_at(
    574       Address pc, Address constant_pool, Address target,
    575       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
    576 
    577   // Return the code target address at a call site from the return address
    578   // of that call in the instruction stream.
    579   inline static Address target_address_from_return_address(Address pc);
    580 
    581   // Given the address of the beginning of a call, return the address
    582   // in the instruction stream that the call will return to.
    583   V8_INLINE static Address return_address_from_call_start(Address pc);
    584 
    585   // This sets the branch destination.
    586   // This is for calls and branches within generated code.
    587   inline static void deserialization_set_special_target_at(
    588       Address instruction_payload, Code* code, Address target);
    589 
    590   // Get the size of the special target encoded at 'instruction_payload'.
    591   inline static int deserialization_special_target_size(
    592       Address instruction_payload);
    593 
    594   // This sets the internal reference at the pc.
    595   inline static void deserialization_set_target_internal_reference_at(
    596       Address pc, Address target,
    597       RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
    598 
    599   // Here we are patching the address in the LUI/ORI instruction pair.
    600   // These values are used in the serialization process and must be zero for
    601   // PPC platform, as Code, Embedded Object or External-reference pointers
    602   // are split across two consecutive instructions and don't exist separately
    603   // in the code, so the serializer should not step forwards in memory after
    604   // a target is resolved and written.
    605   static constexpr int kSpecialTargetSize = 0;
    606 
    607 // Number of instructions to load an address via a mov sequence.
    608 #if V8_TARGET_ARCH_PPC64
    609   static constexpr int kMovInstructionsConstantPool = 1;
    610   static constexpr int kMovInstructionsNoConstantPool = 5;
    611 #if defined(V8_PPC_TAGGING_OPT)
    612   static constexpr int kTaggedLoadInstructions = 1;
    613 #else
    614   static constexpr int kTaggedLoadInstructions = 2;
    615 #endif
    616 #else
    617   static constexpr int kMovInstructionsConstantPool = 1;
    618   static constexpr int kMovInstructionsNoConstantPool = 2;
    619   static constexpr int kTaggedLoadInstructions = 1;
    620 #endif
    621   static constexpr int kMovInstructions = FLAG_enable_embedded_constant_pool
    622                                               ? kMovInstructionsConstantPool
    623                                               : kMovInstructionsNoConstantPool;
    624 
    625   // Distance between the instruction referring to the address of the call
    626   // target and the return address.
    627 
    628   // Call sequence is a FIXED_SEQUENCE:
    629   // mov     r8, @ call address
    630   // mtlr    r8
    631   // blrl
    632   //                      @ return address
    633   static constexpr int kCallTargetAddressOffset =
    634       (kMovInstructions + 2) * kInstrSize;
    635 
    636   static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) {
    637     return ((cr.code() * CRWIDTH) + crbit);
    638   }
    639 
    640 #define DECLARE_PPC_X_INSTRUCTIONS_A_FORM(name, instr_name, instr_value)    \
    641   inline void name(const Register rt, const Register ra,                    \
    642                    const Register rb, const RCBit rc = LeaveRC) {           \
    643     x_form(instr_name, rt, ra, rb, rc);                                     \
    644   }
    645 
    646 #define DECLARE_PPC_X_INSTRUCTIONS_B_FORM(name, instr_name, instr_value)    \
    647   inline void name(const Register ra, const Register rs,                    \
    648                    const Register rb, const RCBit rc = LeaveRC) {           \
    649     x_form(instr_name, rs, ra, rb, rc);                                     \
    650   }
    651 
    652 #define DECLARE_PPC_X_INSTRUCTIONS_C_FORM(name, instr_name, instr_value)    \
    653   inline void name(const Register dst, const Register src,                  \
    654                    const RCBit rc = LeaveRC) {                              \
    655     x_form(instr_name, src, dst, r0, rc);                                   \
    656   }
    657 
    658 #define DECLARE_PPC_X_INSTRUCTIONS_D_FORM(name, instr_name, instr_value) \
    659   template <class R>                                                     \
    660   inline void name(const R rt, const Register ra, const Register rb,     \
    661                    const RCBit rc = LeaveRC) {                           \
    662     x_form(instr_name, rt.code(), ra.code(), rb.code(), rc);             \
    663   }                                                                      \
    664   template <class R>                                                     \
    665   inline void name(const R dst, const MemOperand& src) {                 \
    666     name(dst, src.ra(), src.rb());                                       \
    667   }
    668 
    669 #define DECLARE_PPC_X_INSTRUCTIONS_E_FORM(name, instr_name, instr_value)    \
    670   inline void name(const Register dst, const Register src,                  \
    671                    const int sh, const RCBit rc = LeaveRC) {                \
    672     x_form(instr_name, src.code(), dst.code(), sh, rc);                     \
    673   }
    674 
    675 #define DECLARE_PPC_X_INSTRUCTIONS_F_FORM(name, instr_name, instr_value)    \
    676   inline void name(const Register src1, const Register src2,                \
    677                    const CRegister cr = cr7, const RCBit rc = LeaveRC) {    \
    678     x_form(instr_name, cr, src1, src2, rc);                                 \
    679   }                                                                         \
    680   inline void name##w(const Register src1, const Register src2,             \
    681                       const CRegister cr = cr7, const RCBit rc = LeaveRC) { \
    682     x_form(instr_name, cr.code() * B2, src1.code(), src2.code(), LeaveRC);  \
    683   }
    684 
    685 #define DECLARE_PPC_X_INSTRUCTIONS_EH_S_FORM(name, instr_name, instr_value) \
    686   inline void name(const Register dst, const MemOperand& src) {             \
    687     x_form(instr_name, src.ra(), dst, src.rb(), SetEH);                     \
    688   }
    689 #define DECLARE_PPC_X_INSTRUCTIONS_EH_L_FORM(name, instr_name, instr_value) \
    690   inline void name(const Register dst, const MemOperand& src) {             \
    691     DCHECK(src.ra_ != r0);                                                  \
    692     x_form(instr_name, src.ra(), dst, src.rb(), SetEH);                     \
    693   }
    694 
    695   inline void x_form(Instr instr, int f1, int f2, int f3, int rc) {
    696     emit(instr | f1 * B21 | f2 * B16 | f3 * B11 | rc);
    697   }
    698   inline void x_form(Instr instr, Register rs, Register ra, Register rb,
    699                      RCBit rc) {
    700     emit(instr | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 | rc);
    701   }
    702   inline void x_form(Instr instr, Register ra, Register rs, Register rb,
    703                      EHBit eh = SetEH) {
    704     emit(instr | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 | eh);
    705   }
    706   inline void x_form(Instr instr, CRegister cr, Register s1, Register s2,
    707                      RCBit rc) {
    708 #if V8_TARGET_ARCH_PPC64
    709     int L = 1;
    710 #else
    711     int L = 0;
    712 #endif
    713     emit(instr | cr.code() * B23 | L * B21 | s1.code() * B16 |
    714          s2.code() * B11 | rc);
    715   }
    716 
    717   PPC_X_OPCODE_A_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_A_FORM)
    718   PPC_X_OPCODE_B_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_B_FORM)
    719   PPC_X_OPCODE_C_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_C_FORM)
    720   PPC_X_OPCODE_D_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_D_FORM)
    721   PPC_X_OPCODE_E_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_E_FORM)
    722   PPC_X_OPCODE_F_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_F_FORM)
    723   PPC_X_OPCODE_EH_S_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_EH_S_FORM)
    724   PPC_X_OPCODE_EH_L_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_EH_L_FORM)
    725 
    726   inline void notx(Register dst, Register src, RCBit rc = LeaveRC) {
    727     nor(dst, src, src, rc);
    728   }
    729   inline void lwax(Register rt, const MemOperand& src) {
    730 #if V8_TARGET_ARCH_PPC64
    731     Register ra = src.ra();
    732     Register rb = src.rb();
    733     DCHECK(ra != r0);
    734     x_form(LWAX, rt, ra, rb, LeaveRC);
    735 #else
    736     lwzx(rt, src);
    737 #endif
    738   }
    739   inline void extsw(Register rs, Register ra, RCBit rc = LeaveRC) {
    740 #if V8_TARGET_ARCH_PPC64
    741     emit(EXT2 | EXTSW | ra.code() * B21 | rs.code() * B16 | rc);
    742 #else
    743     // nop on 32-bit
    744     DCHECK(rs == ra && rc == LeaveRC);
    745 #endif
    746   }
    747 
    748 #undef DECLARE_PPC_X_INSTRUCTIONS_A_FORM
    749 #undef DECLARE_PPC_X_INSTRUCTIONS_B_FORM
    750 #undef DECLARE_PPC_X_INSTRUCTIONS_C_FORM
    751 #undef DECLARE_PPC_X_INSTRUCTIONS_D_FORM
    752 #undef DECLARE_PPC_X_INSTRUCTIONS_E_FORM
    753 #undef DECLARE_PPC_X_INSTRUCTIONS_F_FORM
    754 #undef DECLARE_PPC_X_INSTRUCTIONS_EH_S_FORM
    755 #undef DECLARE_PPC_X_INSTRUCTIONS_EH_L_FORM
    756 
    757 #define DECLARE_PPC_XX3_INSTRUCTIONS(name, instr_name, instr_value)  \
    758   inline void name(const DoubleRegister rt, const DoubleRegister ra, \
    759                    const DoubleRegister rb) {                        \
    760     xx3_form(instr_name, rt, ra, rb);                                \
    761   }
    762 
    763   inline void xx3_form(Instr instr, DoubleRegister t, DoubleRegister a,
    764                        DoubleRegister b) {
    765     int AX = ((a.code() & 0x20) >> 5) & 0x1;
    766     int BX = ((b.code() & 0x20) >> 5) & 0x1;
    767     int TX = ((t.code() & 0x20) >> 5) & 0x1;
    768 
    769     emit(instr | (t.code() & 0x1F) * B21 | (a.code() & 0x1F) * B16 |
    770          (b.code() & 0x1F) * B11 | AX * B2 | BX * B1 | TX);
    771   }
    772 
    773   PPC_XX3_OPCODE_LIST(DECLARE_PPC_XX3_INSTRUCTIONS)
    774 #undef DECLARE_PPC_XX3_INSTRUCTIONS
    775 
    776   // ---------------------------------------------------------------------------
    777   // Code generation
    778 
    779   // Insert the smallest number of nop instructions
    780   // possible to align the pc offset to a multiple
    781   // of m. m must be a power of 2 (>= 4).
    782   void Align(int m);
    783   // Insert the smallest number of zero bytes possible to align the pc offset
    784   // to a mulitple of m. m must be a power of 2 (>= 2).
    785   void DataAlign(int m);
    786   // Aligns code to something that's optimal for a jump target for the platform.
    787   void CodeTargetAlign();
    788 
    789   // Branch instructions
    790   void bclr(BOfield bo, int condition_bit, LKBit lk);
    791   void blr();
    792   void bc(int branch_offset, BOfield bo, int condition_bit, LKBit lk = LeaveLK);
    793   void b(int branch_offset, LKBit lk);
    794 
    795   void bcctr(BOfield bo, int condition_bit, LKBit lk);
    796   void bctr();
    797   void bctrl();
    798 
    799   // Convenience branch instructions using labels
    800   void b(Label* L, LKBit lk = LeaveLK) { b(branch_offset(L), lk); }
    801 
    802   inline CRegister cmpi_optimization(CRegister cr) {
    803     // Check whether the branch is preceded by an optimizable cmpi against 0.
    804     // The cmpi can be deleted if it is also preceded by an instruction that
    805     // sets the register used by the compare and supports a dot form.
    806     unsigned int sradi_mask = kOpcodeMask | kExt2OpcodeVariant2Mask;
    807     unsigned int srawi_mask = kOpcodeMask | kExt2OpcodeMask;
    808     int pos = pc_offset();
    809     int cmpi_pos = pc_offset() - kInstrSize;
    810 
    811     if (cmpi_pos > 0 && optimizable_cmpi_pos_ == cmpi_pos &&
    812         cmpi_cr_.code() == cr.code() && last_bound_pos_ != pos) {
    813       int xpos = cmpi_pos - kInstrSize;
    814       int xinstr = instr_at(xpos);
    815       int cmpi_ra = (instr_at(cmpi_pos) & 0x1f0000) >> 16;
    816       // ra is at the same bit position for the three cases below.
    817       int ra = (xinstr & 0x1f0000) >> 16;
    818       if (cmpi_ra == ra) {
    819         if ((xinstr & sradi_mask) == (EXT2 | SRADIX)) {
    820           cr = cr0;
    821           instr_at_put(xpos, xinstr | SetRC);
    822           pc_ -= kInstrSize;
    823         } else if ((xinstr & srawi_mask) == (EXT2 | SRAWIX)) {
    824           cr = cr0;
    825           instr_at_put(xpos, xinstr | SetRC);
    826           pc_ -= kInstrSize;
    827         } else if ((xinstr & kOpcodeMask) == ANDIx) {
    828           cr = cr0;
    829           pc_ -= kInstrSize;
    830           // nothing to do here since andi. records.
    831         }
    832         // didn't match one of the above, must keep cmpwi.
    833       }
    834     }
    835     return cr;
    836   }
    837 
    838   void bc_short(Condition cond, Label* L, CRegister cr = cr7,
    839                 LKBit lk = LeaveLK) {
    840     DCHECK(cond != al);
    841     DCHECK(cr.code() >= 0 && cr.code() <= 7);
    842 
    843     cr = cmpi_optimization(cr);
    844 
    845     int b_offset = branch_offset(L);
    846 
    847     switch (cond) {
    848       case eq:
    849         bc(b_offset, BT, encode_crbit(cr, CR_EQ), lk);
    850         break;
    851       case ne:
    852         bc(b_offset, BF, encode_crbit(cr, CR_EQ), lk);
    853         break;
    854       case gt:
    855         bc(b_offset, BT, encode_crbit(cr, CR_GT), lk);
    856         break;
    857       case le:
    858         bc(b_offset, BF, encode_crbit(cr, CR_GT), lk);
    859         break;
    860       case lt:
    861         bc(b_offset, BT, encode_crbit(cr, CR_LT), lk);
    862         break;
    863       case ge:
    864         bc(b_offset, BF, encode_crbit(cr, CR_LT), lk);
    865         break;
    866       case unordered:
    867         bc(b_offset, BT, encode_crbit(cr, CR_FU), lk);
    868         break;
    869       case ordered:
    870         bc(b_offset, BF, encode_crbit(cr, CR_FU), lk);
    871         break;
    872       case overflow:
    873         bc(b_offset, BT, encode_crbit(cr, CR_SO), lk);
    874         break;
    875       case nooverflow:
    876         bc(b_offset, BF, encode_crbit(cr, CR_SO), lk);
    877         break;
    878       default:
    879         UNIMPLEMENTED();
    880     }
    881   }
    882 
    883   void bclr(Condition cond, CRegister cr = cr7, LKBit lk = LeaveLK) {
    884     DCHECK(cond != al);
    885     DCHECK(cr.code() >= 0 && cr.code() <= 7);
    886 
    887     cr = cmpi_optimization(cr);
    888 
    889     switch (cond) {
    890       case eq:
    891         bclr(BT, encode_crbit(cr, CR_EQ), lk);
    892         break;
    893       case ne:
    894         bclr(BF, encode_crbit(cr, CR_EQ), lk);
    895         break;
    896       case gt:
    897         bclr(BT, encode_crbit(cr, CR_GT), lk);
    898         break;
    899       case le:
    900         bclr(BF, encode_crbit(cr, CR_GT), lk);
    901         break;
    902       case lt:
    903         bclr(BT, encode_crbit(cr, CR_LT), lk);
    904         break;
    905       case ge:
    906         bclr(BF, encode_crbit(cr, CR_LT), lk);
    907         break;
    908       case unordered:
    909         bclr(BT, encode_crbit(cr, CR_FU), lk);
    910         break;
    911       case ordered:
    912         bclr(BF, encode_crbit(cr, CR_FU), lk);
    913         break;
    914       case overflow:
    915         bclr(BT, encode_crbit(cr, CR_SO), lk);
    916         break;
    917       case nooverflow:
    918         bclr(BF, encode_crbit(cr, CR_SO), lk);
    919         break;
    920       default:
    921         UNIMPLEMENTED();
    922     }
    923   }
    924 
    925   void isel(Register rt, Register ra, Register rb, int cb);
    926   void isel(Condition cond, Register rt, Register ra, Register rb,
    927             CRegister cr = cr7) {
    928     DCHECK(cond != al);
    929     DCHECK(cr.code() >= 0 && cr.code() <= 7);
    930 
    931     cr = cmpi_optimization(cr);
    932 
    933     switch (cond) {
    934       case eq:
    935         isel(rt, ra, rb, encode_crbit(cr, CR_EQ));
    936         break;
    937       case ne:
    938         isel(rt, rb, ra, encode_crbit(cr, CR_EQ));
    939         break;
    940       case gt:
    941         isel(rt, ra, rb, encode_crbit(cr, CR_GT));
    942         break;
    943       case le:
    944         isel(rt, rb, ra, encode_crbit(cr, CR_GT));
    945         break;
    946       case lt:
    947         isel(rt, ra, rb, encode_crbit(cr, CR_LT));
    948         break;
    949       case ge:
    950         isel(rt, rb, ra, encode_crbit(cr, CR_LT));
    951         break;
    952       case unordered:
    953         isel(rt, ra, rb, encode_crbit(cr, CR_FU));
    954         break;
    955       case ordered:
    956         isel(rt, rb, ra, encode_crbit(cr, CR_FU));
    957         break;
    958       case overflow:
    959         isel(rt, ra, rb, encode_crbit(cr, CR_SO));
    960         break;
    961       case nooverflow:
    962         isel(rt, rb, ra, encode_crbit(cr, CR_SO));
    963         break;
    964       default:
    965         UNIMPLEMENTED();
    966     }
    967   }
    968 
    969   void b(Condition cond, Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
    970     if (cond == al) {
    971       b(L, lk);
    972       return;
    973     }
    974 
    975     if ((L->is_bound() && is_near(L, cond)) || !is_trampoline_emitted()) {
    976       bc_short(cond, L, cr, lk);
    977       return;
    978     }
    979 
    980     Label skip;
    981     Condition neg_cond = NegateCondition(cond);
    982     bc_short(neg_cond, &skip, cr);
    983     b(L, lk);
    984     bind(&skip);
    985   }
    986 
    987   void bne(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
    988     b(ne, L, cr, lk);
    989   }
    990   void beq(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
    991     b(eq, L, cr, lk);
    992   }
    993   void blt(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
    994     b(lt, L, cr, lk);
    995   }
    996   void bge(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
    997     b(ge, L, cr, lk);
    998   }
    999   void ble(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
   1000     b(le, L, cr, lk);
   1001   }
   1002   void bgt(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
   1003     b(gt, L, cr, lk);
   1004   }
   1005   void bunordered(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
   1006     b(unordered, L, cr, lk);
   1007   }
   1008   void bordered(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
   1009     b(ordered, L, cr, lk);
   1010   }
   1011   void boverflow(Label* L, CRegister cr = cr0, LKBit lk = LeaveLK) {
   1012     b(overflow, L, cr, lk);
   1013   }
   1014   void bnooverflow(Label* L, CRegister cr = cr0, LKBit lk = LeaveLK) {
   1015     b(nooverflow, L, cr, lk);
   1016   }
   1017 
   1018   // Decrement CTR; branch if CTR != 0
   1019   void bdnz(Label* L, LKBit lk = LeaveLK) {
   1020     bc(branch_offset(L), DCBNZ, 0, lk);
   1021   }
   1022 
   1023   // Data-processing instructions
   1024 
   1025   void sub(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
   1026            RCBit r = LeaveRC);
   1027 
   1028   void subc(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
   1029             RCBit r = LeaveRC);
   1030   void sube(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
   1031             RCBit r = LeaveRC);
   1032 
   1033   void subfic(Register dst, Register src, const Operand& imm);
   1034 
   1035   void add(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
   1036            RCBit r = LeaveRC);
   1037 
   1038   void addc(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
   1039             RCBit r = LeaveRC);
   1040   void adde(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
   1041             RCBit r = LeaveRC);
   1042   void addze(Register dst, Register src1, OEBit o = LeaveOE, RCBit r = LeaveRC);
   1043 
   1044   void mullw(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
   1045              RCBit r = LeaveRC);
   1046 
   1047   void mulhw(Register dst, Register src1, Register src2, RCBit r = LeaveRC);
   1048   void mulhwu(Register dst, Register src1, Register src2, RCBit r = LeaveRC);
   1049 
   1050   void divw(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
   1051             RCBit r = LeaveRC);
   1052   void divwu(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
   1053              RCBit r = LeaveRC);
   1054 
   1055   void addi(Register dst, Register src, const Operand& imm);
   1056   void addis(Register dst, Register src, const Operand& imm);
   1057   void addic(Register dst, Register src, const Operand& imm);
   1058 
   1059   void andi(Register ra, Register rs, const Operand& imm);
   1060   void andis(Register ra, Register rs, const Operand& imm);
   1061   void ori(Register dst, Register src, const Operand& imm);
   1062   void oris(Register dst, Register src, const Operand& imm);
   1063   void xori(Register dst, Register src, const Operand& imm);
   1064   void xoris(Register ra, Register rs, const Operand& imm);
   1065   void cmpi(Register src1, const Operand& src2, CRegister cr = cr7);
   1066   void cmpli(Register src1, const Operand& src2, CRegister cr = cr7);
   1067   void cmpwi(Register src1, const Operand& src2, CRegister cr = cr7);
   1068   void cmplwi(Register src1, const Operand& src2, CRegister cr = cr7);
   1069   void li(Register dst, const Operand& src);
   1070   void lis(Register dst, const Operand& imm);
   1071   void mr(Register dst, Register src);
   1072 
   1073   void lbz(Register dst, const MemOperand& src);
   1074   void lhz(Register dst, const MemOperand& src);
   1075   void lha(Register dst, const MemOperand& src);
   1076   void lwz(Register dst, const MemOperand& src);
   1077   void lwzu(Register dst, const MemOperand& src);
   1078   void lwa(Register dst, const MemOperand& src);
   1079   void stb(Register dst, const MemOperand& src);
   1080   void sth(Register dst, const MemOperand& src);
   1081   void stw(Register dst, const MemOperand& src);
   1082   void stwu(Register dst, const MemOperand& src);
   1083   void neg(Register rt, Register ra, OEBit o = LeaveOE, RCBit c = LeaveRC);
   1084 
   1085 #if V8_TARGET_ARCH_PPC64
   1086   void ld(Register rd, const MemOperand& src);
   1087   void ldu(Register rd, const MemOperand& src);
   1088   void std(Register rs, const MemOperand& src);
   1089   void stdu(Register rs, const MemOperand& src);
   1090   void rldic(Register dst, Register src, int sh, int mb, RCBit r = LeaveRC);
   1091   void rldicl(Register dst, Register src, int sh, int mb, RCBit r = LeaveRC);
   1092   void rldcl(Register ra, Register rs, Register rb, int mb, RCBit r = LeaveRC);
   1093   void rldicr(Register dst, Register src, int sh, int me, RCBit r = LeaveRC);
   1094   void rldimi(Register dst, Register src, int sh, int mb, RCBit r = LeaveRC);
   1095   void sldi(Register dst, Register src, const Operand& val, RCBit rc = LeaveRC);
   1096   void srdi(Register dst, Register src, const Operand& val, RCBit rc = LeaveRC);
   1097   void clrrdi(Register dst, Register src, const Operand& val,
   1098               RCBit rc = LeaveRC);
   1099   void clrldi(Register dst, Register src, const Operand& val,
   1100               RCBit rc = LeaveRC);
   1101   void sradi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
   1102   void rotld(Register ra, Register rs, Register rb, RCBit r = LeaveRC);
   1103   void rotldi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
   1104   void rotrdi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
   1105   void mulld(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
   1106              RCBit r = LeaveRC);
   1107   void divd(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
   1108             RCBit r = LeaveRC);
   1109   void divdu(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
   1110              RCBit r = LeaveRC);
   1111 #endif
   1112 
   1113   void rlwinm(Register ra, Register rs, int sh, int mb, int me,
   1114               RCBit rc = LeaveRC);
   1115   void rlwimi(Register ra, Register rs, int sh, int mb, int me,
   1116               RCBit rc = LeaveRC);
   1117   void rlwnm(Register ra, Register rs, Register rb, int mb, int me,
   1118              RCBit rc = LeaveRC);
   1119   void slwi(Register dst, Register src, const Operand& val, RCBit rc = LeaveRC);
   1120   void srwi(Register dst, Register src, const Operand& val, RCBit rc = LeaveRC);
   1121   void clrrwi(Register dst, Register src, const Operand& val,
   1122               RCBit rc = LeaveRC);
   1123   void clrlwi(Register dst, Register src, const Operand& val,
   1124               RCBit rc = LeaveRC);
   1125   void rotlw(Register ra, Register rs, Register rb, RCBit r = LeaveRC);
   1126   void rotlwi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
   1127   void rotrwi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
   1128 
   1129   void subi(Register dst, Register src1, const Operand& src2);
   1130 
   1131   void mov(Register dst, const Operand& src);
   1132   void bitwise_mov(Register dst, intptr_t value);
   1133   void bitwise_mov32(Register dst, int32_t value);
   1134   void bitwise_add32(Register dst, Register src, int32_t value);
   1135 
   1136   // Load the position of the label relative to the generated code object
   1137   // pointer in a register.
   1138   void mov_label_offset(Register dst, Label* label);
   1139 
   1140   // dst = base + label position + delta
   1141   void add_label_offset(Register dst, Register base, Label* label,
   1142                         int delta = 0);
   1143 
   1144   // Load the address of the label in a register and associate with an
   1145   // internal reference relocation.
   1146   void mov_label_addr(Register dst, Label* label);
   1147 
   1148   // Emit the address of the label (i.e. a jump table entry) and associate with
   1149   // an internal reference relocation.
   1150   void emit_label_addr(Label* label);
   1151 
   1152   // Multiply instructions
   1153   void mul(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
   1154            RCBit r = LeaveRC);
   1155 
   1156   // Miscellaneous arithmetic instructions
   1157 
   1158   // Special register access
   1159   void crxor(int bt, int ba, int bb);
   1160   void crclr(int bt) { crxor(bt, bt, bt); }
   1161   void creqv(int bt, int ba, int bb);
   1162   void crset(int bt) { creqv(bt, bt, bt); }
   1163   void mflr(Register dst);
   1164   void mtlr(Register src);
   1165   void mtctr(Register src);
   1166   void mtxer(Register src);
   1167   void mcrfs(CRegister cr, FPSCRBit bit);
   1168   void mfcr(Register dst);
   1169 #if V8_TARGET_ARCH_PPC64
   1170   void mffprd(Register dst, DoubleRegister src);
   1171   void mffprwz(Register dst, DoubleRegister src);
   1172   void mtfprd(DoubleRegister dst, Register src);
   1173   void mtfprwz(DoubleRegister dst, Register src);
   1174   void mtfprwa(DoubleRegister dst, Register src);
   1175 #endif
   1176 
   1177   void function_descriptor();
   1178 
   1179   // Exception-generating instructions and debugging support
   1180   void stop(const char* msg, Condition cond = al,
   1181             int32_t code = kDefaultStopCode, CRegister cr = cr7);
   1182 
   1183   void bkpt(uint32_t imm16);  // v5 and above
   1184 
   1185   void dcbf(Register ra, Register rb);
   1186   void sync();
   1187   void lwsync();
   1188   void icbi(Register ra, Register rb);
   1189   void isync();
   1190 
   1191   // Support for floating point
   1192   void lfd(const DoubleRegister frt, const MemOperand& src);
   1193   void lfdu(const DoubleRegister frt, const MemOperand& src);
   1194   void lfs(const DoubleRegister frt, const MemOperand& src);
   1195   void lfsu(const DoubleRegister frt, const MemOperand& src);
   1196   void stfd(const DoubleRegister frs, const MemOperand& src);
   1197   void stfdu(const DoubleRegister frs, const MemOperand& src);
   1198   void stfs(const DoubleRegister frs, const MemOperand& src);
   1199   void stfsu(const DoubleRegister frs, const MemOperand& src);
   1200 
   1201   void fadd(const DoubleRegister frt, const DoubleRegister fra,
   1202             const DoubleRegister frb, RCBit rc = LeaveRC);
   1203   void fsub(const DoubleRegister frt, const DoubleRegister fra,
   1204             const DoubleRegister frb, RCBit rc = LeaveRC);
   1205   void fdiv(const DoubleRegister frt, const DoubleRegister fra,
   1206             const DoubleRegister frb, RCBit rc = LeaveRC);
   1207   void fmul(const DoubleRegister frt, const DoubleRegister fra,
   1208             const DoubleRegister frc, RCBit rc = LeaveRC);
   1209   void fcmpu(const DoubleRegister fra, const DoubleRegister frb,
   1210              CRegister cr = cr7);
   1211   void fmr(const DoubleRegister frt, const DoubleRegister frb,
   1212            RCBit rc = LeaveRC);
   1213   void fctiwz(const DoubleRegister frt, const DoubleRegister frb);
   1214   void fctiw(const DoubleRegister frt, const DoubleRegister frb);
   1215   void frin(const DoubleRegister frt, const DoubleRegister frb,
   1216             RCBit rc = LeaveRC);
   1217   void friz(const DoubleRegister frt, const DoubleRegister frb,
   1218             RCBit rc = LeaveRC);
   1219   void frip(const DoubleRegister frt, const DoubleRegister frb,
   1220             RCBit rc = LeaveRC);
   1221   void frim(const DoubleRegister frt, const DoubleRegister frb,
   1222             RCBit rc = LeaveRC);
   1223   void frsp(const DoubleRegister frt, const DoubleRegister frb,
   1224             RCBit rc = LeaveRC);
   1225   void fcfid(const DoubleRegister frt, const DoubleRegister frb,
   1226              RCBit rc = LeaveRC);
   1227   void fcfidu(const DoubleRegister frt, const DoubleRegister frb,
   1228               RCBit rc = LeaveRC);
   1229   void fcfidus(const DoubleRegister frt, const DoubleRegister frb,
   1230                RCBit rc = LeaveRC);
   1231   void fcfids(const DoubleRegister frt, const DoubleRegister frb,
   1232               RCBit rc = LeaveRC);
   1233   void fctid(const DoubleRegister frt, const DoubleRegister frb,
   1234              RCBit rc = LeaveRC);
   1235   void fctidz(const DoubleRegister frt, const DoubleRegister frb,
   1236               RCBit rc = LeaveRC);
   1237   void fctidu(const DoubleRegister frt, const DoubleRegister frb,
   1238               RCBit rc = LeaveRC);
   1239   void fctiduz(const DoubleRegister frt, const DoubleRegister frb,
   1240                RCBit rc = LeaveRC);
   1241   void fsel(const DoubleRegister frt, const DoubleRegister fra,
   1242             const DoubleRegister frc, const DoubleRegister frb,
   1243             RCBit rc = LeaveRC);
   1244   void fneg(const DoubleRegister frt, const DoubleRegister frb,
   1245             RCBit rc = LeaveRC);
   1246   void mtfsb0(FPSCRBit bit, RCBit rc = LeaveRC);
   1247   void mtfsb1(FPSCRBit bit, RCBit rc = LeaveRC);
   1248   void mtfsfi(int bf, int immediate, RCBit rc = LeaveRC);
   1249   void mffs(const DoubleRegister frt, RCBit rc = LeaveRC);
   1250   void mtfsf(const DoubleRegister frb, bool L = 1, int FLM = 0, bool W = 0,
   1251              RCBit rc = LeaveRC);
   1252   void fsqrt(const DoubleRegister frt, const DoubleRegister frb,
   1253              RCBit rc = LeaveRC);
   1254   void fabs(const DoubleRegister frt, const DoubleRegister frb,
   1255             RCBit rc = LeaveRC);
   1256   void fmadd(const DoubleRegister frt, const DoubleRegister fra,
   1257              const DoubleRegister frc, const DoubleRegister frb,
   1258              RCBit rc = LeaveRC);
   1259   void fmsub(const DoubleRegister frt, const DoubleRegister fra,
   1260              const DoubleRegister frc, const DoubleRegister frb,
   1261              RCBit rc = LeaveRC);
   1262 
   1263   // Pseudo instructions
   1264 
   1265   // Different nop operations are used by the code generator to detect certain
   1266   // states of the generated code.
   1267   enum NopMarkerTypes {
   1268     NON_MARKING_NOP = 0,
   1269     GROUP_ENDING_NOP,
   1270     DEBUG_BREAK_NOP,
   1271     // IC markers.
   1272     PROPERTY_ACCESS_INLINED,
   1273     PROPERTY_ACCESS_INLINED_CONTEXT,
   1274     PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
   1275     // Helper values.
   1276     LAST_CODE_MARKER,
   1277     FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
   1278   };
   1279 
   1280   void nop(int type = 0);  // 0 is the default non-marking type.
   1281 
   1282   void push(Register src) {
   1283 #if V8_TARGET_ARCH_PPC64
   1284     stdu(src, MemOperand(sp, -kPointerSize));
   1285 #else
   1286     stwu(src, MemOperand(sp, -kPointerSize));
   1287 #endif
   1288   }
   1289 
   1290   void pop(Register dst) {
   1291 #if V8_TARGET_ARCH_PPC64
   1292     ld(dst, MemOperand(sp));
   1293 #else
   1294     lwz(dst, MemOperand(sp));
   1295 #endif
   1296     addi(sp, sp, Operand(kPointerSize));
   1297   }
   1298 
   1299   void pop() { addi(sp, sp, Operand(kPointerSize)); }
   1300 
   1301   // Jump unconditionally to given label.
   1302   void jmp(Label* L) { b(L); }
   1303 
   1304   // Check the code size generated from label to here.
   1305   int SizeOfCodeGeneratedSince(Label* label) {
   1306     return pc_offset() - label->pos();
   1307   }
   1308 
   1309   // Check the number of instructions generated from label to here.
   1310   int InstructionsGeneratedSince(Label* label) {
   1311     return SizeOfCodeGeneratedSince(label) / kInstrSize;
   1312   }
   1313 
   1314   // Class for scoping postponing the trampoline pool generation.
   1315   class BlockTrampolinePoolScope {
   1316    public:
   1317     explicit BlockTrampolinePoolScope(Assembler* assem) : assem_(assem) {
   1318       assem_->StartBlockTrampolinePool();
   1319     }
   1320     ~BlockTrampolinePoolScope() { assem_->EndBlockTrampolinePool(); }
   1321 
   1322    private:
   1323     Assembler* assem_;
   1324 
   1325     DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope);
   1326   };
   1327 
   1328   // Class for scoping disabling constant pool entry merging
   1329   class BlockConstantPoolEntrySharingScope {
   1330    public:
   1331     explicit BlockConstantPoolEntrySharingScope(Assembler* assem)
   1332         : assem_(assem) {
   1333       assem_->StartBlockConstantPoolEntrySharing();
   1334     }
   1335     ~BlockConstantPoolEntrySharingScope() {
   1336       assem_->EndBlockConstantPoolEntrySharing();
   1337     }
   1338 
   1339    private:
   1340     Assembler* assem_;
   1341 
   1342     DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstantPoolEntrySharingScope);
   1343   };
   1344 
   1345   // Record a comment relocation entry that can be used by a disassembler.
   1346   // Use --code-comments to enable.
   1347   void RecordComment(const char* msg);
   1348 
   1349   // Record a deoptimization reason that can be used by a log or cpu profiler.
   1350   // Use --trace-deopt to enable.
   1351   void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
   1352                          int id);
   1353 
   1354   // Writes a single byte or word of data in the code stream.  Used
   1355   // for inline tables, e.g., jump-tables.
   1356   void db(uint8_t data);
   1357   void dd(uint32_t data);
   1358   void dq(uint64_t data);
   1359   void dp(uintptr_t data);
   1360 
   1361   // Read/patch instructions
   1362   Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
   1363   void instr_at_put(int pos, Instr instr) {
   1364     *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
   1365   }
   1366   static Instr instr_at(Address pc) { return *reinterpret_cast<Instr*>(pc); }
   1367   static void instr_at_put(Address pc, Instr instr) {
   1368     *reinterpret_cast<Instr*>(pc) = instr;
   1369   }
   1370   static Condition GetCondition(Instr instr);
   1371 
   1372   static bool IsLis(Instr instr);
   1373   static bool IsLi(Instr instr);
   1374   static bool IsAddic(Instr instr);
   1375   static bool IsOri(Instr instr);
   1376 
   1377   static bool IsBranch(Instr instr);
   1378   static Register GetRA(Instr instr);
   1379   static Register GetRB(Instr instr);
   1380 #if V8_TARGET_ARCH_PPC64
   1381   static bool Is64BitLoadIntoR12(Instr instr1, Instr instr2, Instr instr3,
   1382                                  Instr instr4, Instr instr5);
   1383 #else
   1384   static bool Is32BitLoadIntoR12(Instr instr1, Instr instr2);
   1385 #endif
   1386 
   1387   static bool IsCmpRegister(Instr instr);
   1388   static bool IsCmpImmediate(Instr instr);
   1389   static bool IsRlwinm(Instr instr);
   1390   static bool IsAndi(Instr instr);
   1391 #if V8_TARGET_ARCH_PPC64
   1392   static bool IsRldicl(Instr instr);
   1393 #endif
   1394   static bool IsCrSet(Instr instr);
   1395   static Register GetCmpImmediateRegister(Instr instr);
   1396   static int GetCmpImmediateRawImmediate(Instr instr);
   1397   static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
   1398 
   1399   // Postpone the generation of the trampoline pool for the specified number of
   1400   // instructions.
   1401   void BlockTrampolinePoolFor(int instructions);
   1402   void CheckTrampolinePool();
   1403 
   1404   // For mov.  Return the number of actual instructions required to
   1405   // load the operand into a register.  This can be anywhere from
   1406   // one (constant pool small section) to five instructions (full
   1407   // 64-bit sequence).
   1408   //
   1409   // The value returned is only valid as long as no entries are added to the
   1410   // constant pool between this call and the actual instruction being emitted.
   1411   int instructions_required_for_mov(Register dst, const Operand& src) const;
   1412 
   1413   // Decide between using the constant pool vs. a mov immediate sequence.
   1414   bool use_constant_pool_for_mov(Register dst, const Operand& src,
   1415                                  bool canOptimize) const;
   1416 
   1417   // The code currently calls CheckBuffer() too often. This has the side
   1418   // effect of randomly growing the buffer in the middle of multi-instruction
   1419   // sequences.
   1420   //
   1421   // This function allows outside callers to check and grow the buffer
   1422   void EnsureSpaceFor(int space_needed);
   1423 
   1424   int EmitConstantPool() { return constant_pool_builder_.Emit(this); }
   1425 
   1426   bool ConstantPoolAccessIsInOverflow() const {
   1427     return constant_pool_builder_.NextAccess(ConstantPoolEntry::INTPTR) ==
   1428            ConstantPoolEntry::OVERFLOWED;
   1429   }
   1430 
   1431   Label* ConstantPoolPosition() {
   1432     return constant_pool_builder_.EmittedPosition();
   1433   }
   1434 
   1435   void EmitRelocations();
   1436 
   1437  protected:
   1438   int buffer_space() const { return reloc_info_writer.pos() - pc_; }
   1439 
   1440   // Decode instruction(s) at pos and return backchain to previous
   1441   // label reference or kEndOfChain.
   1442   int target_at(int pos);
   1443 
   1444   // Patch instruction(s) at pos to target target_pos (e.g. branch)
   1445   void target_at_put(int pos, int target_pos, bool* is_branch = nullptr);
   1446 
   1447   // Record reloc info for current pc_
   1448   void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
   1449   ConstantPoolEntry::Access ConstantPoolAddEntry(RelocInfo::Mode rmode,
   1450                                                  intptr_t value) {
   1451     bool sharing_ok = RelocInfo::IsNone(rmode) ||
   1452                       (!options().record_reloc_info_for_serialization &&
   1453                        RelocInfo::IsShareableRelocMode(rmode) &&
   1454                        !is_constant_pool_entry_sharing_blocked());
   1455     return constant_pool_builder_.AddEntry(pc_offset(), value, sharing_ok);
   1456   }
   1457   ConstantPoolEntry::Access ConstantPoolAddEntry(Double value) {
   1458     return constant_pool_builder_.AddEntry(pc_offset(), value);
   1459   }
   1460 
   1461   // Block the emission of the trampoline pool before pc_offset.
   1462   void BlockTrampolinePoolBefore(int pc_offset) {
   1463     if (no_trampoline_pool_before_ < pc_offset)
   1464       no_trampoline_pool_before_ = pc_offset;
   1465   }
   1466 
   1467   void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; }
   1468   void EndBlockTrampolinePool() {
   1469     int count = --trampoline_pool_blocked_nesting_;
   1470     if (count == 0) CheckTrampolinePoolQuick();
   1471   }
   1472   bool is_trampoline_pool_blocked() const {
   1473     return trampoline_pool_blocked_nesting_ > 0;
   1474   }
   1475 
   1476   void StartBlockConstantPoolEntrySharing() {
   1477     constant_pool_entry_sharing_blocked_nesting_++;
   1478   }
   1479   void EndBlockConstantPoolEntrySharing() {
   1480     constant_pool_entry_sharing_blocked_nesting_--;
   1481   }
   1482   bool is_constant_pool_entry_sharing_blocked() const {
   1483     return constant_pool_entry_sharing_blocked_nesting_ > 0;
   1484   }
   1485 
   1486   bool has_exception() const { return internal_trampoline_exception_; }
   1487 
   1488   bool is_trampoline_emitted() const { return trampoline_emitted_; }
   1489 
   1490   // Code generation
   1491   // The relocation writer's position is at least kGap bytes below the end of
   1492   // the generated instructions. This is so that multi-instruction sequences do
   1493   // not have to check for overflow. The same is true for writes of large
   1494   // relocation info entries.
   1495   static constexpr int kGap = 32;
   1496 
   1497   RelocInfoWriter reloc_info_writer;
   1498 
   1499  private:
   1500   // Avoid overflows for displacements etc.
   1501   static const int kMaximalBufferSize = 512 * MB;
   1502 
   1503   // Repeated checking whether the trampoline pool should be emitted is rather
   1504   // expensive. By default we only check again once a number of instructions
   1505   // has been generated.
   1506   int next_trampoline_check_;  // pc offset of next buffer check.
   1507 
   1508   // Emission of the trampoline pool may be blocked in some code sequences.
   1509   int trampoline_pool_blocked_nesting_;  // Block emission if this is not zero.
   1510   int no_trampoline_pool_before_;  // Block emission before this pc offset.
   1511 
   1512   // Do not share constant pool entries.
   1513   int constant_pool_entry_sharing_blocked_nesting_;
   1514 
   1515   // Relocation info generation
   1516   // Each relocation is encoded as a variable size value
   1517   static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize;
   1518   std::vector<DeferredRelocInfo> relocations_;
   1519 
   1520   // The bound position, before this we cannot do instruction elimination.
   1521   int last_bound_pos_;
   1522   // Optimizable cmpi information.
   1523   int optimizable_cmpi_pos_;
   1524   CRegister cmpi_cr_ = CRegister::no_reg();
   1525 
   1526   ConstantPoolBuilder constant_pool_builder_;
   1527 
   1528   void CheckBuffer() {
   1529     if (buffer_space() <= kGap) {
   1530       GrowBuffer();
   1531     }
   1532   }
   1533 
   1534   void GrowBuffer(int needed = 0);
   1535   // Code emission
   1536   void emit(Instr x) {
   1537     CheckBuffer();
   1538     *reinterpret_cast<Instr*>(pc_) = x;
   1539     pc_ += kInstrSize;
   1540     CheckTrampolinePoolQuick();
   1541   }
   1542   void TrackBranch() {
   1543     DCHECK(!trampoline_emitted_);
   1544     int count = tracked_branch_count_++;
   1545     if (count == 0) {
   1546       // We leave space (kMaxBlockTrampolineSectionSize)
   1547       // for BlockTrampolinePoolScope buffer.
   1548       next_trampoline_check_ =
   1549           pc_offset() + kMaxCondBranchReach - kMaxBlockTrampolineSectionSize;
   1550     } else {
   1551       next_trampoline_check_ -= kTrampolineSlotsSize;
   1552     }
   1553   }
   1554 
   1555   inline void UntrackBranch();
   1556   void CheckTrampolinePoolQuick() {
   1557     if (pc_offset() >= next_trampoline_check_) {
   1558       CheckTrampolinePool();
   1559     }
   1560   }
   1561 
   1562   // Instruction generation
   1563   void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra,
   1564               DoubleRegister frb, RCBit r);
   1565   void d_form(Instr instr, Register rt, Register ra, const intptr_t val,
   1566               bool signed_disp);
   1567   void xo_form(Instr instr, Register rt, Register ra, Register rb, OEBit o,
   1568                RCBit r);
   1569   void md_form(Instr instr, Register ra, Register rs, int shift, int maskbit,
   1570                RCBit r);
   1571   void mds_form(Instr instr, Register ra, Register rs, Register rb, int maskbit,
   1572                 RCBit r);
   1573 
   1574   // Labels
   1575   void print(Label* L);
   1576   int max_reach_from(int pos);
   1577   void bind_to(Label* L, int pos);
   1578   void next(Label* L);
   1579 
   1580   class Trampoline {
   1581    public:
   1582     Trampoline() {
   1583       next_slot_ = 0;
   1584       free_slot_count_ = 0;
   1585     }
   1586     Trampoline(int start, int slot_count) {
   1587       next_slot_ = start;
   1588       free_slot_count_ = slot_count;
   1589     }
   1590     int take_slot() {
   1591       int trampoline_slot = kInvalidSlotPos;
   1592       if (free_slot_count_ <= 0) {
   1593         // We have run out of space on trampolines.
   1594         // Make sure we fail in debug mode, so we become aware of each case
   1595         // when this happens.
   1596         DCHECK(0);
   1597         // Internal exception will be caught.
   1598       } else {
   1599         trampoline_slot = next_slot_;
   1600         free_slot_count_--;
   1601         next_slot_ += kTrampolineSlotsSize;
   1602       }
   1603       return trampoline_slot;
   1604     }
   1605 
   1606    private:
   1607     int next_slot_;
   1608     int free_slot_count_;
   1609   };
   1610 
   1611   int32_t get_trampoline_entry();
   1612   int tracked_branch_count_;
   1613   // If trampoline is emitted, generated code is becoming large. As
   1614   // this is already a slow case which can possibly break our code
   1615   // generation for the extreme case, we use this information to
   1616   // trigger different mode of branch instruction generation, where we
   1617   // no longer use a single branch instruction.
   1618   bool trampoline_emitted_;
   1619   static constexpr int kTrampolineSlotsSize = kInstrSize;
   1620   static constexpr int kMaxCondBranchReach = (1 << (16 - 1)) - 1;
   1621   static constexpr int kMaxBlockTrampolineSectionSize = 64 * kInstrSize;
   1622   static constexpr int kInvalidSlotPos = -1;
   1623 
   1624   Trampoline trampoline_;
   1625   bool internal_trampoline_exception_;
   1626 
   1627   void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
   1628 
   1629   friend class RegExpMacroAssemblerPPC;
   1630   friend class RelocInfo;
   1631   friend class BlockTrampolinePoolScope;
   1632   friend class EnsureSpace;
   1633 };
   1634 
   1635 
   1636 class EnsureSpace BASE_EMBEDDED {
   1637  public:
   1638   explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
   1639 };
   1640 
   1641 class PatchingAssembler : public Assembler {
   1642  public:
   1643   PatchingAssembler(const AssemblerOptions& options, byte* address,
   1644                     int instructions);
   1645   ~PatchingAssembler();
   1646 };
   1647 
   1648 }  // namespace internal
   1649 }  // namespace v8
   1650 
   1651 #endif  // V8_PPC_ASSEMBLER_PPC_H_
   1652