• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
from_codeRegister152   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;
is_validRegister160   bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
isRegister161   bool is(Register reg) const { return reg_code == reg.reg_code; }
codeRegister162   int code() const {
163     DCHECK(is_valid());
164     return reg_code;
165   }
bitRegister166   int bit() const {
167     DCHECK(is_valid());
168     return 1 << reg_code;
169   }
set_codeRegister170   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;
is_validDoubleRegister213   bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
isDoubleRegister214   bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
codeDoubleRegister215   int code() const {
216     DCHECK(is_valid());
217     return reg_code;
218   }
bitDoubleRegister219   int bit() const {
220     DCHECK(is_valid());
221     return 1 << reg_code;
222   }
223 
from_codeDoubleRegister224   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 {
is_validCRegister250   bool is_valid() const { return 0 <= reg_code && reg_code < 16; }
isCRegister251   bool is(CRegister creg) const { return reg_code == creg.reg_code; }
codeCRegister252   int code() const {
253     DCHECK(is_valid());
254     return reg_code;
255   }
bitCRegister256   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));
INLINE(static Operand Zero ())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 
immediate()313   inline intptr_t immediate() const {
314     DCHECK(!rm_.is_valid());
315     return imm_;
316   }
317 
rm()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 
offset()339   int32_t offset() const {
340     DCHECK(rb_.is(no_reg));
341     return offset_;
342   }
343 
344   // PowerPC - base register
ra()345   Register ra() const {
346     DCHECK(!ra_.is(no_reg));
347     return ra_;
348   }
349 
rb()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:
DeferredRelocInfo()366   DeferredRelocInfo() {}
DeferredRelocInfo(int position,RelocInfo::Mode rmode,intptr_t data)367   DeferredRelocInfo(int position, RelocInfo::Mode rmode, intptr_t data)
368       : position_(position), rmode_(rmode), data_(data) {}
369 
position()370   int position() const { return position_; }
rmode()371   RelocInfo::Mode rmode() const { return rmode_; }
data()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);
~Assembler()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
branch_offset(Label * L)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));
INLINE(static Address target_address_at (Address pc,Code * code))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   }
INLINE(static void set_target_address_at (Isolate * isolate,Address pc,Code * code,Address target,ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED))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 
encode_crbit(const CRegister & cr,enum CRBit crbit)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 
cmpi_optimization(CRegister cr)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);
crclr(int bt)983   void crclr(int bt) { crxor(bt, bt, bt); }
984   void creqv(int bt, int ba, int bb);
crset(int bt)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 
push(Register src)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 
pop(Register dst)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 
pop()1130   void pop() { addi(sp, sp, Operand(kPointerSize)); }
1131 
1132   // Jump unconditionally to given label.
jmp(Label * L)1133   void jmp(Label* L) { b(L); }
1134 
1135   // Check the code size generated from label to here.
SizeOfCodeGeneratedSince(Label * label)1136   int SizeOfCodeGeneratedSince(Label* label) {
1137     return pc_offset() - label->pos();
1138   }
1139 
1140   // Check the number of instructions generated from label to here.
InstructionsGeneratedSince(Label * label)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:
BlockTrampolinePoolScope(Assembler * assem)1148     explicit BlockTrampolinePoolScope(Assembler* assem) : assem_(assem) {
1149       assem_->StartBlockTrampolinePool();
1150     }
~BlockTrampolinePoolScope()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:
BlockConstantPoolEntrySharingScope(Assembler * assem)1162     explicit BlockConstantPoolEntrySharingScope(Assembler* assem)
1163         : assem_(assem) {
1164       assem_->StartBlockConstantPoolEntrySharing();
1165     }
~BlockConstantPoolEntrySharingScope()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.
SetRecordedAstId(TypeFeedbackId ast_id)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 
RecordedAstId()1192   TypeFeedbackId RecordedAstId() {
1193     // Causes compiler to fail
1194     // DCHECK(!recorded_ast_id_.IsNone());
1195     return recorded_ast_id_;
1196   }
1197 
ClearRecordedAstId()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 
positions_recorder()1215   PositionsRecorder* positions_recorder() { return &positions_recorder_; }
1216 
1217   // Read/patch instructions
instr_at(int pos)1218   Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
instr_at_put(int pos,Instr instr)1219   void instr_at_put(int pos, Instr instr) {
1220     *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
1221   }
instr_at(byte * pc)1222   static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
instr_at_put(byte * pc,Instr instr)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 
EmitConstantPool()1280   int EmitConstantPool() { return constant_pool_builder_.Emit(this); }
1281 
ConstantPoolAccessIsInOverflow()1282   bool ConstantPoolAccessIsInOverflow() const {
1283     return constant_pool_builder_.NextAccess(ConstantPoolEntry::INTPTR) ==
1284            ConstantPoolEntry::OVERFLOWED;
1285   }
1286 
ConstantPoolPosition()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 
buffer_space()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);
ConstantPoolAddEntry(RelocInfo::Mode rmode,intptr_t value)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   }
ConstantPoolAddEntry(double value)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.
BlockTrampolinePoolBefore(int 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 
StartBlockTrampolinePool()1327   void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; }
EndBlockTrampolinePool()1328   void EndBlockTrampolinePool() {
1329     int count = --trampoline_pool_blocked_nesting_;
1330     if (count == 0) CheckTrampolinePoolQuick();
1331   }
is_trampoline_pool_blocked()1332   bool is_trampoline_pool_blocked() const {
1333     return trampoline_pool_blocked_nesting_ > 0;
1334   }
1335 
StartBlockConstantPoolEntrySharing()1336   void StartBlockConstantPoolEntrySharing() {
1337     constant_pool_entry_sharing_blocked_nesting_++;
1338   }
EndBlockConstantPoolEntrySharing()1339   void EndBlockConstantPoolEntrySharing() {
1340     constant_pool_entry_sharing_blocked_nesting_--;
1341   }
is_constant_pool_entry_sharing_blocked()1342   bool is_constant_pool_entry_sharing_blocked() const {
1343     return constant_pool_entry_sharing_blocked_nesting_ > 0;
1344   }
1345 
has_exception()1346   bool has_exception() const { return internal_trampoline_exception_; }
1347 
is_trampoline_emitted()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:
Trampoline()1413     Trampoline() {
1414       next_slot_ = 0;
1415       free_slot_count_ = 0;
1416     }
Trampoline(int start,int slot_count)1417     Trampoline(int start, int slot_count) {
1418       next_slot_ = start;
1419       free_slot_count_ = slot_count;
1420     }
take_slot()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:
EnsureSpace(Assembler * assembler)1470   explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
1471 };
1472 }  // namespace internal
1473 }  // namespace v8
1474 
1475 #endif  // V8_PPC_ASSEMBLER_PPC_H_
1476