deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / src / ppc / assembler-ppc.cc
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 #include "src/v8.h"
38
39 #if V8_TARGET_ARCH_PPC
40
41 #include "src/base/bits.h"
42 #include "src/base/cpu.h"
43 #include "src/macro-assembler.h"
44 #include "src/ppc/assembler-ppc-inl.h"
45
46 namespace v8 {
47 namespace internal {
48
49 // Get the CPU features enabled by the build.
50 static unsigned CpuFeaturesImpliedByCompiler() {
51   unsigned answer = 0;
52   return answer;
53 }
54
55
56 void CpuFeatures::ProbeImpl(bool cross_compile) {
57   supported_ |= CpuFeaturesImpliedByCompiler();
58   cache_line_size_ = 128;
59
60   // Only use statically determined features for cross compile (snapshot).
61   if (cross_compile) return;
62
63 // Detect whether frim instruction is supported (POWER5+)
64 // For now we will just check for processors we know do not
65 // support it
66 #ifndef USE_SIMULATOR
67   // Probe for additional features at runtime.
68   base::CPU cpu;
69 #if V8_TARGET_ARCH_PPC64
70   if (cpu.part() == base::CPU::PPC_POWER8) {
71     supported_ |= (1u << FPR_GPR_MOV);
72   }
73 #endif
74   if (cpu.part() == base::CPU::PPC_POWER6 ||
75       cpu.part() == base::CPU::PPC_POWER7 ||
76       cpu.part() == base::CPU::PPC_POWER8) {
77     supported_ |= (1u << LWSYNC);
78   }
79   if (cpu.part() == base::CPU::PPC_POWER7 ||
80       cpu.part() == base::CPU::PPC_POWER8) {
81     supported_ |= (1u << ISELECT);
82   }
83 #if V8_OS_LINUX
84   if (!(cpu.part() == base::CPU::PPC_G5 || cpu.part() == base::CPU::PPC_G4)) {
85     // Assume support
86     supported_ |= (1u << FPU);
87   }
88 #elif V8_OS_AIX
89   // Assume support FP support and default cache line size
90   supported_ |= (1u << FPU);
91 #endif
92 #else  // Simulator
93   supported_ |= (1u << FPU);
94   supported_ |= (1u << LWSYNC);
95   supported_ |= (1u << ISELECT);
96 #if V8_TARGET_ARCH_PPC64
97   supported_ |= (1u << FPR_GPR_MOV);
98 #endif
99 #endif
100 }
101
102
103 void CpuFeatures::PrintTarget() {
104   const char* ppc_arch = NULL;
105
106 #if V8_TARGET_ARCH_PPC64
107   ppc_arch = "ppc64";
108 #else
109   ppc_arch = "ppc";
110 #endif
111
112   printf("target %s\n", ppc_arch);
113 }
114
115
116 void CpuFeatures::PrintFeatures() {
117   printf("FPU=%d\n", CpuFeatures::IsSupported(FPU));
118 }
119
120
121 Register ToRegister(int num) {
122   DCHECK(num >= 0 && num < kNumRegisters);
123   const Register kRegisters[] = {r0,  sp,  r2,  r3,  r4,  r5,  r6,  r7,
124                                  r8,  r9,  r10, r11, ip,  r13, r14, r15,
125                                  r16, r17, r18, r19, r20, r21, r22, r23,
126                                  r24, r25, r26, r27, r28, r29, r30, fp};
127   return kRegisters[num];
128 }
129
130
131 const char* DoubleRegister::AllocationIndexToString(int index) {
132   DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
133   const char* const names[] = {
134       "d1",  "d2",  "d3",  "d4",  "d5",  "d6",  "d7",  "d8",  "d9",  "d10",
135       "d11", "d12", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
136       "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"};
137   return names[index];
138 }
139
140
141 // -----------------------------------------------------------------------------
142 // Implementation of RelocInfo
143
144 const int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE |
145                                   1 << RelocInfo::INTERNAL_REFERENCE_ENCODED;
146
147
148 bool RelocInfo::IsCodedSpecially() {
149   // The deserializer needs to know whether a pointer is specially
150   // coded.  Being specially coded on PPC means that it is a lis/ori
151   // instruction sequence, and these are always the case inside code
152   // objects.
153   return true;
154 }
155
156
157 bool RelocInfo::IsInConstantPool() {
158   return false;
159 }
160
161
162 // -----------------------------------------------------------------------------
163 // Implementation of Operand and MemOperand
164 // See assembler-ppc-inl.h for inlined constructors
165
166 Operand::Operand(Handle<Object> handle) {
167   AllowDeferredHandleDereference using_raw_address;
168   rm_ = no_reg;
169   // Verify all Objects referred by code are NOT in new space.
170   Object* obj = *handle;
171   if (obj->IsHeapObject()) {
172     DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj));
173     imm_ = reinterpret_cast<intptr_t>(handle.location());
174     rmode_ = RelocInfo::EMBEDDED_OBJECT;
175   } else {
176     // no relocation needed
177     imm_ = reinterpret_cast<intptr_t>(obj);
178     rmode_ = kRelocInfo_NONEPTR;
179   }
180 }
181
182
183 MemOperand::MemOperand(Register rn, int32_t offset) {
184   ra_ = rn;
185   rb_ = no_reg;
186   offset_ = offset;
187 }
188
189
190 MemOperand::MemOperand(Register ra, Register rb) {
191   ra_ = ra;
192   rb_ = rb;
193   offset_ = 0;
194 }
195
196
197 // -----------------------------------------------------------------------------
198 // Specific instructions, constants, and masks.
199
200
201 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
202     : AssemblerBase(isolate, buffer, buffer_size),
203       recorded_ast_id_(TypeFeedbackId::None()),
204       positions_recorder_(this) {
205   reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
206
207   no_trampoline_pool_before_ = 0;
208   trampoline_pool_blocked_nesting_ = 0;
209   // We leave space (kMaxBlockTrampolineSectionSize)
210   // for BlockTrampolinePoolScope buffer.
211   next_buffer_check_ =
212       FLAG_force_long_branches ? kMaxInt : kMaxCondBranchReach -
213                                                kMaxBlockTrampolineSectionSize;
214   internal_trampoline_exception_ = false;
215   last_bound_pos_ = 0;
216   trampoline_emitted_ = FLAG_force_long_branches;
217   unbound_labels_count_ = 0;
218   ClearRecordedAstId();
219   relocations_.reserve(128);
220 }
221
222
223 void Assembler::GetCode(CodeDesc* desc) {
224   EmitRelocations();
225
226   // Set up code descriptor.
227   desc->buffer = buffer_;
228   desc->buffer_size = buffer_size_;
229   desc->instr_size = pc_offset();
230   desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
231   desc->origin = this;
232 }
233
234
235 void Assembler::Align(int m) {
236 #if V8_TARGET_ARCH_PPC64
237   DCHECK(m >= 4 && base::bits::IsPowerOfTwo64(m));
238 #else
239   DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
240 #endif
241   while ((pc_offset() & (m - 1)) != 0) {
242     nop();
243   }
244 }
245
246
247 void Assembler::CodeTargetAlign() { Align(8); }
248
249
250 Condition Assembler::GetCondition(Instr instr) {
251   switch (instr & kCondMask) {
252     case BT:
253       return eq;
254     case BF:
255       return ne;
256     default:
257       UNIMPLEMENTED();
258   }
259   return al;
260 }
261
262
263 bool Assembler::IsLis(Instr instr) {
264   return ((instr & kOpcodeMask) == ADDIS) && GetRA(instr).is(r0);
265 }
266
267
268 bool Assembler::IsLi(Instr instr) {
269   return ((instr & kOpcodeMask) == ADDI) && GetRA(instr).is(r0);
270 }
271
272
273 bool Assembler::IsAddic(Instr instr) { return (instr & kOpcodeMask) == ADDIC; }
274
275
276 bool Assembler::IsOri(Instr instr) { return (instr & kOpcodeMask) == ORI; }
277
278
279 bool Assembler::IsBranch(Instr instr) { return ((instr & kOpcodeMask) == BCX); }
280
281
282 Register Assembler::GetRA(Instr instr) {
283   Register reg;
284   reg.code_ = Instruction::RAValue(instr);
285   return reg;
286 }
287
288
289 Register Assembler::GetRB(Instr instr) {
290   Register reg;
291   reg.code_ = Instruction::RBValue(instr);
292   return reg;
293 }
294
295
296 #if V8_TARGET_ARCH_PPC64
297 // This code assumes a FIXED_SEQUENCE for 64bit loads (lis/ori)
298 bool Assembler::Is64BitLoadIntoR12(Instr instr1, Instr instr2, Instr instr3,
299                                    Instr instr4, Instr instr5) {
300   // Check the instructions are indeed a five part load (into r12)
301   // 3d800000       lis     r12, 0
302   // 618c0000       ori     r12, r12, 0
303   // 798c07c6       rldicr  r12, r12, 32, 31
304   // 658c00c3       oris    r12, r12, 195
305   // 618ccd40       ori     r12, r12, 52544
306   return (((instr1 >> 16) == 0x3d80) && ((instr2 >> 16) == 0x618c) &&
307           (instr3 == 0x798c07c6) && ((instr4 >> 16) == 0x658c) &&
308           ((instr5 >> 16) == 0x618c));
309 }
310 #else
311 // This code assumes a FIXED_SEQUENCE for 32bit loads (lis/ori)
312 bool Assembler::Is32BitLoadIntoR12(Instr instr1, Instr instr2) {
313   // Check the instruction is indeed a two part load (into r12)
314   // 3d802553       lis     r12, 9555
315   // 618c5000       ori   r12, r12, 20480
316   return (((instr1 >> 16) == 0x3d80) && ((instr2 >> 16) == 0x618c));
317 }
318 #endif
319
320
321 bool Assembler::IsCmpRegister(Instr instr) {
322   return (((instr & kOpcodeMask) == EXT2) &&
323           ((instr & kExt2OpcodeMask) == CMP));
324 }
325
326
327 bool Assembler::IsRlwinm(Instr instr) {
328   return ((instr & kOpcodeMask) == RLWINMX);
329 }
330
331
332 #if V8_TARGET_ARCH_PPC64
333 bool Assembler::IsRldicl(Instr instr) {
334   return (((instr & kOpcodeMask) == EXT5) &&
335           ((instr & kExt5OpcodeMask) == RLDICL));
336 }
337 #endif
338
339
340 bool Assembler::IsCmpImmediate(Instr instr) {
341   return ((instr & kOpcodeMask) == CMPI);
342 }
343
344
345 bool Assembler::IsCrSet(Instr instr) {
346   return (((instr & kOpcodeMask) == EXT1) &&
347           ((instr & kExt1OpcodeMask) == CREQV));
348 }
349
350
351 Register Assembler::GetCmpImmediateRegister(Instr instr) {
352   DCHECK(IsCmpImmediate(instr));
353   return GetRA(instr);
354 }
355
356
357 int Assembler::GetCmpImmediateRawImmediate(Instr instr) {
358   DCHECK(IsCmpImmediate(instr));
359   return instr & kOff16Mask;
360 }
361
362
363 // Labels refer to positions in the (to be) generated code.
364 // There are bound, linked, and unused labels.
365 //
366 // Bound labels refer to known positions in the already
367 // generated code. pos() is the position the label refers to.
368 //
369 // Linked labels refer to unknown positions in the code
370 // to be generated; pos() is the position of the last
371 // instruction using the label.
372
373
374 // The link chain is terminated by a negative code position (must be aligned)
375 const int kEndOfChain = -4;
376
377
378 // Dummy opcodes for unbound label mov instructions or jump table entries.
379 enum {
380   kUnboundMovLabelOffsetOpcode = 0 << 26,
381   kUnboundAddLabelOffsetOpcode = 1 << 26,
382   kUnboundMovLabelAddrOpcode = 2 << 26,
383   kUnboundJumpTableEntryOpcode = 3 << 26
384 };
385
386
387 int Assembler::target_at(int pos) {
388   Instr instr = instr_at(pos);
389   // check which type of branch this is 16 or 26 bit offset
390   int opcode = instr & kOpcodeMask;
391   int link;
392   switch (opcode) {
393     case BX:
394       link = SIGN_EXT_IMM26(instr & kImm26Mask);
395       link &= ~(kAAMask | kLKMask);  // discard AA|LK bits if present
396       break;
397     case BCX:
398       link = SIGN_EXT_IMM16((instr & kImm16Mask));
399       link &= ~(kAAMask | kLKMask);  // discard AA|LK bits if present
400       break;
401     case kUnboundMovLabelOffsetOpcode:
402     case kUnboundAddLabelOffsetOpcode:
403     case kUnboundMovLabelAddrOpcode:
404     case kUnboundJumpTableEntryOpcode:
405       link = SIGN_EXT_IMM26(instr & kImm26Mask);
406       link <<= 2;
407       break;
408     default:
409       DCHECK(false);
410       return -1;
411   }
412
413   if (link == 0) return kEndOfChain;
414   return pos + link;
415 }
416
417
418 void Assembler::target_at_put(int pos, int target_pos) {
419   Instr instr = instr_at(pos);
420   int opcode = instr & kOpcodeMask;
421
422   switch (opcode) {
423     case BX: {
424       int imm26 = target_pos - pos;
425       DCHECK(is_int26(imm26) && (imm26 & (kAAMask | kLKMask)) == 0);
426       if (imm26 == kInstrSize && !(instr & kLKMask)) {
427         // Branch to next instr without link.
428         instr = ORI;  // nop: ori, 0,0,0
429       } else {
430         instr &= ((~kImm26Mask) | kAAMask | kLKMask);
431         instr |= (imm26 & kImm26Mask);
432       }
433       instr_at_put(pos, instr);
434       break;
435     }
436     case BCX: {
437       int imm16 = target_pos - pos;
438       DCHECK(is_int16(imm16) && (imm16 & (kAAMask | kLKMask)) == 0);
439       if (imm16 == kInstrSize && !(instr & kLKMask)) {
440         // Branch to next instr without link.
441         instr = ORI;  // nop: ori, 0,0,0
442       } else {
443         instr &= ((~kImm16Mask) | kAAMask | kLKMask);
444         instr |= (imm16 & kImm16Mask);
445       }
446       instr_at_put(pos, instr);
447       break;
448     }
449     case kUnboundMovLabelOffsetOpcode: {
450       // Load the position of the label relative to the generated code object
451       // pointer in a register.
452       Register dst = Register::from_code(instr_at(pos + kInstrSize));
453       int32_t offset = target_pos + (Code::kHeaderSize - kHeapObjectTag);
454       CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos), 2,
455                           CodePatcher::DONT_FLUSH);
456       patcher.masm()->bitwise_mov32(dst, offset);
457       break;
458     }
459     case kUnboundAddLabelOffsetOpcode: {
460       // dst = base + position + immediate
461       Instr operands = instr_at(pos + kInstrSize);
462       Register dst = Register::from_code((operands >> 21) & 0x1f);
463       Register base = Register::from_code((operands >> 16) & 0x1f);
464       int32_t offset = target_pos + SIGN_EXT_IMM16(operands & kImm16Mask);
465       CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos), 2,
466                           CodePatcher::DONT_FLUSH);
467       patcher.masm()->bitwise_add32(dst, base, offset);
468       break;
469     }
470     case kUnboundMovLabelAddrOpcode: {
471       // Load the address of the label in a register.
472       Register dst = Register::from_code(instr_at(pos + kInstrSize));
473       CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
474                           kMovInstructions, CodePatcher::DONT_FLUSH);
475       // Keep internal references relative until EmitRelocations.
476       patcher.masm()->bitwise_mov(dst, target_pos);
477       break;
478     }
479     case kUnboundJumpTableEntryOpcode: {
480       CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
481                           kPointerSize / kInstrSize, CodePatcher::DONT_FLUSH);
482       // Keep internal references relative until EmitRelocations.
483       patcher.masm()->emit_ptr(target_pos);
484       break;
485     }
486     default:
487       DCHECK(false);
488       break;
489   }
490 }
491
492
493 int Assembler::max_reach_from(int pos) {
494   Instr instr = instr_at(pos);
495   int opcode = instr & kOpcodeMask;
496
497   // check which type of branch this is 16 or 26 bit offset
498   switch (opcode) {
499     case BX:
500       return 26;
501     case BCX:
502       return 16;
503     case kUnboundMovLabelOffsetOpcode:
504     case kUnboundAddLabelOffsetOpcode:
505     case kUnboundMovLabelAddrOpcode:
506     case kUnboundJumpTableEntryOpcode:
507       return 0;  // no limit on reach
508   }
509
510   DCHECK(false);
511   return 0;
512 }
513
514
515 void Assembler::bind_to(Label* L, int pos) {
516   DCHECK(0 <= pos && pos <= pc_offset());  // must have a valid binding position
517   int32_t trampoline_pos = kInvalidSlotPos;
518   if (L->is_linked() && !trampoline_emitted_) {
519     unbound_labels_count_--;
520     next_buffer_check_ += kTrampolineSlotsSize;
521   }
522
523   while (L->is_linked()) {
524     int fixup_pos = L->pos();
525     int32_t offset = pos - fixup_pos;
526     int maxReach = max_reach_from(fixup_pos);
527     next(L);  // call next before overwriting link with target at fixup_pos
528     if (maxReach && is_intn(offset, maxReach) == false) {
529       if (trampoline_pos == kInvalidSlotPos) {
530         trampoline_pos = get_trampoline_entry();
531         CHECK(trampoline_pos != kInvalidSlotPos);
532         target_at_put(trampoline_pos, pos);
533       }
534       target_at_put(fixup_pos, trampoline_pos);
535     } else {
536       target_at_put(fixup_pos, pos);
537     }
538   }
539   L->bind_to(pos);
540
541   // Keep track of the last bound label so we don't eliminate any instructions
542   // before a bound label.
543   if (pos > last_bound_pos_) last_bound_pos_ = pos;
544 }
545
546
547 void Assembler::bind(Label* L) {
548   DCHECK(!L->is_bound());  // label can only be bound once
549   bind_to(L, pc_offset());
550 }
551
552
553 void Assembler::next(Label* L) {
554   DCHECK(L->is_linked());
555   int link = target_at(L->pos());
556   if (link == kEndOfChain) {
557     L->Unuse();
558   } else {
559     DCHECK(link >= 0);
560     L->link_to(link);
561   }
562 }
563
564
565 bool Assembler::is_near(Label* L, Condition cond) {
566   DCHECK(L->is_bound());
567   if (L->is_bound() == false) return false;
568
569   int maxReach = ((cond == al) ? 26 : 16);
570   int offset = L->pos() - pc_offset();
571
572   return is_intn(offset, maxReach);
573 }
574
575
576 void Assembler::a_form(Instr instr, DoubleRegister frt, DoubleRegister fra,
577                        DoubleRegister frb, RCBit r) {
578   emit(instr | frt.code() * B21 | fra.code() * B16 | frb.code() * B11 | r);
579 }
580
581
582 void Assembler::d_form(Instr instr, Register rt, Register ra,
583                        const intptr_t val, bool signed_disp) {
584   if (signed_disp) {
585     if (!is_int16(val)) {
586       PrintF("val = %" V8PRIdPTR ", 0x%" V8PRIxPTR "\n", val, val);
587     }
588     DCHECK(is_int16(val));
589   } else {
590     if (!is_uint16(val)) {
591       PrintF("val = %" V8PRIdPTR ", 0x%" V8PRIxPTR
592              ", is_unsigned_imm16(val)=%d, kImm16Mask=0x%x\n",
593              val, val, is_uint16(val), kImm16Mask);
594     }
595     DCHECK(is_uint16(val));
596   }
597   emit(instr | rt.code() * B21 | ra.code() * B16 | (kImm16Mask & val));
598 }
599
600
601 void Assembler::x_form(Instr instr, Register ra, Register rs, Register rb,
602                        RCBit r) {
603   emit(instr | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 | r);
604 }
605
606
607 void Assembler::xo_form(Instr instr, Register rt, Register ra, Register rb,
608                         OEBit o, RCBit r) {
609   emit(instr | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 | o | r);
610 }
611
612
613 void Assembler::md_form(Instr instr, Register ra, Register rs, int shift,
614                         int maskbit, RCBit r) {
615   int sh0_4 = shift & 0x1f;
616   int sh5 = (shift >> 5) & 0x1;
617   int m0_4 = maskbit & 0x1f;
618   int m5 = (maskbit >> 5) & 0x1;
619
620   emit(instr | rs.code() * B21 | ra.code() * B16 | sh0_4 * B11 | m0_4 * B6 |
621        m5 * B5 | sh5 * B1 | r);
622 }
623
624
625 void Assembler::mds_form(Instr instr, Register ra, Register rs, Register rb,
626                          int maskbit, RCBit r) {
627   int m0_4 = maskbit & 0x1f;
628   int m5 = (maskbit >> 5) & 0x1;
629
630   emit(instr | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 | m0_4 * B6 |
631        m5 * B5 | r);
632 }
633
634
635 // Returns the next free trampoline entry.
636 int32_t Assembler::get_trampoline_entry() {
637   int32_t trampoline_entry = kInvalidSlotPos;
638
639   if (!internal_trampoline_exception_) {
640     trampoline_entry = trampoline_.take_slot();
641
642     if (kInvalidSlotPos == trampoline_entry) {
643       internal_trampoline_exception_ = true;
644     }
645   }
646   return trampoline_entry;
647 }
648
649
650 int Assembler::link(Label* L) {
651   int position;
652   if (L->is_bound()) {
653     position = L->pos();
654   } else {
655     if (L->is_linked()) {
656       position = L->pos();  // L's link
657     } else {
658       // was: target_pos = kEndOfChain;
659       // However, using self to mark the first reference
660       // should avoid most instances of branch offset overflow.  See
661       // target_at() for where this is converted back to kEndOfChain.
662       position = pc_offset();
663       if (!trampoline_emitted_) {
664         unbound_labels_count_++;
665         next_buffer_check_ -= kTrampolineSlotsSize;
666       }
667     }
668     L->link_to(pc_offset());
669   }
670
671   return position;
672 }
673
674
675 // Branch instructions.
676
677
678 void Assembler::bclr(BOfield bo, LKBit lk) {
679   positions_recorder()->WriteRecordedPositions();
680   emit(EXT1 | bo | BCLRX | lk);
681 }
682
683
684 void Assembler::bcctr(BOfield bo, LKBit lk) {
685   positions_recorder()->WriteRecordedPositions();
686   emit(EXT1 | bo | BCCTRX | lk);
687 }
688
689
690 // Pseudo op - branch to link register
691 void Assembler::blr() { bclr(BA, LeaveLK); }
692
693
694 // Pseudo op - branch to count register -- used for "jump"
695 void Assembler::bctr() { bcctr(BA, LeaveLK); }
696
697
698 void Assembler::bctrl() { bcctr(BA, SetLK); }
699
700
701 void Assembler::bc(int branch_offset, BOfield bo, int condition_bit, LKBit lk) {
702   if (lk == SetLK) {
703     positions_recorder()->WriteRecordedPositions();
704   }
705   DCHECK(is_int16(branch_offset));
706   emit(BCX | bo | condition_bit * B16 | (kImm16Mask & branch_offset) | lk);
707 }
708
709
710 void Assembler::b(int branch_offset, LKBit lk) {
711   if (lk == SetLK) {
712     positions_recorder()->WriteRecordedPositions();
713   }
714   DCHECK((branch_offset & 3) == 0);
715   int imm26 = branch_offset;
716   DCHECK(is_int26(imm26));
717   // todo add AA and LK bits
718   emit(BX | (imm26 & kImm26Mask) | lk);
719 }
720
721
722 void Assembler::xori(Register dst, Register src, const Operand& imm) {
723   d_form(XORI, src, dst, imm.imm_, false);
724 }
725
726
727 void Assembler::xoris(Register ra, Register rs, const Operand& imm) {
728   d_form(XORIS, rs, ra, imm.imm_, false);
729 }
730
731
732 void Assembler::xor_(Register dst, Register src1, Register src2, RCBit rc) {
733   x_form(EXT2 | XORX, dst, src1, src2, rc);
734 }
735
736
737 void Assembler::cntlzw_(Register ra, Register rs, RCBit rc) {
738   x_form(EXT2 | CNTLZWX, ra, rs, r0, rc);
739 }
740
741
742 void Assembler::and_(Register ra, Register rs, Register rb, RCBit rc) {
743   x_form(EXT2 | ANDX, ra, rs, rb, rc);
744 }
745
746
747 void Assembler::rlwinm(Register ra, Register rs, int sh, int mb, int me,
748                        RCBit rc) {
749   sh &= 0x1f;
750   mb &= 0x1f;
751   me &= 0x1f;
752   emit(RLWINMX | rs.code() * B21 | ra.code() * B16 | sh * B11 | mb * B6 |
753        me << 1 | rc);
754 }
755
756
757 void Assembler::rlwnm(Register ra, Register rs, Register rb, int mb, int me,
758                       RCBit rc) {
759   mb &= 0x1f;
760   me &= 0x1f;
761   emit(RLWNMX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 | mb * B6 |
762        me << 1 | rc);
763 }
764
765
766 void Assembler::rlwimi(Register ra, Register rs, int sh, int mb, int me,
767                        RCBit rc) {
768   sh &= 0x1f;
769   mb &= 0x1f;
770   me &= 0x1f;
771   emit(RLWIMIX | rs.code() * B21 | ra.code() * B16 | sh * B11 | mb * B6 |
772        me << 1 | rc);
773 }
774
775
776 void Assembler::slwi(Register dst, Register src, const Operand& val, RCBit rc) {
777   DCHECK((32 > val.imm_) && (val.imm_ >= 0));
778   rlwinm(dst, src, val.imm_, 0, 31 - val.imm_, rc);
779 }
780
781
782 void Assembler::srwi(Register dst, Register src, const Operand& val, RCBit rc) {
783   DCHECK((32 > val.imm_) && (val.imm_ >= 0));
784   rlwinm(dst, src, 32 - val.imm_, val.imm_, 31, rc);
785 }
786
787
788 void Assembler::clrrwi(Register dst, Register src, const Operand& val,
789                        RCBit rc) {
790   DCHECK((32 > val.imm_) && (val.imm_ >= 0));
791   rlwinm(dst, src, 0, 0, 31 - val.imm_, rc);
792 }
793
794
795 void Assembler::clrlwi(Register dst, Register src, const Operand& val,
796                        RCBit rc) {
797   DCHECK((32 > val.imm_) && (val.imm_ >= 0));
798   rlwinm(dst, src, 0, val.imm_, 31, rc);
799 }
800
801
802 void Assembler::srawi(Register ra, Register rs, int sh, RCBit r) {
803   emit(EXT2 | SRAWIX | rs.code() * B21 | ra.code() * B16 | sh * B11 | r);
804 }
805
806
807 void Assembler::srw(Register dst, Register src1, Register src2, RCBit r) {
808   x_form(EXT2 | SRWX, dst, src1, src2, r);
809 }
810
811
812 void Assembler::slw(Register dst, Register src1, Register src2, RCBit r) {
813   x_form(EXT2 | SLWX, dst, src1, src2, r);
814 }
815
816
817 void Assembler::sraw(Register ra, Register rs, Register rb, RCBit r) {
818   x_form(EXT2 | SRAW, ra, rs, rb, r);
819 }
820
821
822 void Assembler::rotlw(Register ra, Register rs, Register rb, RCBit r) {
823   rlwnm(ra, rs, rb, 0, 31, r);
824 }
825
826
827 void Assembler::rotlwi(Register ra, Register rs, int sh, RCBit r) {
828   rlwinm(ra, rs, sh, 0, 31, r);
829 }
830
831
832 void Assembler::rotrwi(Register ra, Register rs, int sh, RCBit r) {
833   rlwinm(ra, rs, 32 - sh, 0, 31, r);
834 }
835
836
837 void Assembler::subi(Register dst, Register src, const Operand& imm) {
838   addi(dst, src, Operand(-(imm.imm_)));
839 }
840
841 void Assembler::addc(Register dst, Register src1, Register src2, OEBit o,
842                      RCBit r) {
843   xo_form(EXT2 | ADDCX, dst, src1, src2, o, r);
844 }
845
846
847 void Assembler::addze(Register dst, Register src1, OEBit o, RCBit r) {
848   // a special xo_form
849   emit(EXT2 | ADDZEX | dst.code() * B21 | src1.code() * B16 | o | r);
850 }
851
852
853 void Assembler::sub(Register dst, Register src1, Register src2, OEBit o,
854                     RCBit r) {
855   xo_form(EXT2 | SUBFX, dst, src2, src1, o, r);
856 }
857
858
859 void Assembler::subfc(Register dst, Register src1, Register src2, OEBit o,
860                       RCBit r) {
861   xo_form(EXT2 | SUBFCX, dst, src2, src1, o, r);
862 }
863
864
865 void Assembler::subfic(Register dst, Register src, const Operand& imm) {
866   d_form(SUBFIC, dst, src, imm.imm_, true);
867 }
868
869
870 void Assembler::add(Register dst, Register src1, Register src2, OEBit o,
871                     RCBit r) {
872   xo_form(EXT2 | ADDX, dst, src1, src2, o, r);
873 }
874
875
876 // Multiply low word
877 void Assembler::mullw(Register dst, Register src1, Register src2, OEBit o,
878                       RCBit r) {
879   xo_form(EXT2 | MULLW, dst, src1, src2, o, r);
880 }
881
882
883 // Multiply hi word
884 void Assembler::mulhw(Register dst, Register src1, Register src2, RCBit r) {
885   xo_form(EXT2 | MULHWX, dst, src1, src2, LeaveOE, r);
886 }
887
888
889 // Multiply hi word unsigned
890 void Assembler::mulhwu(Register dst, Register src1, Register src2, RCBit r) {
891   xo_form(EXT2 | MULHWUX, dst, src1, src2, LeaveOE, r);
892 }
893
894
895 // Divide word
896 void Assembler::divw(Register dst, Register src1, Register src2, OEBit o,
897                      RCBit r) {
898   xo_form(EXT2 | DIVW, dst, src1, src2, o, r);
899 }
900
901
902 // Divide word unsigned
903 void Assembler::divwu(Register dst, Register src1, Register src2, OEBit o,
904                       RCBit r) {
905   xo_form(EXT2 | DIVWU, dst, src1, src2, o, r);
906 }
907
908
909 void Assembler::addi(Register dst, Register src, const Operand& imm) {
910   DCHECK(!src.is(r0));  // use li instead to show intent
911   d_form(ADDI, dst, src, imm.imm_, true);
912 }
913
914
915 void Assembler::addis(Register dst, Register src, const Operand& imm) {
916   DCHECK(!src.is(r0));  // use lis instead to show intent
917   d_form(ADDIS, dst, src, imm.imm_, true);
918 }
919
920
921 void Assembler::addic(Register dst, Register src, const Operand& imm) {
922   d_form(ADDIC, dst, src, imm.imm_, true);
923 }
924
925
926 void Assembler::andi(Register ra, Register rs, const Operand& imm) {
927   d_form(ANDIx, rs, ra, imm.imm_, false);
928 }
929
930
931 void Assembler::andis(Register ra, Register rs, const Operand& imm) {
932   d_form(ANDISx, rs, ra, imm.imm_, false);
933 }
934
935
936 void Assembler::nor(Register dst, Register src1, Register src2, RCBit r) {
937   x_form(EXT2 | NORX, dst, src1, src2, r);
938 }
939
940
941 void Assembler::notx(Register dst, Register src, RCBit r) {
942   x_form(EXT2 | NORX, dst, src, src, r);
943 }
944
945
946 void Assembler::ori(Register ra, Register rs, const Operand& imm) {
947   d_form(ORI, rs, ra, imm.imm_, false);
948 }
949
950
951 void Assembler::oris(Register dst, Register src, const Operand& imm) {
952   d_form(ORIS, src, dst, imm.imm_, false);
953 }
954
955
956 void Assembler::orx(Register dst, Register src1, Register src2, RCBit rc) {
957   x_form(EXT2 | ORX, dst, src1, src2, rc);
958 }
959
960
961 void Assembler::orc(Register dst, Register src1, Register src2, RCBit rc) {
962   x_form(EXT2 | ORC, dst, src1, src2, rc);
963 }
964
965
966 void Assembler::cmpi(Register src1, const Operand& src2, CRegister cr) {
967   intptr_t imm16 = src2.imm_;
968 #if V8_TARGET_ARCH_PPC64
969   int L = 1;
970 #else
971   int L = 0;
972 #endif
973   DCHECK(is_int16(imm16));
974   DCHECK(cr.code() >= 0 && cr.code() <= 7);
975   imm16 &= kImm16Mask;
976   emit(CMPI | cr.code() * B23 | L * B21 | src1.code() * B16 | imm16);
977 }
978
979
980 void Assembler::cmpli(Register src1, const Operand& src2, CRegister cr) {
981   uintptr_t uimm16 = src2.imm_;
982 #if V8_TARGET_ARCH_PPC64
983   int L = 1;
984 #else
985   int L = 0;
986 #endif
987   DCHECK(is_uint16(uimm16));
988   DCHECK(cr.code() >= 0 && cr.code() <= 7);
989   uimm16 &= kImm16Mask;
990   emit(CMPLI | cr.code() * B23 | L * B21 | src1.code() * B16 | uimm16);
991 }
992
993
994 void Assembler::cmp(Register src1, Register src2, CRegister cr) {
995 #if V8_TARGET_ARCH_PPC64
996   int L = 1;
997 #else
998   int L = 0;
999 #endif
1000   DCHECK(cr.code() >= 0 && cr.code() <= 7);
1001   emit(EXT2 | CMP | cr.code() * B23 | L * B21 | src1.code() * B16 |
1002        src2.code() * B11);
1003 }
1004
1005
1006 void Assembler::cmpl(Register src1, Register src2, CRegister cr) {
1007 #if V8_TARGET_ARCH_PPC64
1008   int L = 1;
1009 #else
1010   int L = 0;
1011 #endif
1012   DCHECK(cr.code() >= 0 && cr.code() <= 7);
1013   emit(EXT2 | CMPL | cr.code() * B23 | L * B21 | src1.code() * B16 |
1014        src2.code() * B11);
1015 }
1016
1017
1018 void Assembler::cmpwi(Register src1, const Operand& src2, CRegister cr) {
1019   intptr_t imm16 = src2.imm_;
1020   int L = 0;
1021   DCHECK(is_int16(imm16));
1022   DCHECK(cr.code() >= 0 && cr.code() <= 7);
1023   imm16 &= kImm16Mask;
1024   emit(CMPI | cr.code() * B23 | L * B21 | src1.code() * B16 | imm16);
1025 }
1026
1027
1028 void Assembler::cmplwi(Register src1, const Operand& src2, CRegister cr) {
1029   uintptr_t uimm16 = src2.imm_;
1030   int L = 0;
1031   DCHECK(is_uint16(uimm16));
1032   DCHECK(cr.code() >= 0 && cr.code() <= 7);
1033   uimm16 &= kImm16Mask;
1034   emit(CMPLI | cr.code() * B23 | L * B21 | src1.code() * B16 | uimm16);
1035 }
1036
1037
1038 void Assembler::cmpw(Register src1, Register src2, CRegister cr) {
1039   int L = 0;
1040   DCHECK(cr.code() >= 0 && cr.code() <= 7);
1041   emit(EXT2 | CMP | cr.code() * B23 | L * B21 | src1.code() * B16 |
1042        src2.code() * B11);
1043 }
1044
1045
1046 void Assembler::cmplw(Register src1, Register src2, CRegister cr) {
1047   int L = 0;
1048   DCHECK(cr.code() >= 0 && cr.code() <= 7);
1049   emit(EXT2 | CMPL | cr.code() * B23 | L * B21 | src1.code() * B16 |
1050        src2.code() * B11);
1051 }
1052
1053
1054 void Assembler::isel(Register rt, Register ra, Register rb, int cb) {
1055   emit(EXT2 | ISEL | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1056        cb * B6);
1057 }
1058
1059
1060 // Pseudo op - load immediate
1061 void Assembler::li(Register dst, const Operand& imm) {
1062   d_form(ADDI, dst, r0, imm.imm_, true);
1063 }
1064
1065
1066 void Assembler::lis(Register dst, const Operand& imm) {
1067   d_form(ADDIS, dst, r0, imm.imm_, true);
1068 }
1069
1070
1071 // Pseudo op - move register
1072 void Assembler::mr(Register dst, Register src) {
1073   // actually or(dst, src, src)
1074   orx(dst, src, src);
1075 }
1076
1077
1078 void Assembler::lbz(Register dst, const MemOperand& src) {
1079   DCHECK(!src.ra_.is(r0));
1080   d_form(LBZ, dst, src.ra(), src.offset(), true);
1081 }
1082
1083
1084 void Assembler::lbzx(Register rt, const MemOperand& src) {
1085   Register ra = src.ra();
1086   Register rb = src.rb();
1087   DCHECK(!ra.is(r0));
1088   emit(EXT2 | LBZX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1089        LeaveRC);
1090 }
1091
1092
1093 void Assembler::lbzux(Register rt, const MemOperand& src) {
1094   Register ra = src.ra();
1095   Register rb = src.rb();
1096   DCHECK(!ra.is(r0));
1097   emit(EXT2 | LBZUX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1098        LeaveRC);
1099 }
1100
1101
1102 void Assembler::lhz(Register dst, const MemOperand& src) {
1103   DCHECK(!src.ra_.is(r0));
1104   d_form(LHZ, dst, src.ra(), src.offset(), true);
1105 }
1106
1107
1108 void Assembler::lhzx(Register rt, const MemOperand& src) {
1109   Register ra = src.ra();
1110   Register rb = src.rb();
1111   DCHECK(!ra.is(r0));
1112   emit(EXT2 | LHZX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1113        LeaveRC);
1114 }
1115
1116
1117 void Assembler::lhzux(Register rt, const MemOperand& src) {
1118   Register ra = src.ra();
1119   Register rb = src.rb();
1120   DCHECK(!ra.is(r0));
1121   emit(EXT2 | LHZUX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1122        LeaveRC);
1123 }
1124
1125
1126 void Assembler::lhax(Register rt, const MemOperand& src) {
1127   Register ra = src.ra();
1128   Register rb = src.rb();
1129   DCHECK(!ra.is(r0));
1130   emit(EXT2 | LHAX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11);
1131 }
1132
1133
1134 void Assembler::lwz(Register dst, const MemOperand& src) {
1135   DCHECK(!src.ra_.is(r0));
1136   d_form(LWZ, dst, src.ra(), src.offset(), true);
1137 }
1138
1139
1140 void Assembler::lwzu(Register dst, const MemOperand& src) {
1141   DCHECK(!src.ra_.is(r0));
1142   d_form(LWZU, dst, src.ra(), src.offset(), true);
1143 }
1144
1145
1146 void Assembler::lwzx(Register rt, const MemOperand& src) {
1147   Register ra = src.ra();
1148   Register rb = src.rb();
1149   DCHECK(!ra.is(r0));
1150   emit(EXT2 | LWZX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1151        LeaveRC);
1152 }
1153
1154
1155 void Assembler::lwzux(Register rt, const MemOperand& src) {
1156   Register ra = src.ra();
1157   Register rb = src.rb();
1158   DCHECK(!ra.is(r0));
1159   emit(EXT2 | LWZUX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1160        LeaveRC);
1161 }
1162
1163
1164 void Assembler::lha(Register dst, const MemOperand& src) {
1165   DCHECK(!src.ra_.is(r0));
1166   d_form(LHA, dst, src.ra(), src.offset(), true);
1167 }
1168
1169
1170 void Assembler::lwa(Register dst, const MemOperand& src) {
1171 #if V8_TARGET_ARCH_PPC64
1172   int offset = src.offset();
1173   DCHECK(!src.ra_.is(r0));
1174   DCHECK(!(offset & 3) && is_int16(offset));
1175   offset = kImm16Mask & offset;
1176   emit(LD | dst.code() * B21 | src.ra().code() * B16 | offset | 2);
1177 #else
1178   lwz(dst, src);
1179 #endif
1180 }
1181
1182
1183 void Assembler::lwax(Register rt, const MemOperand& src) {
1184 #if V8_TARGET_ARCH_PPC64
1185   Register ra = src.ra();
1186   Register rb = src.rb();
1187   DCHECK(!ra.is(r0));
1188   emit(EXT2 | LWAX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11);
1189 #else
1190   lwzx(rt, src);
1191 #endif
1192 }
1193
1194
1195 void Assembler::stb(Register dst, const MemOperand& src) {
1196   DCHECK(!src.ra_.is(r0));
1197   d_form(STB, dst, src.ra(), src.offset(), true);
1198 }
1199
1200
1201 void Assembler::stbx(Register rs, const MemOperand& src) {
1202   Register ra = src.ra();
1203   Register rb = src.rb();
1204   DCHECK(!ra.is(r0));
1205   emit(EXT2 | STBX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1206        LeaveRC);
1207 }
1208
1209
1210 void Assembler::stbux(Register rs, const MemOperand& src) {
1211   Register ra = src.ra();
1212   Register rb = src.rb();
1213   DCHECK(!ra.is(r0));
1214   emit(EXT2 | STBUX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1215        LeaveRC);
1216 }
1217
1218
1219 void Assembler::sth(Register dst, const MemOperand& src) {
1220   DCHECK(!src.ra_.is(r0));
1221   d_form(STH, dst, src.ra(), src.offset(), true);
1222 }
1223
1224
1225 void Assembler::sthx(Register rs, const MemOperand& src) {
1226   Register ra = src.ra();
1227   Register rb = src.rb();
1228   DCHECK(!ra.is(r0));
1229   emit(EXT2 | STHX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1230        LeaveRC);
1231 }
1232
1233
1234 void Assembler::sthux(Register rs, const MemOperand& src) {
1235   Register ra = src.ra();
1236   Register rb = src.rb();
1237   DCHECK(!ra.is(r0));
1238   emit(EXT2 | STHUX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1239        LeaveRC);
1240 }
1241
1242
1243 void Assembler::stw(Register dst, const MemOperand& src) {
1244   DCHECK(!src.ra_.is(r0));
1245   d_form(STW, dst, src.ra(), src.offset(), true);
1246 }
1247
1248
1249 void Assembler::stwu(Register dst, const MemOperand& src) {
1250   DCHECK(!src.ra_.is(r0));
1251   d_form(STWU, dst, src.ra(), src.offset(), true);
1252 }
1253
1254
1255 void Assembler::stwx(Register rs, const MemOperand& src) {
1256   Register ra = src.ra();
1257   Register rb = src.rb();
1258   DCHECK(!ra.is(r0));
1259   emit(EXT2 | STWX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1260        LeaveRC);
1261 }
1262
1263
1264 void Assembler::stwux(Register rs, const MemOperand& src) {
1265   Register ra = src.ra();
1266   Register rb = src.rb();
1267   DCHECK(!ra.is(r0));
1268   emit(EXT2 | STWUX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1269        LeaveRC);
1270 }
1271
1272
1273 void Assembler::extsb(Register rs, Register ra, RCBit rc) {
1274   emit(EXT2 | EXTSB | ra.code() * B21 | rs.code() * B16 | rc);
1275 }
1276
1277
1278 void Assembler::extsh(Register rs, Register ra, RCBit rc) {
1279   emit(EXT2 | EXTSH | ra.code() * B21 | rs.code() * B16 | rc);
1280 }
1281
1282
1283 void Assembler::extsw(Register rs, Register ra, RCBit rc) {
1284 #if V8_TARGET_ARCH_PPC64
1285   emit(EXT2 | EXTSW | ra.code() * B21 | rs.code() * B16 | rc);
1286 #else
1287   // nop on 32-bit
1288   DCHECK(rs.is(ra) && rc == LeaveRC);
1289 #endif
1290 }
1291
1292
1293 void Assembler::neg(Register rt, Register ra, OEBit o, RCBit r) {
1294   emit(EXT2 | NEGX | rt.code() * B21 | ra.code() * B16 | o | r);
1295 }
1296
1297
1298 void Assembler::andc(Register dst, Register src1, Register src2, RCBit rc) {
1299   x_form(EXT2 | ANDCX, dst, src1, src2, rc);
1300 }
1301
1302
1303 #if V8_TARGET_ARCH_PPC64
1304 // 64bit specific instructions
1305 void Assembler::ld(Register rd, const MemOperand& src) {
1306   int offset = src.offset();
1307   DCHECK(!src.ra_.is(r0));
1308   DCHECK(!(offset & 3) && is_int16(offset));
1309   offset = kImm16Mask & offset;
1310   emit(LD | rd.code() * B21 | src.ra().code() * B16 | offset);
1311 }
1312
1313
1314 void Assembler::ldx(Register rd, const MemOperand& src) {
1315   Register ra = src.ra();
1316   Register rb = src.rb();
1317   DCHECK(!ra.is(r0));
1318   emit(EXT2 | LDX | rd.code() * B21 | ra.code() * B16 | rb.code() * B11);
1319 }
1320
1321
1322 void Assembler::ldu(Register rd, const MemOperand& src) {
1323   int offset = src.offset();
1324   DCHECK(!src.ra_.is(r0));
1325   DCHECK(!(offset & 3) && is_int16(offset));
1326   offset = kImm16Mask & offset;
1327   emit(LD | rd.code() * B21 | src.ra().code() * B16 | offset | 1);
1328 }
1329
1330
1331 void Assembler::ldux(Register rd, const MemOperand& src) {
1332   Register ra = src.ra();
1333   Register rb = src.rb();
1334   DCHECK(!ra.is(r0));
1335   emit(EXT2 | LDUX | rd.code() * B21 | ra.code() * B16 | rb.code() * B11);
1336 }
1337
1338
1339 void Assembler::std(Register rs, const MemOperand& src) {
1340   int offset = src.offset();
1341   DCHECK(!src.ra_.is(r0));
1342   DCHECK(!(offset & 3) && is_int16(offset));
1343   offset = kImm16Mask & offset;
1344   emit(STD | rs.code() * B21 | src.ra().code() * B16 | offset);
1345 }
1346
1347
1348 void Assembler::stdx(Register rs, const MemOperand& src) {
1349   Register ra = src.ra();
1350   Register rb = src.rb();
1351   DCHECK(!ra.is(r0));
1352   emit(EXT2 | STDX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11);
1353 }
1354
1355
1356 void Assembler::stdu(Register rs, const MemOperand& src) {
1357   int offset = src.offset();
1358   DCHECK(!src.ra_.is(r0));
1359   DCHECK(!(offset & 3) && is_int16(offset));
1360   offset = kImm16Mask & offset;
1361   emit(STD | rs.code() * B21 | src.ra().code() * B16 | offset | 1);
1362 }
1363
1364
1365 void Assembler::stdux(Register rs, const MemOperand& src) {
1366   Register ra = src.ra();
1367   Register rb = src.rb();
1368   DCHECK(!ra.is(r0));
1369   emit(EXT2 | STDUX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11);
1370 }
1371
1372
1373 void Assembler::rldic(Register ra, Register rs, int sh, int mb, RCBit r) {
1374   md_form(EXT5 | RLDIC, ra, rs, sh, mb, r);
1375 }
1376
1377
1378 void Assembler::rldicl(Register ra, Register rs, int sh, int mb, RCBit r) {
1379   md_form(EXT5 | RLDICL, ra, rs, sh, mb, r);
1380 }
1381
1382
1383 void Assembler::rldcl(Register ra, Register rs, Register rb, int mb, RCBit r) {
1384   mds_form(EXT5 | RLDCL, ra, rs, rb, mb, r);
1385 }
1386
1387
1388 void Assembler::rldicr(Register ra, Register rs, int sh, int me, RCBit r) {
1389   md_form(EXT5 | RLDICR, ra, rs, sh, me, r);
1390 }
1391
1392
1393 void Assembler::sldi(Register dst, Register src, const Operand& val, RCBit rc) {
1394   DCHECK((64 > val.imm_) && (val.imm_ >= 0));
1395   rldicr(dst, src, val.imm_, 63 - val.imm_, rc);
1396 }
1397
1398
1399 void Assembler::srdi(Register dst, Register src, const Operand& val, RCBit rc) {
1400   DCHECK((64 > val.imm_) && (val.imm_ >= 0));
1401   rldicl(dst, src, 64 - val.imm_, val.imm_, rc);
1402 }
1403
1404
1405 void Assembler::clrrdi(Register dst, Register src, const Operand& val,
1406                        RCBit rc) {
1407   DCHECK((64 > val.imm_) && (val.imm_ >= 0));
1408   rldicr(dst, src, 0, 63 - val.imm_, rc);
1409 }
1410
1411
1412 void Assembler::clrldi(Register dst, Register src, const Operand& val,
1413                        RCBit rc) {
1414   DCHECK((64 > val.imm_) && (val.imm_ >= 0));
1415   rldicl(dst, src, 0, val.imm_, rc);
1416 }
1417
1418
1419 void Assembler::rldimi(Register ra, Register rs, int sh, int mb, RCBit r) {
1420   md_form(EXT5 | RLDIMI, ra, rs, sh, mb, r);
1421 }
1422
1423
1424 void Assembler::sradi(Register ra, Register rs, int sh, RCBit r) {
1425   int sh0_4 = sh & 0x1f;
1426   int sh5 = (sh >> 5) & 0x1;
1427
1428   emit(EXT2 | SRADIX | rs.code() * B21 | ra.code() * B16 | sh0_4 * B11 |
1429        sh5 * B1 | r);
1430 }
1431
1432
1433 void Assembler::srd(Register dst, Register src1, Register src2, RCBit r) {
1434   x_form(EXT2 | SRDX, dst, src1, src2, r);
1435 }
1436
1437
1438 void Assembler::sld(Register dst, Register src1, Register src2, RCBit r) {
1439   x_form(EXT2 | SLDX, dst, src1, src2, r);
1440 }
1441
1442
1443 void Assembler::srad(Register ra, Register rs, Register rb, RCBit r) {
1444   x_form(EXT2 | SRAD, ra, rs, rb, r);
1445 }
1446
1447
1448 void Assembler::rotld(Register ra, Register rs, Register rb, RCBit r) {
1449   rldcl(ra, rs, rb, 0, r);
1450 }
1451
1452
1453 void Assembler::rotldi(Register ra, Register rs, int sh, RCBit r) {
1454   rldicl(ra, rs, sh, 0, r);
1455 }
1456
1457
1458 void Assembler::rotrdi(Register ra, Register rs, int sh, RCBit r) {
1459   rldicl(ra, rs, 64 - sh, 0, r);
1460 }
1461
1462
1463 void Assembler::cntlzd_(Register ra, Register rs, RCBit rc) {
1464   x_form(EXT2 | CNTLZDX, ra, rs, r0, rc);
1465 }
1466
1467
1468 void Assembler::mulld(Register dst, Register src1, Register src2, OEBit o,
1469                       RCBit r) {
1470   xo_form(EXT2 | MULLD, dst, src1, src2, o, r);
1471 }
1472
1473
1474 void Assembler::divd(Register dst, Register src1, Register src2, OEBit o,
1475                      RCBit r) {
1476   xo_form(EXT2 | DIVD, dst, src1, src2, o, r);
1477 }
1478
1479
1480 void Assembler::divdu(Register dst, Register src1, Register src2, OEBit o,
1481                       RCBit r) {
1482   xo_form(EXT2 | DIVDU, dst, src1, src2, o, r);
1483 }
1484 #endif
1485
1486
1487 // Function descriptor for AIX.
1488 // Code address skips the function descriptor "header".
1489 // TOC and static chain are ignored and set to 0.
1490 void Assembler::function_descriptor() {
1491 #if ABI_USES_FUNCTION_DESCRIPTORS
1492   Label instructions;
1493   DCHECK(pc_offset() == 0);
1494   emit_label_addr(&instructions);
1495   emit_ptr(0);
1496   emit_ptr(0);
1497   bind(&instructions);
1498 #endif
1499 }
1500
1501
1502 void Assembler::EnsureSpaceFor(int space_needed) {
1503   if (buffer_space() <= (kGap + space_needed)) {
1504     GrowBuffer(space_needed);
1505   }
1506 }
1507
1508
1509 bool Operand::must_output_reloc_info(const Assembler* assembler) const {
1510   if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
1511     if (assembler != NULL && assembler->predictable_code_size()) return true;
1512     return assembler->serializer_enabled();
1513   } else if (RelocInfo::IsNone(rmode_)) {
1514     return false;
1515   }
1516   return true;
1517 }
1518
1519
1520 // Primarily used for loading constants
1521 // This should really move to be in macro-assembler as it
1522 // is really a pseudo instruction
1523 // Some usages of this intend for a FIXED_SEQUENCE to be used
1524 // Todo - break this dependency so we can optimize mov() in general
1525 // and only use the generic version when we require a fixed sequence
1526 void Assembler::mov(Register dst, const Operand& src) {
1527   intptr_t value = src.immediate();
1528   bool relocatable = src.must_output_reloc_info(this);
1529   bool canOptimize;
1530
1531   canOptimize =
1532       !(relocatable || (is_trampoline_pool_blocked() && !is_int16(value)));
1533
1534   if (canOptimize) {
1535     if (is_int16(value)) {
1536       li(dst, Operand(value));
1537     } else {
1538       uint16_t u16;
1539 #if V8_TARGET_ARCH_PPC64
1540       if (is_int32(value)) {
1541 #endif
1542         lis(dst, Operand(value >> 16));
1543 #if V8_TARGET_ARCH_PPC64
1544       } else {
1545         if (is_int48(value)) {
1546           li(dst, Operand(value >> 32));
1547         } else {
1548           lis(dst, Operand(value >> 48));
1549           u16 = ((value >> 32) & 0xffff);
1550           if (u16) {
1551             ori(dst, dst, Operand(u16));
1552           }
1553         }
1554         sldi(dst, dst, Operand(32));
1555         u16 = ((value >> 16) & 0xffff);
1556         if (u16) {
1557           oris(dst, dst, Operand(u16));
1558         }
1559       }
1560 #endif
1561       u16 = (value & 0xffff);
1562       if (u16) {
1563         ori(dst, dst, Operand(u16));
1564       }
1565     }
1566     return;
1567   }
1568
1569   DCHECK(!canOptimize);
1570   if (relocatable) {
1571     RecordRelocInfo(src.rmode_);
1572   }
1573   bitwise_mov(dst, value);
1574 }
1575
1576
1577 void Assembler::bitwise_mov(Register dst, intptr_t value) {
1578     BlockTrampolinePoolScope block_trampoline_pool(this);
1579 #if V8_TARGET_ARCH_PPC64
1580     int32_t hi_32 = static_cast<int32_t>(value >> 32);
1581     int32_t lo_32 = static_cast<int32_t>(value);
1582     int hi_word = static_cast<int>(hi_32 >> 16);
1583     int lo_word = static_cast<int>(hi_32 & 0xffff);
1584     lis(dst, Operand(SIGN_EXT_IMM16(hi_word)));
1585     ori(dst, dst, Operand(lo_word));
1586     sldi(dst, dst, Operand(32));
1587     hi_word = static_cast<int>(((lo_32 >> 16) & 0xffff));
1588     lo_word = static_cast<int>(lo_32 & 0xffff);
1589     oris(dst, dst, Operand(hi_word));
1590     ori(dst, dst, Operand(lo_word));
1591 #else
1592     int hi_word = static_cast<int>(value >> 16);
1593     int lo_word = static_cast<int>(value & 0xffff);
1594     lis(dst, Operand(SIGN_EXT_IMM16(hi_word)));
1595     ori(dst, dst, Operand(lo_word));
1596 #endif
1597 }
1598
1599
1600 void Assembler::bitwise_mov32(Register dst, int32_t value) {
1601   BlockTrampolinePoolScope block_trampoline_pool(this);
1602   int hi_word = static_cast<int>(value >> 16);
1603   int lo_word = static_cast<int>(value & 0xffff);
1604   lis(dst, Operand(SIGN_EXT_IMM16(hi_word)));
1605   ori(dst, dst, Operand(lo_word));
1606 }
1607
1608
1609 void Assembler::bitwise_add32(Register dst, Register src, int32_t value) {
1610   BlockTrampolinePoolScope block_trampoline_pool(this);
1611   if (is_int16(value)) {
1612     addi(dst, src, Operand(value));
1613     nop();
1614   } else {
1615     int hi_word = static_cast<int>(value >> 16);
1616     int lo_word = static_cast<int>(value & 0xffff);
1617     if (lo_word & 0x8000) hi_word++;
1618     addis(dst, src, Operand(SIGN_EXT_IMM16(hi_word)));
1619     addic(dst, dst, Operand(SIGN_EXT_IMM16(lo_word)));
1620   }
1621 }
1622
1623
1624 void Assembler::mov_label_offset(Register dst, Label* label) {
1625   int position = link(label);
1626   if (label->is_bound()) {
1627     // Load the position of the label relative to the generated code object.
1628     mov(dst, Operand(position + Code::kHeaderSize - kHeapObjectTag));
1629   } else {
1630     // Encode internal reference to unbound label. We use a dummy opcode
1631     // such that it won't collide with any opcode that might appear in the
1632     // label's chain.  Encode the destination register in the 2nd instruction.
1633     int link = position - pc_offset();
1634     DCHECK_EQ(0, link & 3);
1635     link >>= 2;
1636     DCHECK(is_int26(link));
1637
1638     // When the label is bound, these instructions will be patched
1639     // with a 2 instruction mov sequence that will load the
1640     // destination register with the position of the label from the
1641     // beginning of the code.
1642     //
1643     // target_at extracts the link and target_at_put patches the instructions.
1644     BlockTrampolinePoolScope block_trampoline_pool(this);
1645     emit(kUnboundMovLabelOffsetOpcode | (link & kImm26Mask));
1646     emit(dst.code());
1647   }
1648 }
1649
1650
1651 void Assembler::add_label_offset(Register dst, Register base, Label* label,
1652                                  int delta) {
1653   int position = link(label);
1654   if (label->is_bound()) {
1655     // dst = base + position + delta
1656     position += delta;
1657     bitwise_add32(dst, base, position);
1658   } else {
1659     // Encode internal reference to unbound label. We use a dummy opcode
1660     // such that it won't collide with any opcode that might appear in the
1661     // label's chain.  Encode the operands in the 2nd instruction.
1662     int link = position - pc_offset();
1663     DCHECK_EQ(0, link & 3);
1664     link >>= 2;
1665     DCHECK(is_int26(link));
1666     DCHECK(is_int16(delta));
1667
1668     BlockTrampolinePoolScope block_trampoline_pool(this);
1669     emit(kUnboundAddLabelOffsetOpcode | (link & kImm26Mask));
1670     emit(dst.code() * B21 | base.code() * B16 | (delta & kImm16Mask));
1671   }
1672 }
1673
1674
1675 void Assembler::mov_label_addr(Register dst, Label* label) {
1676   CheckBuffer();
1677   RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
1678   int position = link(label);
1679   if (label->is_bound()) {
1680     // Keep internal references relative until EmitRelocations.
1681     bitwise_mov(dst, position);
1682   } else {
1683     // Encode internal reference to unbound label. We use a dummy opcode
1684     // such that it won't collide with any opcode that might appear in the
1685     // label's chain.  Encode the destination register in the 2nd instruction.
1686     int link = position - pc_offset();
1687     DCHECK_EQ(0, link & 3);
1688     link >>= 2;
1689     DCHECK(is_int26(link));
1690
1691     // When the label is bound, these instructions will be patched
1692     // with a multi-instruction mov sequence that will load the
1693     // destination register with the address of the label.
1694     //
1695     // target_at extracts the link and target_at_put patches the instructions.
1696     BlockTrampolinePoolScope block_trampoline_pool(this);
1697     emit(kUnboundMovLabelAddrOpcode | (link & kImm26Mask));
1698     emit(dst.code());
1699     DCHECK(kMovInstructions >= 2);
1700     for (int i = 0; i < kMovInstructions - 2; i++) nop();
1701   }
1702 }
1703
1704
1705 void Assembler::emit_label_addr(Label* label) {
1706   CheckBuffer();
1707   RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
1708   int position = link(label);
1709   if (label->is_bound()) {
1710     // Keep internal references relative until EmitRelocations.
1711     emit_ptr(position);
1712   } else {
1713     // Encode internal reference to unbound label. We use a dummy opcode
1714     // such that it won't collide with any opcode that might appear in the
1715     // label's chain.
1716     int link = position - pc_offset();
1717     DCHECK_EQ(0, link & 3);
1718     link >>= 2;
1719     DCHECK(is_int26(link));
1720
1721     // When the label is bound, the instruction(s) will be patched
1722     // as a jump table entry containing the label address.  target_at extracts
1723     // the link and target_at_put patches the instruction(s).
1724     BlockTrampolinePoolScope block_trampoline_pool(this);
1725     emit(kUnboundJumpTableEntryOpcode | (link & kImm26Mask));
1726 #if V8_TARGET_ARCH_PPC64
1727     nop();
1728 #endif
1729   }
1730 }
1731
1732
1733 // Special register instructions
1734 void Assembler::crxor(int bt, int ba, int bb) {
1735   emit(EXT1 | CRXOR | bt * B21 | ba * B16 | bb * B11);
1736 }
1737
1738
1739 void Assembler::creqv(int bt, int ba, int bb) {
1740   emit(EXT1 | CREQV | bt * B21 | ba * B16 | bb * B11);
1741 }
1742
1743
1744 void Assembler::mflr(Register dst) {
1745   emit(EXT2 | MFSPR | dst.code() * B21 | 256 << 11);  // Ignore RC bit
1746 }
1747
1748
1749 void Assembler::mtlr(Register src) {
1750   emit(EXT2 | MTSPR | src.code() * B21 | 256 << 11);  // Ignore RC bit
1751 }
1752
1753
1754 void Assembler::mtctr(Register src) {
1755   emit(EXT2 | MTSPR | src.code() * B21 | 288 << 11);  // Ignore RC bit
1756 }
1757
1758
1759 void Assembler::mtxer(Register src) {
1760   emit(EXT2 | MTSPR | src.code() * B21 | 32 << 11);
1761 }
1762
1763
1764 void Assembler::mcrfs(int bf, int bfa) {
1765   emit(EXT4 | MCRFS | bf * B23 | bfa * B18);
1766 }
1767
1768
1769 void Assembler::mfcr(Register dst) { emit(EXT2 | MFCR | dst.code() * B21); }
1770
1771
1772 #if V8_TARGET_ARCH_PPC64
1773 void Assembler::mffprd(Register dst, DoubleRegister src) {
1774   emit(EXT2 | MFVSRD | src.code() * B21 | dst.code() * B16);
1775 }
1776
1777
1778 void Assembler::mffprwz(Register dst, DoubleRegister src) {
1779   emit(EXT2 | MFVSRWZ | src.code() * B21 | dst.code() * B16);
1780 }
1781
1782
1783 void Assembler::mtfprd(DoubleRegister dst, Register src) {
1784   emit(EXT2 | MTVSRD | dst.code() * B21 | src.code() * B16);
1785 }
1786
1787
1788 void Assembler::mtfprwz(DoubleRegister dst, Register src) {
1789   emit(EXT2 | MTVSRWZ | dst.code() * B21 | src.code() * B16);
1790 }
1791
1792
1793 void Assembler::mtfprwa(DoubleRegister dst, Register src) {
1794   emit(EXT2 | MTVSRWA | dst.code() * B21 | src.code() * B16);
1795 }
1796 #endif
1797
1798
1799 // Exception-generating instructions and debugging support.
1800 // Stops with a non-negative code less than kNumOfWatchedStops support
1801 // enabling/disabling and a counter feature. See simulator-ppc.h .
1802 void Assembler::stop(const char* msg, Condition cond, int32_t code,
1803                      CRegister cr) {
1804   if (cond != al) {
1805     Label skip;
1806     b(NegateCondition(cond), &skip, cr);
1807     bkpt(0);
1808     bind(&skip);
1809   } else {
1810     bkpt(0);
1811   }
1812 }
1813
1814
1815 void Assembler::bkpt(uint32_t imm16) { emit(0x7d821008); }
1816
1817
1818 void Assembler::dcbf(Register ra, Register rb) {
1819   emit(EXT2 | DCBF | ra.code() * B16 | rb.code() * B11);
1820 }
1821
1822
1823 void Assembler::sync() { emit(EXT2 | SYNC); }
1824
1825
1826 void Assembler::lwsync() { emit(EXT2 | SYNC | 1 * B21); }
1827
1828
1829 void Assembler::icbi(Register ra, Register rb) {
1830   emit(EXT2 | ICBI | ra.code() * B16 | rb.code() * B11);
1831 }
1832
1833
1834 void Assembler::isync() { emit(EXT1 | ISYNC); }
1835
1836
1837 // Floating point support
1838
1839 void Assembler::lfd(const DoubleRegister frt, const MemOperand& src) {
1840   int offset = src.offset();
1841   Register ra = src.ra();
1842   DCHECK(is_int16(offset));
1843   int imm16 = offset & kImm16Mask;
1844   // could be x_form instruction with some casting magic
1845   emit(LFD | frt.code() * B21 | ra.code() * B16 | imm16);
1846 }
1847
1848
1849 void Assembler::lfdu(const DoubleRegister frt, const MemOperand& src) {
1850   int offset = src.offset();
1851   Register ra = src.ra();
1852   DCHECK(is_int16(offset));
1853   int imm16 = offset & kImm16Mask;
1854   // could be x_form instruction with some casting magic
1855   emit(LFDU | frt.code() * B21 | ra.code() * B16 | imm16);
1856 }
1857
1858
1859 void Assembler::lfdx(const DoubleRegister frt, const MemOperand& src) {
1860   Register ra = src.ra();
1861   Register rb = src.rb();
1862   DCHECK(!ra.is(r0));
1863   emit(EXT2 | LFDX | frt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1864        LeaveRC);
1865 }
1866
1867
1868 void Assembler::lfdux(const DoubleRegister frt, const MemOperand& src) {
1869   Register ra = src.ra();
1870   Register rb = src.rb();
1871   DCHECK(!ra.is(r0));
1872   emit(EXT2 | LFDUX | frt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1873        LeaveRC);
1874 }
1875
1876
1877 void Assembler::lfs(const DoubleRegister frt, const MemOperand& src) {
1878   int offset = src.offset();
1879   Register ra = src.ra();
1880   DCHECK(is_int16(offset));
1881   DCHECK(!ra.is(r0));
1882   int imm16 = offset & kImm16Mask;
1883   // could be x_form instruction with some casting magic
1884   emit(LFS | frt.code() * B21 | ra.code() * B16 | imm16);
1885 }
1886
1887
1888 void Assembler::lfsu(const DoubleRegister frt, const MemOperand& src) {
1889   int offset = src.offset();
1890   Register ra = src.ra();
1891   DCHECK(is_int16(offset));
1892   DCHECK(!ra.is(r0));
1893   int imm16 = offset & kImm16Mask;
1894   // could be x_form instruction with some casting magic
1895   emit(LFSU | frt.code() * B21 | ra.code() * B16 | imm16);
1896 }
1897
1898
1899 void Assembler::lfsx(const DoubleRegister frt, const MemOperand& src) {
1900   Register ra = src.ra();
1901   Register rb = src.rb();
1902   DCHECK(!ra.is(r0));
1903   emit(EXT2 | LFSX | frt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1904        LeaveRC);
1905 }
1906
1907
1908 void Assembler::lfsux(const DoubleRegister frt, const MemOperand& src) {
1909   Register ra = src.ra();
1910   Register rb = src.rb();
1911   DCHECK(!ra.is(r0));
1912   emit(EXT2 | LFSUX | frt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1913        LeaveRC);
1914 }
1915
1916
1917 void Assembler::stfd(const DoubleRegister frs, const MemOperand& src) {
1918   int offset = src.offset();
1919   Register ra = src.ra();
1920   DCHECK(is_int16(offset));
1921   DCHECK(!ra.is(r0));
1922   int imm16 = offset & kImm16Mask;
1923   // could be x_form instruction with some casting magic
1924   emit(STFD | frs.code() * B21 | ra.code() * B16 | imm16);
1925 }
1926
1927
1928 void Assembler::stfdu(const DoubleRegister frs, const MemOperand& src) {
1929   int offset = src.offset();
1930   Register ra = src.ra();
1931   DCHECK(is_int16(offset));
1932   DCHECK(!ra.is(r0));
1933   int imm16 = offset & kImm16Mask;
1934   // could be x_form instruction with some casting magic
1935   emit(STFDU | frs.code() * B21 | ra.code() * B16 | imm16);
1936 }
1937
1938
1939 void Assembler::stfdx(const DoubleRegister frs, const MemOperand& src) {
1940   Register ra = src.ra();
1941   Register rb = src.rb();
1942   DCHECK(!ra.is(r0));
1943   emit(EXT2 | STFDX | frs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1944        LeaveRC);
1945 }
1946
1947
1948 void Assembler::stfdux(const DoubleRegister frs, const MemOperand& src) {
1949   Register ra = src.ra();
1950   Register rb = src.rb();
1951   DCHECK(!ra.is(r0));
1952   emit(EXT2 | STFDUX | frs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1953        LeaveRC);
1954 }
1955
1956
1957 void Assembler::stfs(const DoubleRegister frs, const MemOperand& src) {
1958   int offset = src.offset();
1959   Register ra = src.ra();
1960   DCHECK(is_int16(offset));
1961   DCHECK(!ra.is(r0));
1962   int imm16 = offset & kImm16Mask;
1963   // could be x_form instruction with some casting magic
1964   emit(STFS | frs.code() * B21 | ra.code() * B16 | imm16);
1965 }
1966
1967
1968 void Assembler::stfsu(const DoubleRegister frs, const MemOperand& src) {
1969   int offset = src.offset();
1970   Register ra = src.ra();
1971   DCHECK(is_int16(offset));
1972   DCHECK(!ra.is(r0));
1973   int imm16 = offset & kImm16Mask;
1974   // could be x_form instruction with some casting magic
1975   emit(STFSU | frs.code() * B21 | ra.code() * B16 | imm16);
1976 }
1977
1978
1979 void Assembler::stfsx(const DoubleRegister frs, const MemOperand& src) {
1980   Register ra = src.ra();
1981   Register rb = src.rb();
1982   DCHECK(!ra.is(r0));
1983   emit(EXT2 | STFSX | frs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1984        LeaveRC);
1985 }
1986
1987
1988 void Assembler::stfsux(const DoubleRegister frs, const MemOperand& src) {
1989   Register ra = src.ra();
1990   Register rb = src.rb();
1991   DCHECK(!ra.is(r0));
1992   emit(EXT2 | STFSUX | frs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
1993        LeaveRC);
1994 }
1995
1996
1997 void Assembler::fsub(const DoubleRegister frt, const DoubleRegister fra,
1998                      const DoubleRegister frb, RCBit rc) {
1999   a_form(EXT4 | FSUB, frt, fra, frb, rc);
2000 }
2001
2002
2003 void Assembler::fadd(const DoubleRegister frt, const DoubleRegister fra,
2004                      const DoubleRegister frb, RCBit rc) {
2005   a_form(EXT4 | FADD, frt, fra, frb, rc);
2006 }
2007
2008
2009 void Assembler::fmul(const DoubleRegister frt, const DoubleRegister fra,
2010                      const DoubleRegister frc, RCBit rc) {
2011   emit(EXT4 | FMUL | frt.code() * B21 | fra.code() * B16 | frc.code() * B6 |
2012        rc);
2013 }
2014
2015
2016 void Assembler::fdiv(const DoubleRegister frt, const DoubleRegister fra,
2017                      const DoubleRegister frb, RCBit rc) {
2018   a_form(EXT4 | FDIV, frt, fra, frb, rc);
2019 }
2020
2021
2022 void Assembler::fcmpu(const DoubleRegister fra, const DoubleRegister frb,
2023                       CRegister cr) {
2024   DCHECK(cr.code() >= 0 && cr.code() <= 7);
2025   emit(EXT4 | FCMPU | cr.code() * B23 | fra.code() * B16 | frb.code() * B11);
2026 }
2027
2028
2029 void Assembler::fmr(const DoubleRegister frt, const DoubleRegister frb,
2030                     RCBit rc) {
2031   emit(EXT4 | FMR | frt.code() * B21 | frb.code() * B11 | rc);
2032 }
2033
2034
2035 void Assembler::fctiwz(const DoubleRegister frt, const DoubleRegister frb) {
2036   emit(EXT4 | FCTIWZ | frt.code() * B21 | frb.code() * B11);
2037 }
2038
2039
2040 void Assembler::fctiw(const DoubleRegister frt, const DoubleRegister frb) {
2041   emit(EXT4 | FCTIW | frt.code() * B21 | frb.code() * B11);
2042 }
2043
2044
2045 void Assembler::frin(const DoubleRegister frt, const DoubleRegister frb,
2046                      RCBit rc) {
2047   emit(EXT4 | FRIN | frt.code() * B21 | frb.code() * B11 | rc);
2048 }
2049
2050
2051 void Assembler::friz(const DoubleRegister frt, const DoubleRegister frb,
2052                      RCBit rc) {
2053   emit(EXT4 | FRIZ | frt.code() * B21 | frb.code() * B11 | rc);
2054 }
2055
2056
2057 void Assembler::frip(const DoubleRegister frt, const DoubleRegister frb,
2058                      RCBit rc) {
2059   emit(EXT4 | FRIP | frt.code() * B21 | frb.code() * B11 | rc);
2060 }
2061
2062
2063 void Assembler::frim(const DoubleRegister frt, const DoubleRegister frb,
2064                      RCBit rc) {
2065   emit(EXT4 | FRIM | frt.code() * B21 | frb.code() * B11 | rc);
2066 }
2067
2068
2069 void Assembler::frsp(const DoubleRegister frt, const DoubleRegister frb,
2070                      RCBit rc) {
2071   emit(EXT4 | FRSP | frt.code() * B21 | frb.code() * B11 | rc);
2072 }
2073
2074
2075 void Assembler::fcfid(const DoubleRegister frt, const DoubleRegister frb,
2076                       RCBit rc) {
2077   emit(EXT4 | FCFID | frt.code() * B21 | frb.code() * B11 | rc);
2078 }
2079
2080
2081 void Assembler::fctid(const DoubleRegister frt, const DoubleRegister frb,
2082                       RCBit rc) {
2083   emit(EXT4 | FCTID | frt.code() * B21 | frb.code() * B11 | rc);
2084 }
2085
2086
2087 void Assembler::fctidz(const DoubleRegister frt, const DoubleRegister frb,
2088                        RCBit rc) {
2089   emit(EXT4 | FCTIDZ | frt.code() * B21 | frb.code() * B11 | rc);
2090 }
2091
2092
2093 void Assembler::fsel(const DoubleRegister frt, const DoubleRegister fra,
2094                      const DoubleRegister frc, const DoubleRegister frb,
2095                      RCBit rc) {
2096   emit(EXT4 | FSEL | frt.code() * B21 | fra.code() * B16 | frb.code() * B11 |
2097        frc.code() * B6 | rc);
2098 }
2099
2100
2101 void Assembler::fneg(const DoubleRegister frt, const DoubleRegister frb,
2102                      RCBit rc) {
2103   emit(EXT4 | FNEG | frt.code() * B21 | frb.code() * B11 | rc);
2104 }
2105
2106
2107 void Assembler::mtfsfi(int bf, int immediate, RCBit rc) {
2108   emit(EXT4 | MTFSFI | bf * B23 | immediate * B12 | rc);
2109 }
2110
2111
2112 void Assembler::mffs(const DoubleRegister frt, RCBit rc) {
2113   emit(EXT4 | MFFS | frt.code() * B21 | rc);
2114 }
2115
2116
2117 void Assembler::mtfsf(const DoubleRegister frb, bool L, int FLM, bool W,
2118                       RCBit rc) {
2119   emit(EXT4 | MTFSF | frb.code() * B11 | W * B16 | FLM * B17 | L * B25 | rc);
2120 }
2121
2122
2123 void Assembler::fsqrt(const DoubleRegister frt, const DoubleRegister frb,
2124                       RCBit rc) {
2125   emit(EXT4 | FSQRT | frt.code() * B21 | frb.code() * B11 | rc);
2126 }
2127
2128
2129 void Assembler::fabs(const DoubleRegister frt, const DoubleRegister frb,
2130                      RCBit rc) {
2131   emit(EXT4 | FABS | frt.code() * B21 | frb.code() * B11 | rc);
2132 }
2133
2134
2135 void Assembler::fmadd(const DoubleRegister frt, const DoubleRegister fra,
2136                       const DoubleRegister frc, const DoubleRegister frb,
2137                       RCBit rc) {
2138   emit(EXT4 | FMADD | frt.code() * B21 | fra.code() * B16 | frb.code() * B11 |
2139        frc.code() * B6 | rc);
2140 }
2141
2142
2143 void Assembler::fmsub(const DoubleRegister frt, const DoubleRegister fra,
2144                       const DoubleRegister frc, const DoubleRegister frb,
2145                       RCBit rc) {
2146   emit(EXT4 | FMSUB | frt.code() * B21 | fra.code() * B16 | frb.code() * B11 |
2147        frc.code() * B6 | rc);
2148 }
2149
2150
2151 // Pseudo instructions.
2152 void Assembler::nop(int type) {
2153   Register reg = r0;
2154   switch (type) {
2155     case NON_MARKING_NOP:
2156       reg = r0;
2157       break;
2158     case GROUP_ENDING_NOP:
2159       reg = r2;
2160       break;
2161     case DEBUG_BREAK_NOP:
2162       reg = r3;
2163       break;
2164     default:
2165       UNIMPLEMENTED();
2166   }
2167
2168   ori(reg, reg, Operand::Zero());
2169 }
2170
2171
2172 bool Assembler::IsNop(Instr instr, int type) {
2173   int reg = 0;
2174   switch (type) {
2175     case NON_MARKING_NOP:
2176       reg = 0;
2177       break;
2178     case GROUP_ENDING_NOP:
2179       reg = 2;
2180       break;
2181     case DEBUG_BREAK_NOP:
2182       reg = 3;
2183       break;
2184     default:
2185       UNIMPLEMENTED();
2186   }
2187   return instr == (ORI | reg * B21 | reg * B16);
2188 }
2189
2190
2191 void Assembler::GrowBuffer(int needed) {
2192   if (!own_buffer_) FATAL("external code buffer is too small");
2193
2194   // Compute new buffer size.
2195   CodeDesc desc;  // the new buffer
2196   if (buffer_size_ < 4 * KB) {
2197     desc.buffer_size = 4 * KB;
2198   } else if (buffer_size_ < 1 * MB) {
2199     desc.buffer_size = 2 * buffer_size_;
2200   } else {
2201     desc.buffer_size = buffer_size_ + 1 * MB;
2202   }
2203   int space = buffer_space() + (desc.buffer_size - buffer_size_);
2204   if (space < needed) {
2205     desc.buffer_size += needed - space;
2206   }
2207   CHECK_GT(desc.buffer_size, 0);  // no overflow
2208
2209   // Set up new buffer.
2210   desc.buffer = NewArray<byte>(desc.buffer_size);
2211
2212   desc.instr_size = pc_offset();
2213   desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
2214
2215   // Copy the data.
2216   intptr_t pc_delta = desc.buffer - buffer_;
2217   intptr_t rc_delta =
2218       (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
2219   memmove(desc.buffer, buffer_, desc.instr_size);
2220   memmove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(),
2221           desc.reloc_size);
2222
2223   // Switch buffers.
2224   DeleteArray(buffer_);
2225   buffer_ = desc.buffer;
2226   buffer_size_ = desc.buffer_size;
2227   pc_ += pc_delta;
2228   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2229                                reloc_info_writer.last_pc() + pc_delta);
2230
2231   // Nothing else to do here since we keep all internal references and
2232   // deferred relocation entries relative to the buffer (until
2233   // EmitRelocations).
2234 }
2235
2236
2237 void Assembler::db(uint8_t data) {
2238   CheckBuffer();
2239   *reinterpret_cast<uint8_t*>(pc_) = data;
2240   pc_ += sizeof(uint8_t);
2241 }
2242
2243
2244 void Assembler::dd(uint32_t data) {
2245   CheckBuffer();
2246   *reinterpret_cast<uint32_t*>(pc_) = data;
2247   pc_ += sizeof(uint32_t);
2248 }
2249
2250
2251 void Assembler::emit_ptr(intptr_t data) {
2252   CheckBuffer();
2253   *reinterpret_cast<intptr_t*>(pc_) = data;
2254   pc_ += sizeof(intptr_t);
2255 }
2256
2257
2258 void Assembler::emit_double(double value) {
2259   CheckBuffer();
2260   *reinterpret_cast<double*>(pc_) = value;
2261   pc_ += sizeof(double);
2262 }
2263
2264
2265 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2266   DeferredRelocInfo rinfo(pc_offset(), rmode, data);
2267   RecordRelocInfo(rinfo);
2268 }
2269
2270
2271 void Assembler::RecordRelocInfo(const DeferredRelocInfo& rinfo) {
2272   if (rinfo.rmode() >= RelocInfo::JS_RETURN &&
2273       rinfo.rmode() <= RelocInfo::DEBUG_BREAK_SLOT) {
2274     // Adjust code for new modes.
2275     DCHECK(RelocInfo::IsDebugBreakSlot(rinfo.rmode()) ||
2276            RelocInfo::IsJSReturn(rinfo.rmode()) ||
2277            RelocInfo::IsComment(rinfo.rmode()) ||
2278            RelocInfo::IsPosition(rinfo.rmode()));
2279   }
2280   if (!RelocInfo::IsNone(rinfo.rmode())) {
2281     // Don't record external references unless the heap will be serialized.
2282     if (rinfo.rmode() == RelocInfo::EXTERNAL_REFERENCE) {
2283       if (!serializer_enabled() && !emit_debug_code()) {
2284         return;
2285       }
2286     }
2287     if (rinfo.rmode() == RelocInfo::CODE_TARGET_WITH_ID) {
2288       DeferredRelocInfo reloc_info_with_ast_id(rinfo.position(), rinfo.rmode(),
2289                                                RecordedAstId().ToInt());
2290       ClearRecordedAstId();
2291       relocations_.push_back(reloc_info_with_ast_id);
2292     } else {
2293       relocations_.push_back(rinfo);
2294     }
2295   }
2296 }
2297
2298
2299 void Assembler::EmitRelocations() {
2300   EnsureSpaceFor(relocations_.size() * kMaxRelocSize);
2301
2302   for (std::vector<DeferredRelocInfo>::iterator it = relocations_.begin();
2303        it != relocations_.end(); it++) {
2304     RelocInfo::Mode rmode = it->rmode();
2305     Address pc = buffer_ + it->position();
2306     Code* code = NULL;
2307     RelocInfo rinfo(pc, rmode, it->data(), code);
2308
2309     // Fix up internal references now that they are guaranteed to be bound.
2310     if (RelocInfo::IsInternalReference(rmode)) {
2311       // Jump table entry
2312       intptr_t pos = reinterpret_cast<intptr_t>(Memory::Address_at(pc));
2313       Memory::Address_at(pc) = buffer_ + pos;
2314     } else if (RelocInfo::IsInternalReferenceEncoded(rmode)) {
2315       // mov sequence
2316       intptr_t pos = reinterpret_cast<intptr_t>(target_address_at(pc, code));
2317       set_target_address_at(pc, code, buffer_ + pos, SKIP_ICACHE_FLUSH);
2318     }
2319
2320     reloc_info_writer.Write(&rinfo);
2321   }
2322
2323   reloc_info_writer.Finish();
2324 }
2325
2326
2327 void Assembler::BlockTrampolinePoolFor(int instructions) {
2328   BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize);
2329 }
2330
2331
2332 void Assembler::CheckTrampolinePool() {
2333   // Some small sequences of instructions must not be broken up by the
2334   // insertion of a trampoline pool; such sequences are protected by setting
2335   // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_,
2336   // which are both checked here. Also, recursive calls to CheckTrampolinePool
2337   // are blocked by trampoline_pool_blocked_nesting_.
2338   if ((trampoline_pool_blocked_nesting_ > 0) ||
2339       (pc_offset() < no_trampoline_pool_before_)) {
2340     // Emission is currently blocked; make sure we try again as soon as
2341     // possible.
2342     if (trampoline_pool_blocked_nesting_ > 0) {
2343       next_buffer_check_ = pc_offset() + kInstrSize;
2344     } else {
2345       next_buffer_check_ = no_trampoline_pool_before_;
2346     }
2347     return;
2348   }
2349
2350   DCHECK(!trampoline_emitted_);
2351   DCHECK(unbound_labels_count_ >= 0);
2352   if (unbound_labels_count_ > 0) {
2353     // First we emit jump, then we emit trampoline pool.
2354     {
2355       BlockTrampolinePoolScope block_trampoline_pool(this);
2356       Label after_pool;
2357       b(&after_pool);
2358
2359       int pool_start = pc_offset();
2360       for (int i = 0; i < unbound_labels_count_; i++) {
2361         b(&after_pool);
2362       }
2363       bind(&after_pool);
2364       trampoline_ = Trampoline(pool_start, unbound_labels_count_);
2365
2366       trampoline_emitted_ = true;
2367       // As we are only going to emit trampoline once, we need to prevent any
2368       // further emission.
2369       next_buffer_check_ = kMaxInt;
2370     }
2371   } else {
2372     // Number of branches to unbound label at this point is zero, so we can
2373     // move next buffer check to maximum.
2374     next_buffer_check_ =
2375         pc_offset() + kMaxCondBranchReach - kMaxBlockTrampolineSectionSize;
2376   }
2377   return;
2378 }
2379
2380
2381 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
2382   DCHECK(!FLAG_enable_ool_constant_pool);
2383   return isolate->factory()->empty_constant_pool_array();
2384 }
2385
2386
2387 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
2388   DCHECK(!FLAG_enable_ool_constant_pool);
2389 }
2390 }
2391 }  // namespace v8::internal
2392
2393 #endif  // V8_TARGET_ARCH_PPC