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