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