deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / src / mips / assembler-mips.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 are
6 // 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 distribution.
14 //
15 // - Neither the name of Sun Microsystems or the names of contributors may
16 // be used to endorse or promote products derived from this software without
17 // specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 // The original source code covered by the above license above has been
32 // modified significantly by Google Inc.
33 // Copyright 2012 the V8 project authors. All rights reserved.
34
35
36 #include "src/v8.h"
37
38 #if V8_TARGET_ARCH_MIPS
39
40 #include "src/base/bits.h"
41 #include "src/base/cpu.h"
42 #include "src/mips/assembler-mips-inl.h"
43
44 namespace v8 {
45 namespace internal {
46
47 // Get the CPU features enabled by the build. For cross compilation the
48 // preprocessor symbols CAN_USE_FPU_INSTRUCTIONS
49 // can be defined to enable FPU instructions when building the
50 // snapshot.
51 static unsigned CpuFeaturesImpliedByCompiler() {
52   unsigned answer = 0;
53 #ifdef CAN_USE_FPU_INSTRUCTIONS
54   answer |= 1u << FPU;
55 #endif  // def CAN_USE_FPU_INSTRUCTIONS
56
57   // If the compiler is allowed to use FPU then we can use FPU too in our code
58   // generation even when generating snapshots.  This won't work for cross
59   // compilation.
60 #if defined(__mips__) && defined(__mips_hard_float) && __mips_hard_float != 0
61   answer |= 1u << FPU;
62 #endif
63
64   return answer;
65 }
66
67
68 const char* DoubleRegister::AllocationIndexToString(int index) {
69   DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
70   const char* const names[] = {
71     "f0",
72     "f2",
73     "f4",
74     "f6",
75     "f8",
76     "f10",
77     "f12",
78     "f14",
79     "f16",
80     "f18",
81     "f20",
82     "f22",
83     "f24",
84     "f26"
85   };
86   return names[index];
87 }
88
89
90 void CpuFeatures::ProbeImpl(bool cross_compile) {
91   supported_ |= CpuFeaturesImpliedByCompiler();
92
93   // Only use statically determined features for cross compile (snapshot).
94   if (cross_compile) return;
95
96   // If the compiler is allowed to use fpu then we can use fpu too in our
97   // code generation.
98 #ifndef __mips__
99   // For the simulator build, use FPU.
100   supported_ |= 1u << FPU;
101 #if defined(_MIPS_ARCH_MIPS32R6)
102   // FP64 mode is implied on r6.
103   supported_ |= 1u << FP64FPU;
104 #endif
105 #if defined(FPU_MODE_FP64)
106   supported_ |= 1u << FP64FPU;
107 #endif
108 #else
109   // Probe for additional features at runtime.
110   base::CPU cpu;
111   if (cpu.has_fpu()) supported_ |= 1u << FPU;
112 #if defined(FPU_MODE_FPXX)
113   if (cpu.is_fp64_mode()) supported_ |= 1u << FP64FPU;
114 #elif defined(FPU_MODE_FP64)
115   supported_ |= 1u << FP64FPU;
116 #endif
117 #if defined(_MIPS_ARCH_MIPS32RX)
118   if (cpu.architecture() == 6) {
119     supported_ |= 1u << MIPSr6;
120   } else if (cpu.architecture() == 2) {
121     supported_ |= 1u << MIPSr1;
122     supported_ |= 1u << MIPSr2;
123   } else {
124     supported_ |= 1u << MIPSr1;
125   }
126 #endif
127 #endif
128 }
129
130
131 void CpuFeatures::PrintTarget() { }
132 void CpuFeatures::PrintFeatures() { }
133
134
135 int ToNumber(Register reg) {
136   DCHECK(reg.is_valid());
137   const int kNumbers[] = {
138     0,    // zero_reg
139     1,    // at
140     2,    // v0
141     3,    // v1
142     4,    // a0
143     5,    // a1
144     6,    // a2
145     7,    // a3
146     8,    // t0
147     9,    // t1
148     10,   // t2
149     11,   // t3
150     12,   // t4
151     13,   // t5
152     14,   // t6
153     15,   // t7
154     16,   // s0
155     17,   // s1
156     18,   // s2
157     19,   // s3
158     20,   // s4
159     21,   // s5
160     22,   // s6
161     23,   // s7
162     24,   // t8
163     25,   // t9
164     26,   // k0
165     27,   // k1
166     28,   // gp
167     29,   // sp
168     30,   // fp
169     31,   // ra
170   };
171   return kNumbers[reg.code()];
172 }
173
174
175 Register ToRegister(int num) {
176   DCHECK(num >= 0 && num < kNumRegisters);
177   const Register kRegisters[] = {
178     zero_reg,
179     at,
180     v0, v1,
181     a0, a1, a2, a3,
182     t0, t1, t2, t3, t4, t5, t6, t7,
183     s0, s1, s2, s3, s4, s5, s6, s7,
184     t8, t9,
185     k0, k1,
186     gp,
187     sp,
188     fp,
189     ra
190   };
191   return kRegisters[num];
192 }
193
194
195 // -----------------------------------------------------------------------------
196 // Implementation of RelocInfo.
197
198 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
199                                   1 << RelocInfo::INTERNAL_REFERENCE |
200                                   1 << RelocInfo::INTERNAL_REFERENCE_ENCODED;
201
202
203 bool RelocInfo::IsCodedSpecially() {
204   // The deserializer needs to know whether a pointer is specially coded.  Being
205   // specially coded on MIPS means that it is a lui/ori instruction, and that is
206   // always the case inside code objects.
207   return true;
208 }
209
210
211 bool RelocInfo::IsInConstantPool() {
212   return false;
213 }
214
215
216 // -----------------------------------------------------------------------------
217 // Implementation of Operand and MemOperand.
218 // See assembler-mips-inl.h for inlined constructors.
219
220 Operand::Operand(Handle<Object> handle) {
221   AllowDeferredHandleDereference using_raw_address;
222   rm_ = no_reg;
223   // Verify all Objects referred by code are NOT in new space.
224   Object* obj = *handle;
225   if (obj->IsHeapObject()) {
226     DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj));
227     imm32_ = reinterpret_cast<intptr_t>(handle.location());
228     rmode_ = RelocInfo::EMBEDDED_OBJECT;
229   } else {
230     // No relocation needed.
231     imm32_ = reinterpret_cast<intptr_t>(obj);
232     rmode_ = RelocInfo::NONE32;
233   }
234 }
235
236
237 MemOperand::MemOperand(Register rm, int32_t offset) : Operand(rm) {
238   offset_ = offset;
239 }
240
241
242 MemOperand::MemOperand(Register rm, int32_t unit, int32_t multiplier,
243                        OffsetAddend offset_addend) : Operand(rm) {
244   offset_ = unit * multiplier + offset_addend;
245 }
246
247
248 // -----------------------------------------------------------------------------
249 // Specific instructions, constants, and masks.
250
251 static const int kNegOffset = 0x00008000;
252 // addiu(sp, sp, 4) aka Pop() operation or part of Pop(r)
253 // operations as post-increment of sp.
254 const Instr kPopInstruction = ADDIU | (kRegister_sp_Code << kRsShift)
255       | (kRegister_sp_Code << kRtShift)
256       | (kPointerSize & kImm16Mask);  // NOLINT
257 // addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp.
258 const Instr kPushInstruction = ADDIU | (kRegister_sp_Code << kRsShift)
259       | (kRegister_sp_Code << kRtShift)
260       | (-kPointerSize & kImm16Mask);  // NOLINT
261 // sw(r, MemOperand(sp, 0))
262 const Instr kPushRegPattern = SW | (kRegister_sp_Code << kRsShift)
263       | (0 & kImm16Mask);  // NOLINT
264 //  lw(r, MemOperand(sp, 0))
265 const Instr kPopRegPattern = LW | (kRegister_sp_Code << kRsShift)
266       | (0 & kImm16Mask);  // NOLINT
267
268 const Instr kLwRegFpOffsetPattern = LW | (kRegister_fp_Code << kRsShift)
269       | (0 & kImm16Mask);  // NOLINT
270
271 const Instr kSwRegFpOffsetPattern = SW | (kRegister_fp_Code << kRsShift)
272       | (0 & kImm16Mask);  // NOLINT
273
274 const Instr kLwRegFpNegOffsetPattern = LW | (kRegister_fp_Code << kRsShift)
275       | (kNegOffset & kImm16Mask);  // NOLINT
276
277 const Instr kSwRegFpNegOffsetPattern = SW | (kRegister_fp_Code << kRsShift)
278       | (kNegOffset & kImm16Mask);  // NOLINT
279 // A mask for the Rt register for push, pop, lw, sw instructions.
280 const Instr kRtMask = kRtFieldMask;
281 const Instr kLwSwInstrTypeMask = 0xffe00000;
282 const Instr kLwSwInstrArgumentMask  = ~kLwSwInstrTypeMask;
283 const Instr kLwSwOffsetMask = kImm16Mask;
284
285
286 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
287     : AssemblerBase(isolate, buffer, buffer_size),
288       recorded_ast_id_(TypeFeedbackId::None()),
289       positions_recorder_(this) {
290   reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
291
292   last_trampoline_pool_end_ = 0;
293   no_trampoline_pool_before_ = 0;
294   trampoline_pool_blocked_nesting_ = 0;
295   // We leave space (16 * kTrampolineSlotsSize)
296   // for BlockTrampolinePoolScope buffer.
297   next_buffer_check_ = FLAG_force_long_branches
298       ? kMaxInt : kMaxBranchOffset - kTrampolineSlotsSize * 16;
299   internal_trampoline_exception_ = false;
300   last_bound_pos_ = 0;
301
302   trampoline_emitted_ = FLAG_force_long_branches;
303   unbound_labels_count_ = 0;
304   block_buffer_growth_ = false;
305
306   ClearRecordedAstId();
307 }
308
309
310 void Assembler::GetCode(CodeDesc* desc) {
311   DCHECK(pc_ <= reloc_info_writer.pos());  // No overlap.
312   // Set up code descriptor.
313   desc->buffer = buffer_;
314   desc->buffer_size = buffer_size_;
315   desc->instr_size = pc_offset();
316   desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
317   desc->origin = this;
318 }
319
320
321 void Assembler::Align(int m) {
322   DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
323   while ((pc_offset() & (m - 1)) != 0) {
324     nop();
325   }
326 }
327
328
329 void Assembler::CodeTargetAlign() {
330   // No advantage to aligning branch/call targets to more than
331   // single instruction, that I am aware of.
332   Align(4);
333 }
334
335
336 Register Assembler::GetRtReg(Instr instr) {
337   Register rt;
338   rt.code_ = (instr & kRtFieldMask) >> kRtShift;
339   return rt;
340 }
341
342
343 Register Assembler::GetRsReg(Instr instr) {
344   Register rs;
345   rs.code_ = (instr & kRsFieldMask) >> kRsShift;
346   return rs;
347 }
348
349
350 Register Assembler::GetRdReg(Instr instr) {
351   Register rd;
352   rd.code_ = (instr & kRdFieldMask) >> kRdShift;
353   return rd;
354 }
355
356
357 uint32_t Assembler::GetRt(Instr instr) {
358   return (instr & kRtFieldMask) >> kRtShift;
359 }
360
361
362 uint32_t Assembler::GetRtField(Instr instr) {
363   return instr & kRtFieldMask;
364 }
365
366
367 uint32_t Assembler::GetRs(Instr instr) {
368   return (instr & kRsFieldMask) >> kRsShift;
369 }
370
371
372 uint32_t Assembler::GetRsField(Instr instr) {
373   return instr & kRsFieldMask;
374 }
375
376
377 uint32_t Assembler::GetRd(Instr instr) {
378   return  (instr & kRdFieldMask) >> kRdShift;
379 }
380
381
382 uint32_t Assembler::GetRdField(Instr instr) {
383   return  instr & kRdFieldMask;
384 }
385
386
387 uint32_t Assembler::GetSa(Instr instr) {
388   return (instr & kSaFieldMask) >> kSaShift;
389 }
390
391
392 uint32_t Assembler::GetSaField(Instr instr) {
393   return instr & kSaFieldMask;
394 }
395
396
397 uint32_t Assembler::GetOpcodeField(Instr instr) {
398   return instr & kOpcodeMask;
399 }
400
401
402 uint32_t Assembler::GetFunction(Instr instr) {
403   return (instr & kFunctionFieldMask) >> kFunctionShift;
404 }
405
406
407 uint32_t Assembler::GetFunctionField(Instr instr) {
408   return instr & kFunctionFieldMask;
409 }
410
411
412 uint32_t Assembler::GetImmediate16(Instr instr) {
413   return instr & kImm16Mask;
414 }
415
416
417 uint32_t Assembler::GetLabelConst(Instr instr) {
418   return instr & ~kImm16Mask;
419 }
420
421
422 bool Assembler::IsPop(Instr instr) {
423   return (instr & ~kRtMask) == kPopRegPattern;
424 }
425
426
427 bool Assembler::IsPush(Instr instr) {
428   return (instr & ~kRtMask) == kPushRegPattern;
429 }
430
431
432 bool Assembler::IsSwRegFpOffset(Instr instr) {
433   return ((instr & kLwSwInstrTypeMask) == kSwRegFpOffsetPattern);
434 }
435
436
437 bool Assembler::IsLwRegFpOffset(Instr instr) {
438   return ((instr & kLwSwInstrTypeMask) == kLwRegFpOffsetPattern);
439 }
440
441
442 bool Assembler::IsSwRegFpNegOffset(Instr instr) {
443   return ((instr & (kLwSwInstrTypeMask | kNegOffset)) ==
444           kSwRegFpNegOffsetPattern);
445 }
446
447
448 bool Assembler::IsLwRegFpNegOffset(Instr instr) {
449   return ((instr & (kLwSwInstrTypeMask | kNegOffset)) ==
450           kLwRegFpNegOffsetPattern);
451 }
452
453
454 // Labels refer to positions in the (to be) generated code.
455 // There are bound, linked, and unused labels.
456 //
457 // Bound labels refer to known positions in the already
458 // generated code. pos() is the position the label refers to.
459 //
460 // Linked labels refer to unknown positions in the code
461 // to be generated; pos() is the position of the last
462 // instruction using the label.
463
464 // The link chain is terminated by a value in the instruction of -1,
465 // which is an otherwise illegal value (branch -1 is inf loop).
466 // The instruction 16-bit offset field addresses 32-bit words, but in
467 // code is conv to an 18-bit value addressing bytes, hence the -4 value.
468
469 const int kEndOfChain = -4;
470 // Determines the end of the Jump chain (a subset of the label link chain).
471 const int kEndOfJumpChain = 0;
472
473
474 bool Assembler::IsBranch(Instr instr) {
475   uint32_t opcode   = GetOpcodeField(instr);
476   uint32_t rt_field = GetRtField(instr);
477   uint32_t rs_field = GetRsField(instr);
478   // Checks if the instruction is a branch.
479   return opcode == BEQ ||
480       opcode == BNE ||
481       opcode == BLEZ ||
482       opcode == BGTZ ||
483       opcode == BEQL ||
484       opcode == BNEL ||
485       opcode == BLEZL ||
486       opcode == BGTZL ||
487       (opcode == REGIMM && (rt_field == BLTZ || rt_field == BGEZ ||
488                             rt_field == BLTZAL || rt_field == BGEZAL)) ||
489       (opcode == COP1 && rs_field == BC1) ||  // Coprocessor branch.
490       (opcode == COP1 && rs_field == BC1EQZ) ||
491       (opcode == COP1 && rs_field == BC1NEZ);
492 }
493
494
495 bool Assembler::IsEmittedConstant(Instr instr) {
496   uint32_t label_constant = GetLabelConst(instr);
497   return label_constant == 0;  // Emitted label const in reg-exp engine.
498 }
499
500
501 bool Assembler::IsBeq(Instr instr) {
502   return GetOpcodeField(instr) == BEQ;
503 }
504
505
506 bool Assembler::IsBne(Instr instr) {
507   return GetOpcodeField(instr) == BNE;
508 }
509
510
511 bool Assembler::IsJump(Instr instr) {
512   uint32_t opcode   = GetOpcodeField(instr);
513   uint32_t rt_field = GetRtField(instr);
514   uint32_t rd_field = GetRdField(instr);
515   uint32_t function_field = GetFunctionField(instr);
516   // Checks if the instruction is a jump.
517   return opcode == J || opcode == JAL ||
518       (opcode == SPECIAL && rt_field == 0 &&
519       ((function_field == JALR) || (rd_field == 0 && (function_field == JR))));
520 }
521
522
523 bool Assembler::IsJ(Instr instr) {
524   uint32_t opcode = GetOpcodeField(instr);
525   // Checks if the instruction is a jump.
526   return opcode == J;
527 }
528
529
530 bool Assembler::IsJal(Instr instr) {
531   return GetOpcodeField(instr) == JAL;
532 }
533
534
535 bool Assembler::IsJr(Instr instr) {
536   if (!IsMipsArchVariant(kMips32r6))  {
537     return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JR;
538   } else {
539     return GetOpcodeField(instr) == SPECIAL &&
540         GetRdField(instr) == 0  && GetFunctionField(instr) == JALR;
541   }
542 }
543
544
545 bool Assembler::IsJalr(Instr instr) {
546   return GetOpcodeField(instr) == SPECIAL &&
547          GetRdField(instr) != 0  && GetFunctionField(instr) == JALR;
548 }
549
550
551 bool Assembler::IsLui(Instr instr) {
552   uint32_t opcode = GetOpcodeField(instr);
553   // Checks if the instruction is a load upper immediate.
554   return opcode == LUI;
555 }
556
557
558 bool Assembler::IsOri(Instr instr) {
559   uint32_t opcode = GetOpcodeField(instr);
560   // Checks if the instruction is a load upper immediate.
561   return opcode == ORI;
562 }
563
564
565 bool Assembler::IsNop(Instr instr, unsigned int type) {
566   // See Assembler::nop(type).
567   DCHECK(type < 32);
568   uint32_t opcode = GetOpcodeField(instr);
569   uint32_t function = GetFunctionField(instr);
570   uint32_t rt = GetRt(instr);
571   uint32_t rd = GetRd(instr);
572   uint32_t sa = GetSa(instr);
573
574   // Traditional mips nop == sll(zero_reg, zero_reg, 0)
575   // When marking non-zero type, use sll(zero_reg, at, type)
576   // to avoid use of mips ssnop and ehb special encodings
577   // of the sll instruction.
578
579   Register nop_rt_reg = (type == 0) ? zero_reg : at;
580   bool ret = (opcode == SPECIAL && function == SLL &&
581               rd == static_cast<uint32_t>(ToNumber(zero_reg)) &&
582               rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) &&
583               sa == type);
584
585   return ret;
586 }
587
588
589 int32_t Assembler::GetBranchOffset(Instr instr) {
590   DCHECK(IsBranch(instr));
591   return (static_cast<int16_t>(instr & kImm16Mask)) << 2;
592 }
593
594
595 bool Assembler::IsLw(Instr instr) {
596   return ((instr & kOpcodeMask) == LW);
597 }
598
599
600 int16_t Assembler::GetLwOffset(Instr instr) {
601   DCHECK(IsLw(instr));
602   return ((instr & kImm16Mask));
603 }
604
605
606 Instr Assembler::SetLwOffset(Instr instr, int16_t offset) {
607   DCHECK(IsLw(instr));
608
609   // We actually create a new lw instruction based on the original one.
610   Instr temp_instr = LW | (instr & kRsFieldMask) | (instr & kRtFieldMask)
611       | (offset & kImm16Mask);
612
613   return temp_instr;
614 }
615
616
617 bool Assembler::IsSw(Instr instr) {
618   return ((instr & kOpcodeMask) == SW);
619 }
620
621
622 Instr Assembler::SetSwOffset(Instr instr, int16_t offset) {
623   DCHECK(IsSw(instr));
624   return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
625 }
626
627
628 bool Assembler::IsAddImmediate(Instr instr) {
629   return ((instr & kOpcodeMask) == ADDIU);
630 }
631
632
633 Instr Assembler::SetAddImmediateOffset(Instr instr, int16_t offset) {
634   DCHECK(IsAddImmediate(instr));
635   return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
636 }
637
638
639 bool Assembler::IsAndImmediate(Instr instr) {
640   return GetOpcodeField(instr) == ANDI;
641 }
642
643
644 int Assembler::target_at(int pos, bool is_internal) {
645   Instr instr = instr_at(pos);
646   if (is_internal) {
647     if (instr == 0) {
648       return kEndOfChain;
649     } else {
650       int32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos);
651       int delta = static_cast<int>(instr_address - instr);
652       DCHECK(pos > delta);
653       return pos - delta;
654     }
655   }
656   if ((instr & ~kImm16Mask) == 0) {
657     // Emitted label constant, not part of a branch.
658     if (instr == 0) {
659        return kEndOfChain;
660      } else {
661        int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
662        return (imm18 + pos);
663      }
664   }
665   // Check we have a branch or jump instruction.
666   DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr));
667   // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
668   // the compiler uses arithmectic shifts for signed integers.
669   if (IsBranch(instr)) {
670     int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
671
672     if (imm18 == kEndOfChain) {
673       // EndOfChain sentinel is returned directly, not relative to pc or pos.
674       return kEndOfChain;
675     } else {
676       return pos + kBranchPCOffset + imm18;
677     }
678   } else if (IsLui(instr)) {
679     Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
680     Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
681     DCHECK(IsOri(instr_ori));
682     int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift;
683     imm |= (instr_ori & static_cast<int32_t>(kImm16Mask));
684
685     if (imm == kEndOfJumpChain) {
686       // EndOfChain sentinel is returned directly, not relative to pc or pos.
687       return kEndOfChain;
688     } else {
689       uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos);
690       int32_t delta = instr_address - imm;
691       DCHECK(pos > delta);
692       return pos - delta;
693     }
694   } else {
695     int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
696     if (imm28 == kEndOfJumpChain) {
697       // EndOfChain sentinel is returned directly, not relative to pc or pos.
698       return kEndOfChain;
699     } else {
700       uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos);
701       instr_address &= kImm28Mask;
702       int delta = static_cast<int>(instr_address - imm28);
703       DCHECK(pos > delta);
704       return pos - delta;
705     }
706   }
707 }
708
709
710 void Assembler::target_at_put(int32_t pos, int32_t target_pos,
711                               bool is_internal) {
712   Instr instr = instr_at(pos);
713
714   if (is_internal) {
715     uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos;
716     instr_at_put(pos, imm);
717     return;
718   }
719   if ((instr & ~kImm16Mask) == 0) {
720     DCHECK(target_pos == kEndOfChain || target_pos >= 0);
721     // Emitted label constant, not part of a branch.
722     // Make label relative to Code* of generated Code object.
723     instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
724     return;
725   }
726
727   DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr));
728   if (IsBranch(instr)) {
729     int32_t imm18 = target_pos - (pos + kBranchPCOffset);
730     DCHECK((imm18 & 3) == 0);
731
732     instr &= ~kImm16Mask;
733     int32_t imm16 = imm18 >> 2;
734     DCHECK(is_int16(imm16));
735
736     instr_at_put(pos, instr | (imm16 & kImm16Mask));
737   } else if (IsLui(instr)) {
738     Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
739     Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
740     DCHECK(IsOri(instr_ori));
741     uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos;
742     DCHECK((imm & 3) == 0);
743
744     instr_lui &= ~kImm16Mask;
745     instr_ori &= ~kImm16Mask;
746
747     instr_at_put(pos + 0 * Assembler::kInstrSize,
748                  instr_lui | ((imm & kHiMask) >> kLuiShift));
749     instr_at_put(pos + 1 * Assembler::kInstrSize,
750                  instr_ori | (imm & kImm16Mask));
751   } else {
752     uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos;
753     imm28 &= kImm28Mask;
754     DCHECK((imm28 & 3) == 0);
755
756     instr &= ~kImm26Mask;
757     uint32_t imm26 = imm28 >> 2;
758     DCHECK(is_uint26(imm26));
759
760     instr_at_put(pos, instr | (imm26 & kImm26Mask));
761   }
762 }
763
764
765 void Assembler::print(Label* L) {
766   if (L->is_unused()) {
767     PrintF("unused label\n");
768   } else if (L->is_bound()) {
769     PrintF("bound label to %d\n", L->pos());
770   } else if (L->is_linked()) {
771     Label l = *L;
772     PrintF("unbound label");
773     while (l.is_linked()) {
774       PrintF("@ %d ", l.pos());
775       Instr instr = instr_at(l.pos());
776       if ((instr & ~kImm16Mask) == 0) {
777         PrintF("value\n");
778       } else {
779         PrintF("%d\n", instr);
780       }
781       next(&l, internal_reference_positions_.find(l.pos()) !=
782                    internal_reference_positions_.end());
783     }
784   } else {
785     PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
786   }
787 }
788
789
790 void Assembler::bind_to(Label* L, int pos) {
791   DCHECK(0 <= pos && pos <= pc_offset());  // Must have valid binding position.
792   int32_t trampoline_pos = kInvalidSlotPos;
793   bool is_internal = false;
794   if (L->is_linked() && !trampoline_emitted_) {
795     unbound_labels_count_--;
796     next_buffer_check_ += kTrampolineSlotsSize;
797   }
798
799   while (L->is_linked()) {
800     int32_t fixup_pos = L->pos();
801     int32_t dist = pos - fixup_pos;
802     is_internal = internal_reference_positions_.find(fixup_pos) !=
803                   internal_reference_positions_.end();
804     next(L, is_internal);  // Call next before overwriting link with target at
805                            // fixup_pos.
806     Instr instr = instr_at(fixup_pos);
807     if (is_internal) {
808       target_at_put(fixup_pos, pos, is_internal);
809     } else if (!is_internal && IsBranch(instr)) {
810       if (dist > kMaxBranchOffset) {
811         if (trampoline_pos == kInvalidSlotPos) {
812           trampoline_pos = get_trampoline_entry(fixup_pos);
813           CHECK(trampoline_pos != kInvalidSlotPos);
814         }
815         DCHECK((trampoline_pos - fixup_pos) <= kMaxBranchOffset);
816         target_at_put(fixup_pos, trampoline_pos, false);
817         fixup_pos = trampoline_pos;
818         dist = pos - fixup_pos;
819       }
820       target_at_put(fixup_pos, pos, false);
821     } else {
822       target_at_put(fixup_pos, pos, false);
823     }
824   }
825   L->bind_to(pos);
826
827   // Keep track of the last bound label so we don't eliminate any instructions
828   // before a bound label.
829   if (pos > last_bound_pos_)
830     last_bound_pos_ = pos;
831 }
832
833
834 void Assembler::bind(Label* L) {
835   DCHECK(!L->is_bound());  // Label can only be bound once.
836   bind_to(L, pc_offset());
837 }
838
839
840 void Assembler::next(Label* L, bool is_internal) {
841   DCHECK(L->is_linked());
842   int link = target_at(L->pos(), is_internal);
843   if (link == kEndOfChain) {
844     L->Unuse();
845   } else {
846     DCHECK(link >= 0);
847     L->link_to(link);
848   }
849 }
850
851
852 bool Assembler::is_near(Label* L) {
853   if (L->is_bound()) {
854     return ((pc_offset() - L->pos()) < kMaxBranchOffset - 4 * kInstrSize);
855   }
856   return false;
857 }
858
859
860 // We have to use a temporary register for things that can be relocated even
861 // if they can be encoded in the MIPS's 16 bits of immediate-offset instruction
862 // space.  There is no guarantee that the relocated location can be similarly
863 // encoded.
864 bool Assembler::MustUseReg(RelocInfo::Mode rmode) {
865   return !RelocInfo::IsNone(rmode);
866 }
867
868 void Assembler::GenInstrRegister(Opcode opcode,
869                                  Register rs,
870                                  Register rt,
871                                  Register rd,
872                                  uint16_t sa,
873                                  SecondaryField func) {
874   DCHECK(rd.is_valid() && rs.is_valid() && rt.is_valid() && is_uint5(sa));
875   Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
876       | (rd.code() << kRdShift) | (sa << kSaShift) | func;
877   emit(instr);
878 }
879
880
881 void Assembler::GenInstrRegister(Opcode opcode,
882                                  Register rs,
883                                  Register rt,
884                                  uint16_t msb,
885                                  uint16_t lsb,
886                                  SecondaryField func) {
887   DCHECK(rs.is_valid() && rt.is_valid() && is_uint5(msb) && is_uint5(lsb));
888   Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
889       | (msb << kRdShift) | (lsb << kSaShift) | func;
890   emit(instr);
891 }
892
893
894 void Assembler::GenInstrRegister(Opcode opcode,
895                                  SecondaryField fmt,
896                                  FPURegister ft,
897                                  FPURegister fs,
898                                  FPURegister fd,
899                                  SecondaryField func) {
900   DCHECK(fd.is_valid() && fs.is_valid() && ft.is_valid());
901   Instr instr = opcode | fmt | (ft.code() << kFtShift) | (fs.code() << kFsShift)
902       | (fd.code() << kFdShift) | func;
903   emit(instr);
904 }
905
906
907 void Assembler::GenInstrRegister(Opcode opcode,
908                                  FPURegister fr,
909                                  FPURegister ft,
910                                  FPURegister fs,
911                                  FPURegister fd,
912                                  SecondaryField func) {
913   DCHECK(fd.is_valid() && fr.is_valid() && fs.is_valid() && ft.is_valid());
914   Instr instr = opcode | (fr.code() << kFrShift) | (ft.code() << kFtShift)
915       | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
916   emit(instr);
917 }
918
919
920 void Assembler::GenInstrRegister(Opcode opcode,
921                                  SecondaryField fmt,
922                                  Register rt,
923                                  FPURegister fs,
924                                  FPURegister fd,
925                                  SecondaryField func) {
926   DCHECK(fd.is_valid() && fs.is_valid() && rt.is_valid());
927   Instr instr = opcode | fmt | (rt.code() << kRtShift)
928       | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
929   emit(instr);
930 }
931
932
933 void Assembler::GenInstrRegister(Opcode opcode,
934                                  SecondaryField fmt,
935                                  Register rt,
936                                  FPUControlRegister fs,
937                                  SecondaryField func) {
938   DCHECK(fs.is_valid() && rt.is_valid());
939   Instr instr =
940       opcode | fmt | (rt.code() << kRtShift) | (fs.code() << kFsShift) | func;
941   emit(instr);
942 }
943
944
945 // Instructions with immediate value.
946 // Registers are in the order of the instruction encoding, from left to right.
947 void Assembler::GenInstrImmediate(Opcode opcode,
948                                   Register rs,
949                                   Register rt,
950                                   int32_t j) {
951   DCHECK(rs.is_valid() && rt.is_valid() && (is_int16(j) || is_uint16(j)));
952   Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
953       | (j & kImm16Mask);
954   emit(instr);
955 }
956
957
958 void Assembler::GenInstrImmediate(Opcode opcode,
959                                   Register rs,
960                                   SecondaryField SF,
961                                   int32_t j) {
962   DCHECK(rs.is_valid() && (is_int16(j) || is_uint16(j)));
963   Instr instr = opcode | (rs.code() << kRsShift) | SF | (j & kImm16Mask);
964   emit(instr);
965 }
966
967
968 void Assembler::GenInstrImmediate(Opcode opcode,
969                                   Register rs,
970                                   FPURegister ft,
971                                   int32_t j) {
972   DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j)));
973   Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift)
974       | (j & kImm16Mask);
975   emit(instr);
976 }
977
978
979 void Assembler::GenInstrJump(Opcode opcode,
980                              uint32_t address) {
981   BlockTrampolinePoolScope block_trampoline_pool(this);
982   DCHECK(is_uint26(address));
983   Instr instr = opcode | address;
984   emit(instr);
985   BlockTrampolinePoolFor(1);  // For associated delay slot.
986 }
987
988
989 // Returns the next free trampoline entry.
990 int32_t Assembler::get_trampoline_entry(int32_t pos) {
991   int32_t trampoline_entry = kInvalidSlotPos;
992
993   if (!internal_trampoline_exception_) {
994     if (trampoline_.start() > pos) {
995      trampoline_entry = trampoline_.take_slot();
996     }
997
998     if (kInvalidSlotPos == trampoline_entry) {
999       internal_trampoline_exception_ = true;
1000     }
1001   }
1002   return trampoline_entry;
1003 }
1004
1005
1006 uint32_t Assembler::jump_address(Label* L) {
1007   int32_t target_pos;
1008
1009   if (L->is_bound()) {
1010     target_pos = L->pos();
1011   } else {
1012     if (L->is_linked()) {
1013       target_pos = L->pos();  // L's link.
1014       L->link_to(pc_offset());
1015     } else {
1016       L->link_to(pc_offset());
1017       return kEndOfJumpChain;
1018     }
1019   }
1020
1021   uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos;
1022   DCHECK((imm & 3) == 0);
1023
1024   return imm;
1025 }
1026
1027
1028 int32_t Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
1029   int32_t target_pos;
1030
1031   if (L->is_bound()) {
1032     target_pos = L->pos();
1033   } else {
1034     if (L->is_linked()) {
1035       target_pos = L->pos();
1036       L->link_to(pc_offset());
1037     } else {
1038       L->link_to(pc_offset());
1039       if (!trampoline_emitted_) {
1040         unbound_labels_count_++;
1041         next_buffer_check_ -= kTrampolineSlotsSize;
1042       }
1043       return kEndOfChain;
1044     }
1045   }
1046
1047   int32_t offset = target_pos - (pc_offset() + kBranchPCOffset);
1048   DCHECK((offset & 3) == 0);
1049   DCHECK(is_int16(offset >> 2));
1050
1051   return offset;
1052 }
1053
1054
1055 int32_t Assembler::branch_offset_compact(Label* L,
1056     bool jump_elimination_allowed) {
1057   int32_t target_pos;
1058   if (L->is_bound()) {
1059     target_pos = L->pos();
1060   } else {
1061     if (L->is_linked()) {
1062       target_pos = L->pos();
1063       L->link_to(pc_offset());
1064     } else {
1065       L->link_to(pc_offset());
1066       if (!trampoline_emitted_) {
1067         unbound_labels_count_++;
1068         next_buffer_check_ -= kTrampolineSlotsSize;
1069       }
1070       return kEndOfChain;
1071     }
1072   }
1073
1074   int32_t offset = target_pos - pc_offset();
1075   DCHECK((offset & 3) == 0);
1076   DCHECK(is_int16(offset >> 2));
1077
1078   return offset;
1079 }
1080
1081
1082 int32_t Assembler::branch_offset21(Label* L, bool jump_elimination_allowed) {
1083   int32_t target_pos;
1084
1085   if (L->is_bound()) {
1086     target_pos = L->pos();
1087   } else {
1088     if (L->is_linked()) {
1089       target_pos = L->pos();
1090       L->link_to(pc_offset());
1091     } else {
1092       L->link_to(pc_offset());
1093       if (!trampoline_emitted_) {
1094         unbound_labels_count_++;
1095         next_buffer_check_ -= kTrampolineSlotsSize;
1096       }
1097       return kEndOfChain;
1098     }
1099   }
1100
1101   int32_t offset = target_pos - (pc_offset() + kBranchPCOffset);
1102   DCHECK((offset & 3) == 0);
1103   DCHECK(((offset >> 2) & 0xFFE00000) == 0);  // Offset is 21bit width.
1104
1105   return offset;
1106 }
1107
1108
1109 int32_t Assembler::branch_offset21_compact(Label* L,
1110     bool jump_elimination_allowed) {
1111   int32_t target_pos;
1112
1113   if (L->is_bound()) {
1114     target_pos = L->pos();
1115   } else {
1116     if (L->is_linked()) {
1117       target_pos = L->pos();
1118       L->link_to(pc_offset());
1119     } else {
1120       L->link_to(pc_offset());
1121       if (!trampoline_emitted_) {
1122         unbound_labels_count_++;
1123         next_buffer_check_ -= kTrampolineSlotsSize;
1124       }
1125       return kEndOfChain;
1126     }
1127   }
1128
1129   int32_t offset = target_pos - pc_offset();
1130   DCHECK((offset & 3) == 0);
1131   DCHECK(((offset >> 2) & 0xFFe00000) == 0);  // Offset is 21bit width.
1132
1133   return offset;
1134 }
1135
1136
1137 void Assembler::label_at_put(Label* L, int at_offset) {
1138   int target_pos;
1139   if (L->is_bound()) {
1140     target_pos = L->pos();
1141     instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
1142   } else {
1143     if (L->is_linked()) {
1144       target_pos = L->pos();  // L's link.
1145       int32_t imm18 = target_pos - at_offset;
1146       DCHECK((imm18 & 3) == 0);
1147       int32_t imm16 = imm18 >> 2;
1148       DCHECK(is_int16(imm16));
1149       instr_at_put(at_offset, (imm16 & kImm16Mask));
1150     } else {
1151       target_pos = kEndOfChain;
1152       instr_at_put(at_offset, 0);
1153       if (!trampoline_emitted_) {
1154         unbound_labels_count_++;
1155         next_buffer_check_ -= kTrampolineSlotsSize;
1156       }
1157     }
1158     L->link_to(at_offset);
1159   }
1160 }
1161
1162
1163 //------- Branch and jump instructions --------
1164
1165 void Assembler::b(int16_t offset) {
1166   beq(zero_reg, zero_reg, offset);
1167 }
1168
1169
1170 void Assembler::bal(int16_t offset) {
1171   positions_recorder()->WriteRecordedPositions();
1172   bgezal(zero_reg, offset);
1173 }
1174
1175
1176 void Assembler::beq(Register rs, Register rt, int16_t offset) {
1177   BlockTrampolinePoolScope block_trampoline_pool(this);
1178   GenInstrImmediate(BEQ, rs, rt, offset);
1179   BlockTrampolinePoolFor(1);  // For associated delay slot.
1180 }
1181
1182
1183 void Assembler::bgez(Register rs, int16_t offset) {
1184   BlockTrampolinePoolScope block_trampoline_pool(this);
1185   GenInstrImmediate(REGIMM, rs, BGEZ, offset);
1186   BlockTrampolinePoolFor(1);  // For associated delay slot.
1187 }
1188
1189
1190 void Assembler::bgezc(Register rt, int16_t offset) {
1191   DCHECK(IsMipsArchVariant(kMips32r6));
1192   DCHECK(!(rt.is(zero_reg)));
1193   GenInstrImmediate(BLEZL, rt, rt, offset);
1194 }
1195
1196
1197 void Assembler::bgeuc(Register rs, Register rt, int16_t offset) {
1198   DCHECK(IsMipsArchVariant(kMips32r6));
1199   DCHECK(!(rs.is(zero_reg)));
1200   DCHECK(!(rt.is(zero_reg)));
1201   DCHECK(rs.code() != rt.code());
1202   GenInstrImmediate(BLEZ, rs, rt, offset);
1203 }
1204
1205
1206 void Assembler::bgec(Register rs, Register rt, int16_t offset) {
1207   DCHECK(IsMipsArchVariant(kMips32r6));
1208   DCHECK(!(rs.is(zero_reg)));
1209   DCHECK(!(rt.is(zero_reg)));
1210   DCHECK(rs.code() != rt.code());
1211   GenInstrImmediate(BLEZL, rs, rt, offset);
1212 }
1213
1214
1215 void Assembler::bgezal(Register rs, int16_t offset) {
1216   DCHECK(!IsMipsArchVariant(kMips32r6) || rs.is(zero_reg));
1217   BlockTrampolinePoolScope block_trampoline_pool(this);
1218   positions_recorder()->WriteRecordedPositions();
1219   GenInstrImmediate(REGIMM, rs, BGEZAL, offset);
1220   BlockTrampolinePoolFor(1);  // For associated delay slot.
1221 }
1222
1223
1224 void Assembler::bgtz(Register rs, int16_t offset) {
1225   BlockTrampolinePoolScope block_trampoline_pool(this);
1226   GenInstrImmediate(BGTZ, rs, zero_reg, offset);
1227   BlockTrampolinePoolFor(1);  // For associated delay slot.
1228 }
1229
1230
1231 void Assembler::bgtzc(Register rt, int16_t offset) {
1232   DCHECK(IsMipsArchVariant(kMips32r6));
1233   DCHECK(!(rt.is(zero_reg)));
1234   GenInstrImmediate(BGTZL, zero_reg, rt, offset);
1235 }
1236
1237
1238 void Assembler::blez(Register rs, int16_t offset) {
1239   BlockTrampolinePoolScope block_trampoline_pool(this);
1240   GenInstrImmediate(BLEZ, rs, zero_reg, offset);
1241   BlockTrampolinePoolFor(1);  // For associated delay slot.
1242 }
1243
1244
1245 void Assembler::blezc(Register rt, int16_t offset) {
1246   DCHECK(IsMipsArchVariant(kMips32r6));
1247   DCHECK(!(rt.is(zero_reg)));
1248   GenInstrImmediate(BLEZL, zero_reg, rt, offset);
1249 }
1250
1251
1252 void Assembler::bltzc(Register rt, int16_t offset) {
1253   DCHECK(IsMipsArchVariant(kMips32r6));
1254   DCHECK(!(rt.is(zero_reg)));
1255   GenInstrImmediate(BGTZL, rt, rt, offset);
1256 }
1257
1258
1259 void Assembler::bltuc(Register rs, Register rt, int16_t offset) {
1260   DCHECK(IsMipsArchVariant(kMips32r6));
1261   DCHECK(!(rs.is(zero_reg)));
1262   DCHECK(!(rt.is(zero_reg)));
1263   DCHECK(rs.code() != rt.code());
1264   GenInstrImmediate(BGTZ, rs, rt, offset);
1265 }
1266
1267
1268 void Assembler::bltc(Register rs, Register rt, int16_t offset) {
1269   DCHECK(IsMipsArchVariant(kMips32r6));
1270   DCHECK(!(rs.is(zero_reg)));
1271   DCHECK(!(rt.is(zero_reg)));
1272   DCHECK(rs.code() != rt.code());
1273   GenInstrImmediate(BGTZL, rs, rt, offset);
1274 }
1275
1276
1277 void Assembler::bltz(Register rs, int16_t offset) {
1278   BlockTrampolinePoolScope block_trampoline_pool(this);
1279   GenInstrImmediate(REGIMM, rs, BLTZ, offset);
1280   BlockTrampolinePoolFor(1);  // For associated delay slot.
1281 }
1282
1283
1284 void Assembler::bltzal(Register rs, int16_t offset) {
1285   DCHECK(!IsMipsArchVariant(kMips32r6) || rs.is(zero_reg));
1286   BlockTrampolinePoolScope block_trampoline_pool(this);
1287   positions_recorder()->WriteRecordedPositions();
1288   GenInstrImmediate(REGIMM, rs, BLTZAL, offset);
1289   BlockTrampolinePoolFor(1);  // For associated delay slot.
1290 }
1291
1292
1293 void Assembler::bne(Register rs, Register rt, int16_t offset) {
1294   BlockTrampolinePoolScope block_trampoline_pool(this);
1295   GenInstrImmediate(BNE, rs, rt, offset);
1296   BlockTrampolinePoolFor(1);  // For associated delay slot.
1297 }
1298
1299
1300 void Assembler::bovc(Register rs, Register rt, int16_t offset) {
1301   DCHECK(IsMipsArchVariant(kMips32r6));
1302   DCHECK(!(rs.is(zero_reg)));
1303   DCHECK(rs.code() >= rt.code());
1304   GenInstrImmediate(ADDI, rs, rt, offset);
1305 }
1306
1307
1308 void Assembler::bnvc(Register rs, Register rt, int16_t offset) {
1309   DCHECK(IsMipsArchVariant(kMips32r6));
1310   DCHECK(!(rs.is(zero_reg)));
1311   DCHECK(rs.code() >= rt.code());
1312   GenInstrImmediate(DADDI, rs, rt, offset);
1313 }
1314
1315
1316 void Assembler::blezalc(Register rt, int16_t offset) {
1317   DCHECK(IsMipsArchVariant(kMips32r6));
1318   DCHECK(!(rt.is(zero_reg)));
1319   GenInstrImmediate(BLEZ, zero_reg, rt, offset);
1320 }
1321
1322
1323 void Assembler::bgezalc(Register rt, int16_t offset) {
1324   DCHECK(IsMipsArchVariant(kMips32r6));
1325   DCHECK(!(rt.is(zero_reg)));
1326   GenInstrImmediate(BLEZ, rt, rt, offset);
1327 }
1328
1329
1330 void Assembler::bgezall(Register rs, int16_t offset) {
1331   DCHECK(IsMipsArchVariant(kMips32r6));
1332   DCHECK(!(rs.is(zero_reg)));
1333   GenInstrImmediate(REGIMM, rs, BGEZALL, offset);
1334 }
1335
1336
1337 void Assembler::bltzalc(Register rt, int16_t offset) {
1338   DCHECK(IsMipsArchVariant(kMips32r6));
1339   DCHECK(!(rt.is(zero_reg)));
1340   GenInstrImmediate(BGTZ, rt, rt, offset);
1341 }
1342
1343
1344 void Assembler::bgtzalc(Register rt, int16_t offset) {
1345   DCHECK(IsMipsArchVariant(kMips32r6));
1346   DCHECK(!(rt.is(zero_reg)));
1347   GenInstrImmediate(BGTZ, zero_reg, rt, offset);
1348 }
1349
1350
1351 void Assembler::beqzalc(Register rt, int16_t offset) {
1352   DCHECK(IsMipsArchVariant(kMips32r6));
1353   DCHECK(!(rt.is(zero_reg)));
1354   GenInstrImmediate(ADDI, zero_reg, rt, offset);
1355 }
1356
1357
1358 void Assembler::bnezalc(Register rt, int16_t offset) {
1359   DCHECK(IsMipsArchVariant(kMips32r6));
1360   DCHECK(!(rt.is(zero_reg)));
1361   GenInstrImmediate(DADDI, zero_reg, rt, offset);
1362 }
1363
1364
1365 void Assembler::beqc(Register rs, Register rt, int16_t offset) {
1366   DCHECK(IsMipsArchVariant(kMips32r6));
1367   DCHECK(rs.code() < rt.code());
1368   GenInstrImmediate(ADDI, rs, rt, offset);
1369 }
1370
1371
1372 void Assembler::beqzc(Register rs, int32_t offset) {
1373   DCHECK(IsMipsArchVariant(kMips32r6));
1374   DCHECK(!(rs.is(zero_reg)));
1375   Instr instr = BEQZC | (rs.code() << kRsShift) | offset;
1376   emit(instr);
1377 }
1378
1379
1380 void Assembler::bnec(Register rs, Register rt, int16_t offset) {
1381   DCHECK(IsMipsArchVariant(kMips32r6));
1382   DCHECK(rs.code() < rt.code());
1383   GenInstrImmediate(DADDI, rs, rt, offset);
1384 }
1385
1386
1387 void Assembler::bnezc(Register rs, int32_t offset) {
1388   DCHECK(IsMipsArchVariant(kMips32r6));
1389   DCHECK(!(rs.is(zero_reg)));
1390   Instr instr = BNEZC | (rs.code() << kRsShift) | offset;
1391   emit(instr);
1392 }
1393
1394
1395 void Assembler::j(int32_t target) {
1396 #if DEBUG
1397   // Get pc of delay slot.
1398   uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize);
1399   bool in_range = (ipc ^ static_cast<uint32_t>(target) >>
1400                   (kImm26Bits + kImmFieldShift)) == 0;
1401   DCHECK(in_range && ((target & 3) == 0));
1402 #endif
1403   GenInstrJump(J, target >> 2);
1404 }
1405
1406
1407 void Assembler::jr(Register rs) {
1408   if (!IsMipsArchVariant(kMips32r6)) {
1409     BlockTrampolinePoolScope block_trampoline_pool(this);
1410     if (rs.is(ra)) {
1411       positions_recorder()->WriteRecordedPositions();
1412     }
1413     GenInstrRegister(SPECIAL, rs, zero_reg, zero_reg, 0, JR);
1414     BlockTrampolinePoolFor(1);  // For associated delay slot.
1415   } else {
1416     jalr(rs, zero_reg);
1417   }
1418 }
1419
1420
1421 void Assembler::jal(int32_t target) {
1422 #ifdef DEBUG
1423   // Get pc of delay slot.
1424   uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize);
1425   bool in_range = (ipc ^ static_cast<uint32_t>(target) >>
1426                   (kImm26Bits + kImmFieldShift)) == 0;
1427   DCHECK(in_range && ((target & 3) == 0));
1428 #endif
1429   positions_recorder()->WriteRecordedPositions();
1430   GenInstrJump(JAL, target >> 2);
1431 }
1432
1433
1434 void Assembler::jalr(Register rs, Register rd) {
1435   BlockTrampolinePoolScope block_trampoline_pool(this);
1436   positions_recorder()->WriteRecordedPositions();
1437   GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR);
1438   BlockTrampolinePoolFor(1);  // For associated delay slot.
1439 }
1440
1441
1442 void Assembler::j_or_jr(int32_t target, Register rs) {
1443   // Get pc of delay slot.
1444   uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize);
1445   bool in_range = (ipc ^ static_cast<uint32_t>(target) >>
1446                   (kImm26Bits + kImmFieldShift)) == 0;
1447   if (in_range) {
1448       j(target);
1449   } else {
1450       jr(t9);
1451   }
1452 }
1453
1454
1455 void Assembler::jal_or_jalr(int32_t target, Register rs) {
1456   // Get pc of delay slot.
1457   uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize);
1458   bool in_range = (ipc ^ static_cast<uint32_t>(target) >>
1459                   (kImm26Bits+kImmFieldShift)) == 0;
1460   if (in_range) {
1461       jal(target);
1462   } else {
1463       jalr(t9);
1464   }
1465 }
1466
1467
1468 // -------Data-processing-instructions---------
1469
1470 // Arithmetic.
1471
1472 void Assembler::addu(Register rd, Register rs, Register rt) {
1473   GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU);
1474 }
1475
1476
1477 void Assembler::addiu(Register rd, Register rs, int32_t j) {
1478   GenInstrImmediate(ADDIU, rs, rd, j);
1479 }
1480
1481
1482 void Assembler::subu(Register rd, Register rs, Register rt) {
1483   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SUBU);
1484 }
1485
1486
1487 void Assembler::mul(Register rd, Register rs, Register rt) {
1488   if (!IsMipsArchVariant(kMips32r6)) {
1489     GenInstrRegister(SPECIAL2, rs, rt, rd, 0, MUL);
1490   } else {
1491     GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH);
1492   }
1493 }
1494
1495
1496 void Assembler::mulu(Register rd, Register rs, Register rt) {
1497   DCHECK(IsMipsArchVariant(kMips32r6));
1498   GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH_U);
1499 }
1500
1501
1502 void Assembler::muh(Register rd, Register rs, Register rt) {
1503   DCHECK(IsMipsArchVariant(kMips32r6));
1504   GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH);
1505 }
1506
1507
1508 void Assembler::muhu(Register rd, Register rs, Register rt) {
1509   DCHECK(IsMipsArchVariant(kMips32r6));
1510   GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH_U);
1511 }
1512
1513
1514 void Assembler::mod(Register rd, Register rs, Register rt) {
1515   DCHECK(IsMipsArchVariant(kMips32r6));
1516   GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD);
1517 }
1518
1519
1520 void Assembler::modu(Register rd, Register rs, Register rt) {
1521   DCHECK(IsMipsArchVariant(kMips32r6));
1522   GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD_U);
1523 }
1524
1525
1526 void Assembler::mult(Register rs, Register rt) {
1527   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULT);
1528 }
1529
1530
1531 void Assembler::multu(Register rs, Register rt) {
1532   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULTU);
1533 }
1534
1535
1536 void Assembler::div(Register rs, Register rt) {
1537   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIV);
1538 }
1539
1540
1541 void Assembler::div(Register rd, Register rs, Register rt) {
1542   DCHECK(IsMipsArchVariant(kMips32r6));
1543   GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD);
1544 }
1545
1546
1547 void Assembler::divu(Register rs, Register rt) {
1548   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIVU);
1549 }
1550
1551
1552 void Assembler::divu(Register rd, Register rs, Register rt) {
1553   DCHECK(IsMipsArchVariant(kMips32r6));
1554   GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD_U);
1555 }
1556
1557
1558 // Logical.
1559
1560 void Assembler::and_(Register rd, Register rs, Register rt) {
1561   GenInstrRegister(SPECIAL, rs, rt, rd, 0, AND);
1562 }
1563
1564
1565 void Assembler::andi(Register rt, Register rs, int32_t j) {
1566   DCHECK(is_uint16(j));
1567   GenInstrImmediate(ANDI, rs, rt, j);
1568 }
1569
1570
1571 void Assembler::or_(Register rd, Register rs, Register rt) {
1572   GenInstrRegister(SPECIAL, rs, rt, rd, 0, OR);
1573 }
1574
1575
1576 void Assembler::ori(Register rt, Register rs, int32_t j) {
1577   DCHECK(is_uint16(j));
1578   GenInstrImmediate(ORI, rs, rt, j);
1579 }
1580
1581
1582 void Assembler::xor_(Register rd, Register rs, Register rt) {
1583   GenInstrRegister(SPECIAL, rs, rt, rd, 0, XOR);
1584 }
1585
1586
1587 void Assembler::xori(Register rt, Register rs, int32_t j) {
1588   DCHECK(is_uint16(j));
1589   GenInstrImmediate(XORI, rs, rt, j);
1590 }
1591
1592
1593 void Assembler::nor(Register rd, Register rs, Register rt) {
1594   GenInstrRegister(SPECIAL, rs, rt, rd, 0, NOR);
1595 }
1596
1597
1598 // Shifts.
1599 void Assembler::sll(Register rd,
1600                     Register rt,
1601                     uint16_t sa,
1602                     bool coming_from_nop) {
1603   // Don't allow nop instructions in the form sll zero_reg, zero_reg to be
1604   // generated using the sll instruction. They must be generated using
1605   // nop(int/NopMarkerTypes) or MarkCode(int/NopMarkerTypes) pseudo
1606   // instructions.
1607   DCHECK(coming_from_nop || !(rd.is(zero_reg) && rt.is(zero_reg)));
1608   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, SLL);
1609 }
1610
1611
1612 void Assembler::sllv(Register rd, Register rt, Register rs) {
1613   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLLV);
1614 }
1615
1616
1617 void Assembler::srl(Register rd, Register rt, uint16_t sa) {
1618   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, SRL);
1619 }
1620
1621
1622 void Assembler::srlv(Register rd, Register rt, Register rs) {
1623   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRLV);
1624 }
1625
1626
1627 void Assembler::sra(Register rd, Register rt, uint16_t sa) {
1628   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, SRA);
1629 }
1630
1631
1632 void Assembler::srav(Register rd, Register rt, Register rs) {
1633   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRAV);
1634 }
1635
1636
1637 void Assembler::rotr(Register rd, Register rt, uint16_t sa) {
1638   // Should be called via MacroAssembler::Ror.
1639   DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
1640   DCHECK(IsMipsArchVariant(kMips32r2));
1641   Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift)
1642       | (rd.code() << kRdShift) | (sa << kSaShift) | SRL;
1643   emit(instr);
1644 }
1645
1646
1647 void Assembler::rotrv(Register rd, Register rt, Register rs) {
1648   // Should be called via MacroAssembler::Ror.
1649   DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid() );
1650   DCHECK(IsMipsArchVariant(kMips32r2));
1651   Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift)
1652      | (rd.code() << kRdShift) | (1 << kSaShift) | SRLV;
1653   emit(instr);
1654 }
1655
1656
1657 // ------------Memory-instructions-------------
1658
1659 // Helper for base-reg + offset, when offset is larger than int16.
1660 void Assembler::LoadRegPlusOffsetToAt(const MemOperand& src) {
1661   DCHECK(!src.rm().is(at));
1662   lui(at, (src.offset_ >> kLuiShift) & kImm16Mask);
1663   ori(at, at, src.offset_ & kImm16Mask);  // Load 32-bit offset.
1664   addu(at, at, src.rm());  // Add base register.
1665 }
1666
1667
1668 void Assembler::lb(Register rd, const MemOperand& rs) {
1669   if (is_int16(rs.offset_)) {
1670     GenInstrImmediate(LB, rs.rm(), rd, rs.offset_);
1671   } else {  // Offset > 16 bits, use multiple instructions to load.
1672     LoadRegPlusOffsetToAt(rs);
1673     GenInstrImmediate(LB, at, rd, 0);  // Equiv to lb(rd, MemOperand(at, 0));
1674   }
1675 }
1676
1677
1678 void Assembler::lbu(Register rd, const MemOperand& rs) {
1679   if (is_int16(rs.offset_)) {
1680     GenInstrImmediate(LBU, rs.rm(), rd, rs.offset_);
1681   } else {  // Offset > 16 bits, use multiple instructions to load.
1682     LoadRegPlusOffsetToAt(rs);
1683     GenInstrImmediate(LBU, at, rd, 0);  // Equiv to lbu(rd, MemOperand(at, 0));
1684   }
1685 }
1686
1687
1688 void Assembler::lh(Register rd, const MemOperand& rs) {
1689   if (is_int16(rs.offset_)) {
1690     GenInstrImmediate(LH, rs.rm(), rd, rs.offset_);
1691   } else {  // Offset > 16 bits, use multiple instructions to load.
1692     LoadRegPlusOffsetToAt(rs);
1693     GenInstrImmediate(LH, at, rd, 0);  // Equiv to lh(rd, MemOperand(at, 0));
1694   }
1695 }
1696
1697
1698 void Assembler::lhu(Register rd, const MemOperand& rs) {
1699   if (is_int16(rs.offset_)) {
1700     GenInstrImmediate(LHU, rs.rm(), rd, rs.offset_);
1701   } else {  // Offset > 16 bits, use multiple instructions to load.
1702     LoadRegPlusOffsetToAt(rs);
1703     GenInstrImmediate(LHU, at, rd, 0);  // Equiv to lhu(rd, MemOperand(at, 0));
1704   }
1705 }
1706
1707
1708 void Assembler::lw(Register rd, const MemOperand& rs) {
1709   if (is_int16(rs.offset_)) {
1710     GenInstrImmediate(LW, rs.rm(), rd, rs.offset_);
1711   } else {  // Offset > 16 bits, use multiple instructions to load.
1712     LoadRegPlusOffsetToAt(rs);
1713     GenInstrImmediate(LW, at, rd, 0);  // Equiv to lw(rd, MemOperand(at, 0));
1714   }
1715 }
1716
1717
1718 void Assembler::lwl(Register rd, const MemOperand& rs) {
1719   GenInstrImmediate(LWL, rs.rm(), rd, rs.offset_);
1720 }
1721
1722
1723 void Assembler::lwr(Register rd, const MemOperand& rs) {
1724   GenInstrImmediate(LWR, rs.rm(), rd, rs.offset_);
1725 }
1726
1727
1728 void Assembler::sb(Register rd, const MemOperand& rs) {
1729   if (is_int16(rs.offset_)) {
1730     GenInstrImmediate(SB, rs.rm(), rd, rs.offset_);
1731   } else {  // Offset > 16 bits, use multiple instructions to store.
1732     LoadRegPlusOffsetToAt(rs);
1733     GenInstrImmediate(SB, at, rd, 0);  // Equiv to sb(rd, MemOperand(at, 0));
1734   }
1735 }
1736
1737
1738 void Assembler::sh(Register rd, const MemOperand& rs) {
1739   if (is_int16(rs.offset_)) {
1740     GenInstrImmediate(SH, rs.rm(), rd, rs.offset_);
1741   } else {  // Offset > 16 bits, use multiple instructions to store.
1742     LoadRegPlusOffsetToAt(rs);
1743     GenInstrImmediate(SH, at, rd, 0);  // Equiv to sh(rd, MemOperand(at, 0));
1744   }
1745 }
1746
1747
1748 void Assembler::sw(Register rd, const MemOperand& rs) {
1749   if (is_int16(rs.offset_)) {
1750     GenInstrImmediate(SW, rs.rm(), rd, rs.offset_);
1751   } else {  // Offset > 16 bits, use multiple instructions to store.
1752     LoadRegPlusOffsetToAt(rs);
1753     GenInstrImmediate(SW, at, rd, 0);  // Equiv to sw(rd, MemOperand(at, 0));
1754   }
1755 }
1756
1757
1758 void Assembler::swl(Register rd, const MemOperand& rs) {
1759   GenInstrImmediate(SWL, rs.rm(), rd, rs.offset_);
1760 }
1761
1762
1763 void Assembler::swr(Register rd, const MemOperand& rs) {
1764   GenInstrImmediate(SWR, rs.rm(), rd, rs.offset_);
1765 }
1766
1767
1768 void Assembler::lui(Register rd, int32_t j) {
1769   DCHECK(is_uint16(j));
1770   GenInstrImmediate(LUI, zero_reg, rd, j);
1771 }
1772
1773
1774 void Assembler::aui(Register rs, Register rt, int32_t j) {
1775   // This instruction uses same opcode as 'lui'. The difference in encoding is
1776   // 'lui' has zero reg. for rs field.
1777   DCHECK(is_uint16(j));
1778   GenInstrImmediate(LUI, rs, rt, j);
1779 }
1780
1781
1782 // -------------Misc-instructions--------------
1783
1784 // Break / Trap instructions.
1785 void Assembler::break_(uint32_t code, bool break_as_stop) {
1786   DCHECK((code & ~0xfffff) == 0);
1787   // We need to invalidate breaks that could be stops as well because the
1788   // simulator expects a char pointer after the stop instruction.
1789   // See constants-mips.h for explanation.
1790   DCHECK((break_as_stop &&
1791           code <= kMaxStopCode &&
1792           code > kMaxWatchpointCode) ||
1793          (!break_as_stop &&
1794           (code > kMaxStopCode ||
1795            code <= kMaxWatchpointCode)));
1796   Instr break_instr = SPECIAL | BREAK | (code << 6);
1797   emit(break_instr);
1798 }
1799
1800
1801 void Assembler::stop(const char* msg, uint32_t code) {
1802   DCHECK(code > kMaxWatchpointCode);
1803   DCHECK(code <= kMaxStopCode);
1804 #if V8_HOST_ARCH_MIPS
1805   break_(0x54321);
1806 #else  // V8_HOST_ARCH_MIPS
1807   BlockTrampolinePoolFor(2);
1808   // The Simulator will handle the stop instruction and get the message address.
1809   // On MIPS stop() is just a special kind of break_().
1810   break_(code, true);
1811   emit(reinterpret_cast<Instr>(msg));
1812 #endif
1813 }
1814
1815
1816 void Assembler::tge(Register rs, Register rt, uint16_t code) {
1817   DCHECK(is_uint10(code));
1818   Instr instr = SPECIAL | TGE | rs.code() << kRsShift
1819       | rt.code() << kRtShift | code << 6;
1820   emit(instr);
1821 }
1822
1823
1824 void Assembler::tgeu(Register rs, Register rt, uint16_t code) {
1825   DCHECK(is_uint10(code));
1826   Instr instr = SPECIAL | TGEU | rs.code() << kRsShift
1827       | rt.code() << kRtShift | code << 6;
1828   emit(instr);
1829 }
1830
1831
1832 void Assembler::tlt(Register rs, Register rt, uint16_t code) {
1833   DCHECK(is_uint10(code));
1834   Instr instr =
1835       SPECIAL | TLT | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
1836   emit(instr);
1837 }
1838
1839
1840 void Assembler::tltu(Register rs, Register rt, uint16_t code) {
1841   DCHECK(is_uint10(code));
1842   Instr instr =
1843       SPECIAL | TLTU | rs.code() << kRsShift
1844       | rt.code() << kRtShift | code << 6;
1845   emit(instr);
1846 }
1847
1848
1849 void Assembler::teq(Register rs, Register rt, uint16_t code) {
1850   DCHECK(is_uint10(code));
1851   Instr instr =
1852       SPECIAL | TEQ | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
1853   emit(instr);
1854 }
1855
1856
1857 void Assembler::tne(Register rs, Register rt, uint16_t code) {
1858   DCHECK(is_uint10(code));
1859   Instr instr =
1860       SPECIAL | TNE | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
1861   emit(instr);
1862 }
1863
1864
1865 // Move from HI/LO register.
1866
1867 void Assembler::mfhi(Register rd) {
1868   GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFHI);
1869 }
1870
1871
1872 void Assembler::mflo(Register rd) {
1873   GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFLO);
1874 }
1875
1876
1877 // Set on less than instructions.
1878 void Assembler::slt(Register rd, Register rs, Register rt) {
1879   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLT);
1880 }
1881
1882
1883 void Assembler::sltu(Register rd, Register rs, Register rt) {
1884   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLTU);
1885 }
1886
1887
1888 void Assembler::slti(Register rt, Register rs, int32_t j) {
1889   GenInstrImmediate(SLTI, rs, rt, j);
1890 }
1891
1892
1893 void Assembler::sltiu(Register rt, Register rs, int32_t j) {
1894   GenInstrImmediate(SLTIU, rs, rt, j);
1895 }
1896
1897
1898 // Conditional move.
1899 void Assembler::movz(Register rd, Register rs, Register rt) {
1900   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVZ);
1901 }
1902
1903
1904 void Assembler::movn(Register rd, Register rs, Register rt) {
1905   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVN);
1906 }
1907
1908
1909 void Assembler::movt(Register rd, Register rs, uint16_t cc) {
1910   Register rt;
1911   rt.code_ = (cc & 0x0007) << 2 | 1;
1912   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
1913 }
1914
1915
1916 void Assembler::movf(Register rd, Register rs, uint16_t cc) {
1917   Register rt;
1918   rt.code_ = (cc & 0x0007) << 2 | 0;
1919   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
1920 }
1921
1922
1923 // Bit twiddling.
1924 void Assembler::clz(Register rd, Register rs) {
1925   if (!IsMipsArchVariant(kMips32r6)) {
1926     // Clz instr requires same GPR number in 'rd' and 'rt' fields.
1927     GenInstrRegister(SPECIAL2, rs, rd, rd, 0, CLZ);
1928   } else {
1929     GenInstrRegister(SPECIAL, rs, zero_reg, rd, 1, CLZ_R6);
1930   }
1931 }
1932
1933
1934 void Assembler::ins_(Register rt, Register rs, uint16_t pos, uint16_t size) {
1935   // Should be called via MacroAssembler::Ins.
1936   // Ins instr has 'rt' field as dest, and two uint5: msb, lsb.
1937   DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
1938   GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, INS);
1939 }
1940
1941
1942 void Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
1943   // Should be called via MacroAssembler::Ext.
1944   // Ext instr has 'rt' field as dest, and two uint5: msb, lsb.
1945   DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
1946   GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT);
1947 }
1948
1949
1950 void Assembler::pref(int32_t hint, const MemOperand& rs) {
1951   DCHECK(!IsMipsArchVariant(kLoongson));
1952   DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
1953   Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
1954       | (rs.offset_);
1955   emit(instr);
1956 }
1957
1958
1959 // --------Coprocessor-instructions----------------
1960
1961 // Load, store, move.
1962 void Assembler::lwc1(FPURegister fd, const MemOperand& src) {
1963   GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
1964 }
1965
1966
1967 void Assembler::ldc1(FPURegister fd, const MemOperand& src) {
1968   // Workaround for non-8-byte alignment of HeapNumber, convert 64-bit
1969   // load to two 32-bit loads.
1970   if (IsFp64Mode()) {
1971     GenInstrImmediate(LWC1, src.rm(), fd, src.offset_ +
1972         Register::kMantissaOffset);
1973     GenInstrImmediate(LW, src.rm(), at, src.offset_ +
1974         Register::kExponentOffset);
1975     mthc1(at, fd);
1976   } else {
1977     GenInstrImmediate(LWC1, src.rm(), fd, src.offset_ +
1978         Register::kMantissaOffset);
1979     FPURegister nextfpreg;
1980     nextfpreg.setcode(fd.code() + 1);
1981     GenInstrImmediate(LWC1, src.rm(), nextfpreg, src.offset_ +
1982         Register::kExponentOffset);
1983   }
1984 }
1985
1986
1987 void Assembler::swc1(FPURegister fd, const MemOperand& src) {
1988   GenInstrImmediate(SWC1, src.rm(), fd, src.offset_);
1989 }
1990
1991
1992 void Assembler::sdc1(FPURegister fd, const MemOperand& src) {
1993   // Workaround for non-8-byte alignment of HeapNumber, convert 64-bit
1994   // store to two 32-bit stores.
1995   if (IsFp64Mode()) {
1996     GenInstrImmediate(SWC1, src.rm(), fd, src.offset_ +
1997         Register::kMantissaOffset);
1998     mfhc1(at, fd);
1999     GenInstrImmediate(SW, src.rm(), at, src.offset_ +
2000         Register::kExponentOffset);
2001   } else {
2002     GenInstrImmediate(SWC1, src.rm(), fd, src.offset_ +
2003         Register::kMantissaOffset);
2004     FPURegister nextfpreg;
2005     nextfpreg.setcode(fd.code() + 1);
2006     GenInstrImmediate(SWC1, src.rm(), nextfpreg, src.offset_ +
2007         Register::kExponentOffset);
2008   }
2009 }
2010
2011
2012 void Assembler::mtc1(Register rt, FPURegister fs) {
2013   GenInstrRegister(COP1, MTC1, rt, fs, f0);
2014 }
2015
2016
2017 void Assembler::mthc1(Register rt, FPURegister fs) {
2018   GenInstrRegister(COP1, MTHC1, rt, fs, f0);
2019 }
2020
2021
2022 void Assembler::mfc1(Register rt, FPURegister fs) {
2023   GenInstrRegister(COP1, MFC1, rt, fs, f0);
2024 }
2025
2026
2027 void Assembler::mfhc1(Register rt, FPURegister fs) {
2028   GenInstrRegister(COP1, MFHC1, rt, fs, f0);
2029 }
2030
2031
2032 void Assembler::ctc1(Register rt, FPUControlRegister fs) {
2033   GenInstrRegister(COP1, CTC1, rt, fs);
2034 }
2035
2036
2037 void Assembler::cfc1(Register rt, FPUControlRegister fs) {
2038   GenInstrRegister(COP1, CFC1, rt, fs);
2039 }
2040
2041
2042 void Assembler::DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
2043   uint64_t i;
2044   memcpy(&i, &d, 8);
2045
2046   *lo = i & 0xffffffff;
2047   *hi = i >> 32;
2048 }
2049
2050
2051 // Arithmetic.
2052
2053 void Assembler::add_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2054   GenInstrRegister(COP1, D, ft, fs, fd, ADD_D);
2055 }
2056
2057
2058 void Assembler::sub_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2059   GenInstrRegister(COP1, D, ft, fs, fd, SUB_D);
2060 }
2061
2062
2063 void Assembler::mul_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2064   GenInstrRegister(COP1, D, ft, fs, fd, MUL_D);
2065 }
2066
2067
2068 void Assembler::madd_d(FPURegister fd, FPURegister fr, FPURegister fs,
2069     FPURegister ft) {
2070   DCHECK(IsMipsArchVariant(kMips32r2));
2071   GenInstrRegister(COP1X, fr, ft, fs, fd, MADD_D);
2072 }
2073
2074
2075 void Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2076   GenInstrRegister(COP1, D, ft, fs, fd, DIV_D);
2077 }
2078
2079
2080 void Assembler::abs_d(FPURegister fd, FPURegister fs) {
2081   GenInstrRegister(COP1, D, f0, fs, fd, ABS_D);
2082 }
2083
2084
2085 void Assembler::mov_d(FPURegister fd, FPURegister fs) {
2086   GenInstrRegister(COP1, D, f0, fs, fd, MOV_D);
2087 }
2088
2089
2090 void Assembler::neg_d(FPURegister fd, FPURegister fs) {
2091   GenInstrRegister(COP1, D, f0, fs, fd, NEG_D);
2092 }
2093
2094
2095 void Assembler::sqrt_d(FPURegister fd, FPURegister fs) {
2096   GenInstrRegister(COP1, D, f0, fs, fd, SQRT_D);
2097 }
2098
2099
2100 // Conversions.
2101
2102 void Assembler::cvt_w_s(FPURegister fd, FPURegister fs) {
2103   GenInstrRegister(COP1, S, f0, fs, fd, CVT_W_S);
2104 }
2105
2106
2107 void Assembler::cvt_w_d(FPURegister fd, FPURegister fs) {
2108   GenInstrRegister(COP1, D, f0, fs, fd, CVT_W_D);
2109 }
2110
2111
2112 void Assembler::trunc_w_s(FPURegister fd, FPURegister fs) {
2113   GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_W_S);
2114 }
2115
2116
2117 void Assembler::trunc_w_d(FPURegister fd, FPURegister fs) {
2118   GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_W_D);
2119 }
2120
2121
2122 void Assembler::round_w_s(FPURegister fd, FPURegister fs) {
2123   GenInstrRegister(COP1, S, f0, fs, fd, ROUND_W_S);
2124 }
2125
2126
2127 void Assembler::round_w_d(FPURegister fd, FPURegister fs) {
2128   GenInstrRegister(COP1, D, f0, fs, fd, ROUND_W_D);
2129 }
2130
2131
2132 void Assembler::floor_w_s(FPURegister fd, FPURegister fs) {
2133   GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_W_S);
2134 }
2135
2136
2137 void Assembler::floor_w_d(FPURegister fd, FPURegister fs) {
2138   GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_W_D);
2139 }
2140
2141
2142 void Assembler::ceil_w_s(FPURegister fd, FPURegister fs) {
2143   GenInstrRegister(COP1, S, f0, fs, fd, CEIL_W_S);
2144 }
2145
2146
2147 void Assembler::ceil_w_d(FPURegister fd, FPURegister fs) {
2148   GenInstrRegister(COP1, D, f0, fs, fd, CEIL_W_D);
2149 }
2150
2151
2152 void Assembler::cvt_l_s(FPURegister fd, FPURegister fs) {
2153   DCHECK(IsMipsArchVariant(kMips32r2));
2154   GenInstrRegister(COP1, S, f0, fs, fd, CVT_L_S);
2155 }
2156
2157
2158 void Assembler::cvt_l_d(FPURegister fd, FPURegister fs) {
2159   DCHECK(IsMipsArchVariant(kMips32r2));
2160   GenInstrRegister(COP1, D, f0, fs, fd, CVT_L_D);
2161 }
2162
2163
2164 void Assembler::trunc_l_s(FPURegister fd, FPURegister fs) {
2165   DCHECK(IsMipsArchVariant(kMips32r2));
2166   GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_L_S);
2167 }
2168
2169
2170 void Assembler::trunc_l_d(FPURegister fd, FPURegister fs) {
2171   DCHECK(IsMipsArchVariant(kMips32r2));
2172   GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_L_D);
2173 }
2174
2175
2176 void Assembler::round_l_s(FPURegister fd, FPURegister fs) {
2177   GenInstrRegister(COP1, S, f0, fs, fd, ROUND_L_S);
2178 }
2179
2180
2181 void Assembler::round_l_d(FPURegister fd, FPURegister fs) {
2182   GenInstrRegister(COP1, D, f0, fs, fd, ROUND_L_D);
2183 }
2184
2185
2186 void Assembler::floor_l_s(FPURegister fd, FPURegister fs) {
2187   GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_L_S);
2188 }
2189
2190
2191 void Assembler::floor_l_d(FPURegister fd, FPURegister fs) {
2192   GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_L_D);
2193 }
2194
2195
2196 void Assembler::ceil_l_s(FPURegister fd, FPURegister fs) {
2197   GenInstrRegister(COP1, S, f0, fs, fd, CEIL_L_S);
2198 }
2199
2200
2201 void Assembler::ceil_l_d(FPURegister fd, FPURegister fs) {
2202   GenInstrRegister(COP1, D, f0, fs, fd, CEIL_L_D);
2203 }
2204
2205
2206 void Assembler::min(SecondaryField fmt, FPURegister fd, FPURegister ft,
2207     FPURegister fs) {
2208   DCHECK(IsMipsArchVariant(kMips32r6));
2209   DCHECK((fmt == D) || (fmt == S));
2210   GenInstrRegister(COP1, fmt, ft, fs, fd, MIN);
2211 }
2212
2213
2214 void Assembler::mina(SecondaryField fmt, FPURegister fd, FPURegister ft,
2215     FPURegister fs) {
2216   DCHECK(IsMipsArchVariant(kMips32r6));
2217   DCHECK((fmt == D) || (fmt == S));
2218   GenInstrRegister(COP1, fmt, ft, fs, fd, MINA);
2219 }
2220
2221
2222 void Assembler::max(SecondaryField fmt, FPURegister fd, FPURegister ft,
2223     FPURegister fs) {
2224   DCHECK(IsMipsArchVariant(kMips32r6));
2225   DCHECK((fmt == D) || (fmt == S));
2226   GenInstrRegister(COP1, fmt, ft, fs, fd, MAX);
2227 }
2228
2229
2230 void Assembler::maxa(SecondaryField fmt, FPURegister fd, FPURegister ft,
2231     FPURegister fs) {
2232   DCHECK(IsMipsArchVariant(kMips32r6));
2233   DCHECK((fmt == D) || (fmt == S));
2234   GenInstrRegister(COP1, fmt, ft, fs, fd, MAXA);
2235 }
2236
2237
2238 void Assembler::cvt_s_w(FPURegister fd, FPURegister fs) {
2239   GenInstrRegister(COP1, W, f0, fs, fd, CVT_S_W);
2240 }
2241
2242
2243 void Assembler::cvt_s_l(FPURegister fd, FPURegister fs) {
2244   DCHECK(IsMipsArchVariant(kMips32r2));
2245   GenInstrRegister(COP1, L, f0, fs, fd, CVT_S_L);
2246 }
2247
2248
2249 void Assembler::cvt_s_d(FPURegister fd, FPURegister fs) {
2250   GenInstrRegister(COP1, D, f0, fs, fd, CVT_S_D);
2251 }
2252
2253
2254 void Assembler::cvt_d_w(FPURegister fd, FPURegister fs) {
2255   GenInstrRegister(COP1, W, f0, fs, fd, CVT_D_W);
2256 }
2257
2258
2259 void Assembler::cvt_d_l(FPURegister fd, FPURegister fs) {
2260   DCHECK(IsMipsArchVariant(kMips32r2));
2261   GenInstrRegister(COP1, L, f0, fs, fd, CVT_D_L);
2262 }
2263
2264
2265 void Assembler::cvt_d_s(FPURegister fd, FPURegister fs) {
2266   GenInstrRegister(COP1, S, f0, fs, fd, CVT_D_S);
2267 }
2268
2269
2270 // Conditions for >= MIPSr6.
2271 void Assembler::cmp(FPUCondition cond, SecondaryField fmt,
2272     FPURegister fd, FPURegister fs, FPURegister ft) {
2273   DCHECK(IsMipsArchVariant(kMips32r6));
2274   DCHECK((fmt & ~(31 << kRsShift)) == 0);
2275   Instr instr = COP1 | fmt | ft.code() << kFtShift |
2276       fs.code() << kFsShift | fd.code() << kFdShift | (0 << 5) | cond;
2277   emit(instr);
2278 }
2279
2280
2281 void Assembler::bc1eqz(int16_t offset, FPURegister ft) {
2282   DCHECK(IsMipsArchVariant(kMips32r6));
2283   Instr instr = COP1 | BC1EQZ | ft.code() << kFtShift | (offset & kImm16Mask);
2284   emit(instr);
2285 }
2286
2287
2288 void Assembler::bc1nez(int16_t offset, FPURegister ft) {
2289   DCHECK(IsMipsArchVariant(kMips32r6));
2290   Instr instr = COP1 | BC1NEZ | ft.code() << kFtShift | (offset & kImm16Mask);
2291   emit(instr);
2292 }
2293
2294
2295 // Conditions for < MIPSr6.
2296 void Assembler::c(FPUCondition cond, SecondaryField fmt,
2297     FPURegister fs, FPURegister ft, uint16_t cc) {
2298   DCHECK(is_uint3(cc));
2299   DCHECK((fmt & ~(31 << kRsShift)) == 0);
2300   Instr instr = COP1 | fmt | ft.code() << 16 | fs.code() << kFsShift
2301       | cc << 8 | 3 << 4 | cond;
2302   emit(instr);
2303 }
2304
2305
2306 void Assembler::fcmp(FPURegister src1, const double src2,
2307       FPUCondition cond) {
2308   DCHECK(src2 == 0.0);
2309   mtc1(zero_reg, f14);
2310   cvt_d_w(f14, f14);
2311   c(cond, D, src1, f14, 0);
2312 }
2313
2314
2315 void Assembler::bc1f(int16_t offset, uint16_t cc) {
2316   DCHECK(is_uint3(cc));
2317   Instr instr = COP1 | BC1 | cc << 18 | 0 << 16 | (offset & kImm16Mask);
2318   emit(instr);
2319 }
2320
2321
2322 void Assembler::bc1t(int16_t offset, uint16_t cc) {
2323   DCHECK(is_uint3(cc));
2324   Instr instr = COP1 | BC1 | cc << 18 | 1 << 16 | (offset & kImm16Mask);
2325   emit(instr);
2326 }
2327
2328
2329 // Debugging.
2330 int Assembler::RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
2331                                          intptr_t pc_delta) {
2332   Instr instr = instr_at(pc);
2333
2334   if (RelocInfo::IsInternalReference(rmode)) {
2335     int32_t* p = reinterpret_cast<int32_t*>(pc);
2336     if (*p == 0) {
2337       return 0;  // Number of instructions patched.
2338     }
2339     *p += pc_delta;
2340     return 1;  // Number of instructions patched.
2341   } else {
2342     DCHECK(RelocInfo::IsInternalReferenceEncoded(rmode));
2343     if (IsLui(instr)) {
2344       Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
2345       Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
2346       DCHECK(IsOri(instr_ori));
2347       int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift;
2348       imm |= (instr_ori & static_cast<int32_t>(kImm16Mask));
2349       if (imm == kEndOfJumpChain) {
2350         return 0;  // Number of instructions patched.
2351       }
2352       imm += pc_delta;
2353       DCHECK((imm & 3) == 0);
2354
2355       instr_lui &= ~kImm16Mask;
2356       instr_ori &= ~kImm16Mask;
2357
2358       instr_at_put(pc + 0 * Assembler::kInstrSize,
2359                    instr_lui | ((imm >> kLuiShift) & kImm16Mask));
2360       instr_at_put(pc + 1 * Assembler::kInstrSize,
2361                    instr_ori | (imm & kImm16Mask));
2362       return 2;  // Number of instructions patched.
2363     } else if (IsJ(instr)) {
2364       uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
2365       if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
2366         return 0;  // Number of instructions patched.
2367       }
2368       imm28 += pc_delta;
2369       imm28 &= kImm28Mask;
2370       DCHECK((imm28 & 3) == 0);
2371
2372       instr &= ~kImm26Mask;
2373       uint32_t imm26 = imm28 >> 2;
2374       DCHECK(is_uint26(imm26));
2375
2376       instr_at_put(pc, instr | (imm26 & kImm26Mask));
2377       return 1;  // Number of instructions patched.
2378     } else {
2379       UNREACHABLE();
2380       return 0;
2381     }
2382   }
2383 }
2384
2385
2386 void Assembler::GrowBuffer() {
2387   if (!own_buffer_) FATAL("external code buffer is too small");
2388
2389   // Compute new buffer size.
2390   CodeDesc desc;  // The new buffer.
2391   if (buffer_size_ < 1 * MB) {
2392     desc.buffer_size = 2*buffer_size_;
2393   } else {
2394     desc.buffer_size = buffer_size_ + 1*MB;
2395   }
2396   CHECK_GT(desc.buffer_size, 0);  // No overflow.
2397
2398   // Set up new buffer.
2399   desc.buffer = NewArray<byte>(desc.buffer_size);
2400
2401   desc.instr_size = pc_offset();
2402   desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
2403
2404   // Copy the data.
2405   int pc_delta = desc.buffer - buffer_;
2406   int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
2407   MemMove(desc.buffer, buffer_, desc.instr_size);
2408   MemMove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(),
2409           desc.reloc_size);
2410
2411   // Switch buffers.
2412   DeleteArray(buffer_);
2413   buffer_ = desc.buffer;
2414   buffer_size_ = desc.buffer_size;
2415   pc_ += pc_delta;
2416   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2417                                reloc_info_writer.last_pc() + pc_delta);
2418
2419   // Relocate runtime entries.
2420   for (RelocIterator it(desc); !it.done(); it.next()) {
2421     RelocInfo::Mode rmode = it.rinfo()->rmode();
2422     if (rmode == RelocInfo::INTERNAL_REFERENCE_ENCODED ||
2423         rmode == RelocInfo::INTERNAL_REFERENCE) {
2424       byte* p = reinterpret_cast<byte*>(it.rinfo()->pc());
2425       RelocateInternalReference(rmode, p, pc_delta);
2426     }
2427   }
2428   DCHECK(!overflow());
2429 }
2430
2431
2432 void Assembler::db(uint8_t data) {
2433   CheckBuffer();
2434   *reinterpret_cast<uint8_t*>(pc_) = data;
2435   pc_ += sizeof(uint8_t);
2436 }
2437
2438
2439 void Assembler::dd(uint32_t data) {
2440   CheckBuffer();
2441   *reinterpret_cast<uint32_t*>(pc_) = data;
2442   pc_ += sizeof(uint32_t);
2443 }
2444
2445
2446 void Assembler::dd(Label* label) {
2447   CheckBuffer();
2448   RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
2449   if (label->is_bound()) {
2450     uint32_t data = reinterpret_cast<uint32_t>(buffer_ + label->pos());
2451     *reinterpret_cast<uint32_t*>(pc_) = data;
2452     pc_ += sizeof(uint32_t);
2453   } else {
2454     uint32_t target_pos = jump_address(label);
2455     emit(target_pos);
2456     internal_reference_positions_.insert(label->pos());
2457   }
2458 }
2459
2460
2461 void Assembler::emit_code_stub_address(Code* stub) {
2462   CheckBuffer();
2463   *reinterpret_cast<uint32_t*>(pc_) =
2464       reinterpret_cast<uint32_t>(stub->instruction_start());
2465   pc_ += sizeof(uint32_t);
2466 }
2467
2468
2469 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2470   // We do not try to reuse pool constants.
2471   RelocInfo rinfo(pc_, rmode, data, NULL);
2472   if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::DEBUG_BREAK_SLOT) {
2473     // Adjust code for new modes.
2474     DCHECK(RelocInfo::IsDebugBreakSlot(rmode)
2475            || RelocInfo::IsJSReturn(rmode)
2476            || RelocInfo::IsComment(rmode)
2477            || RelocInfo::IsPosition(rmode));
2478     // These modes do not need an entry in the constant pool.
2479   }
2480   if (!RelocInfo::IsNone(rinfo.rmode())) {
2481     // Don't record external references unless the heap will be serialized.
2482     if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
2483         !serializer_enabled() && !emit_debug_code()) {
2484       return;
2485     }
2486     DCHECK(buffer_space() >= kMaxRelocSize);  // Too late to grow buffer here.
2487     if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
2488       RelocInfo reloc_info_with_ast_id(pc_,
2489                                        rmode,
2490                                        RecordedAstId().ToInt(),
2491                                        NULL);
2492       ClearRecordedAstId();
2493       reloc_info_writer.Write(&reloc_info_with_ast_id);
2494     } else {
2495       reloc_info_writer.Write(&rinfo);
2496     }
2497   }
2498 }
2499
2500
2501 void Assembler::BlockTrampolinePoolFor(int instructions) {
2502   BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize);
2503 }
2504
2505
2506 void Assembler::CheckTrampolinePool() {
2507   // Some small sequences of instructions must not be broken up by the
2508   // insertion of a trampoline pool; such sequences are protected by setting
2509   // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_,
2510   // which are both checked here. Also, recursive calls to CheckTrampolinePool
2511   // are blocked by trampoline_pool_blocked_nesting_.
2512   if ((trampoline_pool_blocked_nesting_ > 0) ||
2513       (pc_offset() < no_trampoline_pool_before_)) {
2514     // Emission is currently blocked; make sure we try again as soon as
2515     // possible.
2516     if (trampoline_pool_blocked_nesting_ > 0) {
2517       next_buffer_check_ = pc_offset() + kInstrSize;
2518     } else {
2519       next_buffer_check_ = no_trampoline_pool_before_;
2520     }
2521     return;
2522   }
2523
2524   DCHECK(!trampoline_emitted_);
2525   DCHECK(unbound_labels_count_ >= 0);
2526   if (unbound_labels_count_ > 0) {
2527     // First we emit jump (2 instructions), then we emit trampoline pool.
2528     { BlockTrampolinePoolScope block_trampoline_pool(this);
2529       Label after_pool;
2530       b(&after_pool);
2531       nop();
2532
2533       int pool_start = pc_offset();
2534       for (int i = 0; i < unbound_labels_count_; i++) {
2535         uint32_t imm32;
2536         imm32 = jump_address(&after_pool);
2537         { BlockGrowBufferScope block_buf_growth(this);
2538           // Buffer growth (and relocation) must be blocked for internal
2539           // references until associated instructions are emitted and available
2540           // to be patched.
2541           RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
2542           lui(at, (imm32 & kHiMask) >> kLuiShift);
2543           ori(at, at, (imm32 & kImm16Mask));
2544         }
2545         jr(at);
2546         nop();
2547       }
2548       bind(&after_pool);
2549       trampoline_ = Trampoline(pool_start, unbound_labels_count_);
2550
2551       trampoline_emitted_ = true;
2552       // As we are only going to emit trampoline once, we need to prevent any
2553       // further emission.
2554       next_buffer_check_ = kMaxInt;
2555     }
2556   } else {
2557     // Number of branches to unbound label at this point is zero, so we can
2558     // move next buffer check to maximum.
2559     next_buffer_check_ = pc_offset() +
2560         kMaxBranchOffset - kTrampolineSlotsSize * 16;
2561   }
2562   return;
2563 }
2564
2565
2566 Address Assembler::target_address_at(Address pc) {
2567   Instr instr1 = instr_at(pc);
2568   Instr instr2 = instr_at(pc + kInstrSize);
2569   // Interpret 2 instructions generated by li: lui/ori
2570   if ((GetOpcodeField(instr1) == LUI) && (GetOpcodeField(instr2) == ORI)) {
2571     // Assemble the 32 bit value.
2572     return reinterpret_cast<Address>(
2573         (GetImmediate16(instr1) << 16) | GetImmediate16(instr2));
2574   }
2575
2576   // We should never get here, force a bad address if we do.
2577   UNREACHABLE();
2578   return (Address)0x0;
2579 }
2580
2581
2582 // MIPS and ia32 use opposite encoding for qNaN and sNaN, such that ia32
2583 // qNaN is a MIPS sNaN, and ia32 sNaN is MIPS qNaN. If running from a heap
2584 // snapshot generated on ia32, the resulting MIPS sNaN must be quieted.
2585 // OS::nan_value() returns a qNaN.
2586 void Assembler::QuietNaN(HeapObject* object) {
2587   HeapNumber::cast(object)->set_value(std::numeric_limits<double>::quiet_NaN());
2588 }
2589
2590
2591 // On Mips, a target address is stored in a lui/ori instruction pair, each
2592 // of which load 16 bits of the 32-bit address to a register.
2593 // Patching the address must replace both instr, and flush the i-cache.
2594 //
2595 // There is an optimization below, which emits a nop when the address
2596 // fits in just 16 bits. This is unlikely to help, and should be benchmarked,
2597 // and possibly removed.
2598 void Assembler::set_target_address_at(Address pc,
2599                                       Address target,
2600                                       ICacheFlushMode icache_flush_mode) {
2601   Instr instr2 = instr_at(pc + kInstrSize);
2602   uint32_t rt_code = GetRtField(instr2);
2603   uint32_t* p = reinterpret_cast<uint32_t*>(pc);
2604   uint32_t itarget = reinterpret_cast<uint32_t>(target);
2605
2606 #ifdef DEBUG
2607   // Check we have the result from a li macro-instruction, using instr pair.
2608   Instr instr1 = instr_at(pc);
2609   CHECK((GetOpcodeField(instr1) == LUI && GetOpcodeField(instr2) == ORI));
2610 #endif
2611
2612   // Must use 2 instructions to insure patchable code => just use lui and ori.
2613   // lui rt, upper-16.
2614   // ori rt rt, lower-16.
2615   *p = LUI | rt_code | ((itarget & kHiMask) >> kLuiShift);
2616   *(p + 1) = ORI | rt_code | (rt_code << 5) | (itarget & kImm16Mask);
2617
2618   // The following code is an optimization for the common case of Call()
2619   // or Jump() which is load to register, and jump through register:
2620   //     li(t9, address); jalr(t9)    (or jr(t9)).
2621   // If the destination address is in the same 256 MB page as the call, it
2622   // is faster to do a direct jal, or j, rather than jump thru register, since
2623   // that lets the cpu pipeline prefetch the target address. However each
2624   // time the address above is patched, we have to patch the direct jal/j
2625   // instruction, as well as possibly revert to jalr/jr if we now cross a
2626   // 256 MB page. Note that with the jal/j instructions, we do not need to
2627   // load the register, but that code is left, since it makes it easy to
2628   // revert this process. A further optimization could try replacing the
2629   // li sequence with nops.
2630   // This optimization can only be applied if the rt-code from instr2 is the
2631   // register used for the jalr/jr. Finally, we have to skip 'jr ra', which is
2632   // mips return. Occasionally this lands after an li().
2633
2634   Instr instr3 = instr_at(pc + 2 * kInstrSize);
2635   uint32_t ipc = reinterpret_cast<uint32_t>(pc + 3 * kInstrSize);
2636   bool in_range = ((ipc ^ itarget) >> (kImm26Bits + kImmFieldShift)) == 0;
2637   uint32_t target_field =
2638       static_cast<uint32_t>(itarget & kJumpAddrMask) >> kImmFieldShift;
2639   bool patched_jump = false;
2640
2641 #ifndef ALLOW_JAL_IN_BOUNDARY_REGION
2642   // This is a workaround to the 24k core E156 bug (affect some 34k cores also).
2643   // Since the excluded space is only 64KB out of 256MB (0.02 %), we will just
2644   // apply this workaround for all cores so we don't have to identify the core.
2645   if (in_range) {
2646     // The 24k core E156 bug has some very specific requirements, we only check
2647     // the most simple one: if the address of the delay slot instruction is in
2648     // the first or last 32 KB of the 256 MB segment.
2649     uint32_t segment_mask = ((256 * MB) - 1) ^ ((32 * KB) - 1);
2650     uint32_t ipc_segment_addr = ipc & segment_mask;
2651     if (ipc_segment_addr == 0 || ipc_segment_addr == segment_mask)
2652       in_range = false;
2653   }
2654 #endif
2655
2656   if (IsJalr(instr3)) {
2657     // Try to convert JALR to JAL.
2658     if (in_range && GetRt(instr2) == GetRs(instr3)) {
2659       *(p + 2) = JAL | target_field;
2660       patched_jump = true;
2661     }
2662   } else if (IsJr(instr3)) {
2663     // Try to convert JR to J, skip returns (jr ra).
2664     bool is_ret = static_cast<int>(GetRs(instr3)) == ra.code();
2665     if (in_range && !is_ret && GetRt(instr2) == GetRs(instr3)) {
2666       *(p + 2) = J | target_field;
2667       patched_jump = true;
2668     }
2669   } else if (IsJal(instr3)) {
2670     if (in_range) {
2671       // We are patching an already converted JAL.
2672       *(p + 2) = JAL | target_field;
2673     } else {
2674       // Patch JAL, but out of range, revert to JALR.
2675       // JALR rs reg is the rt reg specified in the ORI instruction.
2676       uint32_t rs_field = GetRt(instr2) << kRsShift;
2677       uint32_t rd_field = ra.code() << kRdShift;  // Return-address (ra) reg.
2678       *(p+2) = SPECIAL | rs_field | rd_field | JALR;
2679     }
2680     patched_jump = true;
2681   } else if (IsJ(instr3)) {
2682     if (in_range) {
2683       // We are patching an already converted J (jump).
2684       *(p + 2) = J | target_field;
2685     } else {
2686       // Trying patch J, but out of range, just go back to JR.
2687       // JR 'rs' reg is the 'rt' reg specified in the ORI instruction (instr2).
2688       uint32_t rs_field = GetRt(instr2) << kRsShift;
2689       if (IsMipsArchVariant(kMips32r6)) {
2690         *(p + 2) = SPECIAL | rs_field | (zero_reg.code() << kRdShift) | JALR;
2691       } else {
2692         *(p + 2) = SPECIAL | rs_field | JR;
2693       }
2694     }
2695     patched_jump = true;
2696   }
2697
2698   if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
2699     CpuFeatures::FlushICache(pc, (patched_jump ? 3 : 2) * sizeof(int32_t));
2700   }
2701 }
2702
2703
2704 void Assembler::JumpLabelToJumpRegister(Address pc) {
2705   // Address pc points to lui/ori instructions.
2706   // Jump to label may follow at pc + 2 * kInstrSize.
2707   uint32_t* p = reinterpret_cast<uint32_t*>(pc);
2708 #ifdef DEBUG
2709   Instr instr1 = instr_at(pc);
2710 #endif
2711   Instr instr2 = instr_at(pc + 1 * kInstrSize);
2712   Instr instr3 = instr_at(pc + 2 * kInstrSize);
2713   bool patched = false;
2714
2715   if (IsJal(instr3)) {
2716     DCHECK(GetOpcodeField(instr1) == LUI);
2717     DCHECK(GetOpcodeField(instr2) == ORI);
2718
2719     uint32_t rs_field = GetRt(instr2) << kRsShift;
2720     uint32_t rd_field = ra.code() << kRdShift;  // Return-address (ra) reg.
2721     *(p + 2) = SPECIAL | rs_field | rd_field | JALR;
2722     patched = true;
2723   } else if (IsJ(instr3)) {
2724     DCHECK(GetOpcodeField(instr1) == LUI);
2725     DCHECK(GetOpcodeField(instr2) == ORI);
2726
2727     uint32_t rs_field = GetRt(instr2) << kRsShift;
2728     if (IsMipsArchVariant(kMips32r6)) {
2729       *(p + 2) = SPECIAL | rs_field | (zero_reg.code() << kRdShift) | JALR;
2730     } else {
2731       *(p + 2) = SPECIAL | rs_field | JR;
2732     }
2733     patched = true;
2734   }
2735
2736   if (patched) {
2737     CpuFeatures::FlushICache(pc + 2, sizeof(Address));
2738   }
2739 }
2740
2741
2742 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
2743   // No out-of-line constant pool support.
2744   DCHECK(!FLAG_enable_ool_constant_pool);
2745   return isolate->factory()->empty_constant_pool_array();
2746 }
2747
2748
2749 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
2750   // No out-of-line constant pool support.
2751   DCHECK(!FLAG_enable_ool_constant_pool);
2752   return;
2753 }
2754
2755
2756 } }  // namespace v8::internal
2757
2758 #endif  // V8_TARGET_ARCH_MIPS