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