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