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