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