Correctify instanceof and make it optimizable.
[platform/upstream/v8.git] / src / mips64 / macro-assembler-mips64.cc
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <limits.h>  // For LONG_MIN, LONG_MAX.
6
7 #if V8_TARGET_ARCH_MIPS64
8
9 #include "src/base/division-by-constant.h"
10 #include "src/bootstrapper.h"
11 #include "src/codegen.h"
12 #include "src/cpu-profiler.h"
13 #include "src/debug/debug.h"
14 #include "src/runtime/runtime.h"
15
16 namespace v8 {
17 namespace internal {
18
19 MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size)
20     : Assembler(arg_isolate, buffer, size),
21       generating_stub_(false),
22       has_frame_(false),
23       has_double_zero_reg_set_(false) {
24   if (isolate() != NULL) {
25     code_object_ = Handle<Object>(isolate()->heap()->undefined_value(),
26                                   isolate());
27   }
28 }
29
30
31 void MacroAssembler::Load(Register dst,
32                           const MemOperand& src,
33                           Representation r) {
34   DCHECK(!r.IsDouble());
35   if (r.IsInteger8()) {
36     lb(dst, src);
37   } else if (r.IsUInteger8()) {
38     lbu(dst, src);
39   } else if (r.IsInteger16()) {
40     lh(dst, src);
41   } else if (r.IsUInteger16()) {
42     lhu(dst, src);
43   } else if (r.IsInteger32()) {
44     lw(dst, src);
45   } else {
46     ld(dst, src);
47   }
48 }
49
50
51 void MacroAssembler::Store(Register src,
52                            const MemOperand& dst,
53                            Representation r) {
54   DCHECK(!r.IsDouble());
55   if (r.IsInteger8() || r.IsUInteger8()) {
56     sb(src, dst);
57   } else if (r.IsInteger16() || r.IsUInteger16()) {
58     sh(src, dst);
59   } else if (r.IsInteger32()) {
60     sw(src, dst);
61   } else {
62     if (r.IsHeapObject()) {
63       AssertNotSmi(src);
64     } else if (r.IsSmi()) {
65       AssertSmi(src);
66     }
67     sd(src, dst);
68   }
69 }
70
71
72 void MacroAssembler::LoadRoot(Register destination,
73                               Heap::RootListIndex index) {
74   ld(destination, MemOperand(s6, index << kPointerSizeLog2));
75 }
76
77
78 void MacroAssembler::LoadRoot(Register destination,
79                               Heap::RootListIndex index,
80                               Condition cond,
81                               Register src1, const Operand& src2) {
82   Branch(2, NegateCondition(cond), src1, src2);
83   ld(destination, MemOperand(s6, index << kPointerSizeLog2));
84 }
85
86
87 void MacroAssembler::StoreRoot(Register source,
88                                Heap::RootListIndex index) {
89   DCHECK(Heap::RootCanBeWrittenAfterInitialization(index));
90   sd(source, MemOperand(s6, index << kPointerSizeLog2));
91 }
92
93
94 void MacroAssembler::StoreRoot(Register source,
95                                Heap::RootListIndex index,
96                                Condition cond,
97                                Register src1, const Operand& src2) {
98   DCHECK(Heap::RootCanBeWrittenAfterInitialization(index));
99   Branch(2, NegateCondition(cond), src1, src2);
100   sd(source, MemOperand(s6, index << kPointerSizeLog2));
101 }
102
103
104 // Push and pop all registers that can hold pointers.
105 void MacroAssembler::PushSafepointRegisters() {
106   // Safepoints expect a block of kNumSafepointRegisters values on the
107   // stack, so adjust the stack for unsaved registers.
108   const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters;
109   DCHECK(num_unsaved >= 0);
110   if (num_unsaved > 0) {
111     Dsubu(sp, sp, Operand(num_unsaved * kPointerSize));
112   }
113   MultiPush(kSafepointSavedRegisters);
114 }
115
116
117 void MacroAssembler::PopSafepointRegisters() {
118   const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters;
119   MultiPop(kSafepointSavedRegisters);
120   if (num_unsaved > 0) {
121     Daddu(sp, sp, Operand(num_unsaved * kPointerSize));
122   }
123 }
124
125
126 void MacroAssembler::StoreToSafepointRegisterSlot(Register src, Register dst) {
127   sd(src, SafepointRegisterSlot(dst));
128 }
129
130
131 void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) {
132   ld(dst, SafepointRegisterSlot(src));
133 }
134
135
136 int MacroAssembler::SafepointRegisterStackIndex(int reg_code) {
137   // The registers are pushed starting with the highest encoding,
138   // which means that lowest encodings are closest to the stack pointer.
139   return kSafepointRegisterStackIndexMap[reg_code];
140 }
141
142
143 MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) {
144   return MemOperand(sp, SafepointRegisterStackIndex(reg.code()) * kPointerSize);
145 }
146
147
148 MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) {
149   UNIMPLEMENTED_MIPS();
150   // General purpose registers are pushed last on the stack.
151   int doubles_size = FPURegister::NumAllocatableRegisters() * kDoubleSize;
152   int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize;
153   return MemOperand(sp, doubles_size + register_offset);
154 }
155
156
157 void MacroAssembler::InNewSpace(Register object,
158                                 Register scratch,
159                                 Condition cc,
160                                 Label* branch) {
161   DCHECK(cc == eq || cc == ne);
162   And(scratch, object, Operand(ExternalReference::new_space_mask(isolate())));
163   Branch(branch, cc, scratch,
164          Operand(ExternalReference::new_space_start(isolate())));
165 }
166
167
168 // Clobbers object, dst, value, and ra, if (ra_status == kRAHasBeenSaved)
169 // The register 'object' contains a heap object pointer.  The heap object
170 // tag is shifted away.
171 void MacroAssembler::RecordWriteField(
172     Register object,
173     int offset,
174     Register value,
175     Register dst,
176     RAStatus ra_status,
177     SaveFPRegsMode save_fp,
178     RememberedSetAction remembered_set_action,
179     SmiCheck smi_check,
180     PointersToHereCheck pointers_to_here_check_for_value) {
181   DCHECK(!AreAliased(value, dst, t8, object));
182   // First, check if a write barrier is even needed. The tests below
183   // catch stores of Smis.
184   Label done;
185
186   // Skip barrier if writing a smi.
187   if (smi_check == INLINE_SMI_CHECK) {
188     JumpIfSmi(value, &done);
189   }
190
191   // Although the object register is tagged, the offset is relative to the start
192   // of the object, so so offset must be a multiple of kPointerSize.
193   DCHECK(IsAligned(offset, kPointerSize));
194
195   Daddu(dst, object, Operand(offset - kHeapObjectTag));
196   if (emit_debug_code()) {
197     Label ok;
198     And(t8, dst, Operand((1 << kPointerSizeLog2) - 1));
199     Branch(&ok, eq, t8, Operand(zero_reg));
200     stop("Unaligned cell in write barrier");
201     bind(&ok);
202   }
203
204   RecordWrite(object,
205               dst,
206               value,
207               ra_status,
208               save_fp,
209               remembered_set_action,
210               OMIT_SMI_CHECK,
211               pointers_to_here_check_for_value);
212
213   bind(&done);
214
215   // Clobber clobbered input registers when running with the debug-code flag
216   // turned on to provoke errors.
217   if (emit_debug_code()) {
218     li(value, Operand(bit_cast<int64_t>(kZapValue + 4)));
219     li(dst, Operand(bit_cast<int64_t>(kZapValue + 8)));
220   }
221 }
222
223
224 // Clobbers object, dst, map, and ra, if (ra_status == kRAHasBeenSaved)
225 void MacroAssembler::RecordWriteForMap(Register object,
226                                        Register map,
227                                        Register dst,
228                                        RAStatus ra_status,
229                                        SaveFPRegsMode fp_mode) {
230   if (emit_debug_code()) {
231     DCHECK(!dst.is(at));
232     ld(dst, FieldMemOperand(map, HeapObject::kMapOffset));
233     Check(eq,
234           kWrongAddressOrValuePassedToRecordWrite,
235           dst,
236           Operand(isolate()->factory()->meta_map()));
237   }
238
239   if (!FLAG_incremental_marking) {
240     return;
241   }
242
243   if (emit_debug_code()) {
244     ld(at, FieldMemOperand(object, HeapObject::kMapOffset));
245     Check(eq,
246           kWrongAddressOrValuePassedToRecordWrite,
247           map,
248           Operand(at));
249   }
250
251   Label done;
252
253   // A single check of the map's pages interesting flag suffices, since it is
254   // only set during incremental collection, and then it's also guaranteed that
255   // the from object's page's interesting flag is also set.  This optimization
256   // relies on the fact that maps can never be in new space.
257   CheckPageFlag(map,
258                 map,  // Used as scratch.
259                 MemoryChunk::kPointersToHereAreInterestingMask,
260                 eq,
261                 &done);
262
263   Daddu(dst, object, Operand(HeapObject::kMapOffset - kHeapObjectTag));
264   if (emit_debug_code()) {
265     Label ok;
266     And(at, dst, Operand((1 << kPointerSizeLog2) - 1));
267     Branch(&ok, eq, at, Operand(zero_reg));
268     stop("Unaligned cell in write barrier");
269     bind(&ok);
270   }
271
272   // Record the actual write.
273   if (ra_status == kRAHasNotBeenSaved) {
274     push(ra);
275   }
276   RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET,
277                        fp_mode);
278   CallStub(&stub);
279   if (ra_status == kRAHasNotBeenSaved) {
280     pop(ra);
281   }
282
283   bind(&done);
284
285   // Count number of write barriers in generated code.
286   isolate()->counters()->write_barriers_static()->Increment();
287   IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1, at, dst);
288
289   // Clobber clobbered registers when running with the debug-code flag
290   // turned on to provoke errors.
291   if (emit_debug_code()) {
292     li(dst, Operand(bit_cast<int64_t>(kZapValue + 12)));
293     li(map, Operand(bit_cast<int64_t>(kZapValue + 16)));
294   }
295 }
296
297
298 // Clobbers object, address, value, and ra, if (ra_status == kRAHasBeenSaved)
299 // The register 'object' contains a heap object pointer.  The heap object
300 // tag is shifted away.
301 void MacroAssembler::RecordWrite(
302     Register object,
303     Register address,
304     Register value,
305     RAStatus ra_status,
306     SaveFPRegsMode fp_mode,
307     RememberedSetAction remembered_set_action,
308     SmiCheck smi_check,
309     PointersToHereCheck pointers_to_here_check_for_value) {
310   DCHECK(!AreAliased(object, address, value, t8));
311   DCHECK(!AreAliased(object, address, value, t9));
312
313   if (emit_debug_code()) {
314     ld(at, MemOperand(address));
315     Assert(
316         eq, kWrongAddressOrValuePassedToRecordWrite, at, Operand(value));
317   }
318
319   if (remembered_set_action == OMIT_REMEMBERED_SET &&
320       !FLAG_incremental_marking) {
321     return;
322   }
323
324   // First, check if a write barrier is even needed. The tests below
325   // catch stores of smis and stores into the young generation.
326   Label done;
327
328   if (smi_check == INLINE_SMI_CHECK) {
329     DCHECK_EQ(0, kSmiTag);
330     JumpIfSmi(value, &done);
331   }
332
333   if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) {
334     CheckPageFlag(value,
335                   value,  // Used as scratch.
336                   MemoryChunk::kPointersToHereAreInterestingMask,
337                   eq,
338                   &done);
339   }
340   CheckPageFlag(object,
341                 value,  // Used as scratch.
342                 MemoryChunk::kPointersFromHereAreInterestingMask,
343                 eq,
344                 &done);
345
346   // Record the actual write.
347   if (ra_status == kRAHasNotBeenSaved) {
348     push(ra);
349   }
350   RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
351                        fp_mode);
352   CallStub(&stub);
353   if (ra_status == kRAHasNotBeenSaved) {
354     pop(ra);
355   }
356
357   bind(&done);
358
359   // Count number of write barriers in generated code.
360   isolate()->counters()->write_barriers_static()->Increment();
361   IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1, at,
362                    value);
363
364   // Clobber clobbered registers when running with the debug-code flag
365   // turned on to provoke errors.
366   if (emit_debug_code()) {
367     li(address, Operand(bit_cast<int64_t>(kZapValue + 12)));
368     li(value, Operand(bit_cast<int64_t>(kZapValue + 16)));
369   }
370 }
371
372
373 void MacroAssembler::RememberedSetHelper(Register object,  // For debug tests.
374                                          Register address,
375                                          Register scratch,
376                                          SaveFPRegsMode fp_mode,
377                                          RememberedSetFinalAction and_then) {
378   Label done;
379   if (emit_debug_code()) {
380     Label ok;
381     JumpIfNotInNewSpace(object, scratch, &ok);
382     stop("Remembered set pointer is in new space");
383     bind(&ok);
384   }
385   // Load store buffer top.
386   ExternalReference store_buffer =
387       ExternalReference::store_buffer_top(isolate());
388   li(t8, Operand(store_buffer));
389   ld(scratch, MemOperand(t8));
390   // Store pointer to buffer and increment buffer top.
391   sd(address, MemOperand(scratch));
392   Daddu(scratch, scratch, kPointerSize);
393   // Write back new top of buffer.
394   sd(scratch, MemOperand(t8));
395   // Call stub on end of buffer.
396   // Check for end of buffer.
397   And(t8, scratch, Operand(StoreBuffer::kStoreBufferOverflowBit));
398   DCHECK(!scratch.is(t8));
399   if (and_then == kFallThroughAtEnd) {
400     Branch(&done, eq, t8, Operand(zero_reg));
401   } else {
402     DCHECK(and_then == kReturnAtEnd);
403     Ret(eq, t8, Operand(zero_reg));
404   }
405   push(ra);
406   StoreBufferOverflowStub store_buffer_overflow(isolate(), fp_mode);
407   CallStub(&store_buffer_overflow);
408   pop(ra);
409   bind(&done);
410   if (and_then == kReturnAtEnd) {
411     Ret();
412   }
413 }
414
415
416 // -----------------------------------------------------------------------------
417 // Allocation support.
418
419
420 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
421                                             Register scratch,
422                                             Label* miss) {
423   Label same_contexts;
424
425   DCHECK(!holder_reg.is(scratch));
426   DCHECK(!holder_reg.is(at));
427   DCHECK(!scratch.is(at));
428
429   // Load current lexical context from the stack frame.
430   ld(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset));
431   // In debug mode, make sure the lexical context is set.
432 #ifdef DEBUG
433   Check(ne, kWeShouldNotHaveAnEmptyLexicalContext,
434       scratch, Operand(zero_reg));
435 #endif
436
437   // Load the native context of the current context.
438   int offset =
439       Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
440   ld(scratch, FieldMemOperand(scratch, offset));
441   ld(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
442
443   // Check the context is a native context.
444   if (emit_debug_code()) {
445     push(holder_reg);  // Temporarily save holder on the stack.
446     // Read the first word and compare to the native_context_map.
447     ld(holder_reg, FieldMemOperand(scratch, HeapObject::kMapOffset));
448     LoadRoot(at, Heap::kNativeContextMapRootIndex);
449     Check(eq, kJSGlobalObjectNativeContextShouldBeANativeContext,
450           holder_reg, Operand(at));
451     pop(holder_reg);  // Restore holder.
452   }
453
454   // Check if both contexts are the same.
455   ld(at, FieldMemOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
456   Branch(&same_contexts, eq, scratch, Operand(at));
457
458   // Check the context is a native context.
459   if (emit_debug_code()) {
460     push(holder_reg);  // Temporarily save holder on the stack.
461     mov(holder_reg, at);  // Move at to its holding place.
462     LoadRoot(at, Heap::kNullValueRootIndex);
463     Check(ne, kJSGlobalProxyContextShouldNotBeNull,
464           holder_reg, Operand(at));
465
466     ld(holder_reg, FieldMemOperand(holder_reg, HeapObject::kMapOffset));
467     LoadRoot(at, Heap::kNativeContextMapRootIndex);
468     Check(eq, kJSGlobalObjectNativeContextShouldBeANativeContext,
469           holder_reg, Operand(at));
470     // Restore at is not needed. at is reloaded below.
471     pop(holder_reg);  // Restore holder.
472     // Restore at to holder's context.
473     ld(at, FieldMemOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
474   }
475
476   // Check that the security token in the calling global object is
477   // compatible with the security token in the receiving global
478   // object.
479   int token_offset = Context::kHeaderSize +
480                      Context::SECURITY_TOKEN_INDEX * kPointerSize;
481
482   ld(scratch, FieldMemOperand(scratch, token_offset));
483   ld(at, FieldMemOperand(at, token_offset));
484   Branch(miss, ne, scratch, Operand(at));
485
486   bind(&same_contexts);
487 }
488
489
490 // Compute the hash code from the untagged key.  This must be kept in sync with
491 // ComputeIntegerHash in utils.h and KeyedLoadGenericStub in
492 // code-stub-hydrogen.cc
493 void MacroAssembler::GetNumberHash(Register reg0, Register scratch) {
494   // First of all we assign the hash seed to scratch.
495   LoadRoot(scratch, Heap::kHashSeedRootIndex);
496   SmiUntag(scratch);
497
498   // Xor original key with a seed.
499   xor_(reg0, reg0, scratch);
500
501   // Compute the hash code from the untagged key.  This must be kept in sync
502   // with ComputeIntegerHash in utils.h.
503   //
504   // hash = ~hash + (hash << 15);
505   // The algorithm uses 32-bit integer values.
506   nor(scratch, reg0, zero_reg);
507   sll(at, reg0, 15);
508   addu(reg0, scratch, at);
509
510   // hash = hash ^ (hash >> 12);
511   srl(at, reg0, 12);
512   xor_(reg0, reg0, at);
513
514   // hash = hash + (hash << 2);
515   sll(at, reg0, 2);
516   addu(reg0, reg0, at);
517
518   // hash = hash ^ (hash >> 4);
519   srl(at, reg0, 4);
520   xor_(reg0, reg0, at);
521
522   // hash = hash * 2057;
523   sll(scratch, reg0, 11);
524   sll(at, reg0, 3);
525   addu(reg0, reg0, at);
526   addu(reg0, reg0, scratch);
527
528   // hash = hash ^ (hash >> 16);
529   srl(at, reg0, 16);
530   xor_(reg0, reg0, at);
531   And(reg0, reg0, Operand(0x3fffffff));
532 }
533
534
535 void MacroAssembler::LoadFromNumberDictionary(Label* miss,
536                                               Register elements,
537                                               Register key,
538                                               Register result,
539                                               Register reg0,
540                                               Register reg1,
541                                               Register reg2) {
542   // Register use:
543   //
544   // elements - holds the slow-case elements of the receiver on entry.
545   //            Unchanged unless 'result' is the same register.
546   //
547   // key      - holds the smi key on entry.
548   //            Unchanged unless 'result' is the same register.
549   //
550   //
551   // result   - holds the result on exit if the load succeeded.
552   //            Allowed to be the same as 'key' or 'result'.
553   //            Unchanged on bailout so 'key' or 'result' can be used
554   //            in further computation.
555   //
556   // Scratch registers:
557   //
558   // reg0 - holds the untagged key on entry and holds the hash once computed.
559   //
560   // reg1 - Used to hold the capacity mask of the dictionary.
561   //
562   // reg2 - Used for the index into the dictionary.
563   // at   - Temporary (avoid MacroAssembler instructions also using 'at').
564   Label done;
565
566   GetNumberHash(reg0, reg1);
567
568   // Compute the capacity mask.
569   ld(reg1, FieldMemOperand(elements, SeededNumberDictionary::kCapacityOffset));
570   SmiUntag(reg1, reg1);
571   Dsubu(reg1, reg1, Operand(1));
572
573   // Generate an unrolled loop that performs a few probes before giving up.
574   for (int i = 0; i < kNumberDictionaryProbes; i++) {
575     // Use reg2 for index calculations and keep the hash intact in reg0.
576     mov(reg2, reg0);
577     // Compute the masked index: (hash + i + i * i) & mask.
578     if (i > 0) {
579       Daddu(reg2, reg2, Operand(SeededNumberDictionary::GetProbeOffset(i)));
580     }
581     and_(reg2, reg2, reg1);
582
583     // Scale the index by multiplying by the element size.
584     DCHECK(SeededNumberDictionary::kEntrySize == 3);
585     dsll(at, reg2, 1);  // 2x.
586     daddu(reg2, reg2, at);  // reg2 = reg2 * 3.
587
588     // Check if the key is identical to the name.
589     dsll(at, reg2, kPointerSizeLog2);
590     daddu(reg2, elements, at);
591
592     ld(at, FieldMemOperand(reg2, SeededNumberDictionary::kElementsStartOffset));
593     if (i != kNumberDictionaryProbes - 1) {
594       Branch(&done, eq, key, Operand(at));
595     } else {
596       Branch(miss, ne, key, Operand(at));
597     }
598   }
599
600   bind(&done);
601   // Check that the value is a field property.
602   // reg2: elements + (index * kPointerSize).
603   const int kDetailsOffset =
604       SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
605   ld(reg1, FieldMemOperand(reg2, kDetailsOffset));
606   DCHECK_EQ(DATA, 0);
607   And(at, reg1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask)));
608   Branch(miss, ne, at, Operand(zero_reg));
609
610   // Get the value at the masked, scaled index and return.
611   const int kValueOffset =
612       SeededNumberDictionary::kElementsStartOffset + kPointerSize;
613   ld(result, FieldMemOperand(reg2, kValueOffset));
614 }
615
616
617 // ---------------------------------------------------------------------------
618 // Instruction macros.
619
620 void MacroAssembler::Addu(Register rd, Register rs, const Operand& rt) {
621   if (rt.is_reg()) {
622     addu(rd, rs, rt.rm());
623   } else {
624     if (is_int16(rt.imm64_) && !MustUseReg(rt.rmode_)) {
625       addiu(rd, rs, static_cast<int32_t>(rt.imm64_));
626     } else {
627       // li handles the relocation.
628       DCHECK(!rs.is(at));
629       li(at, rt);
630       addu(rd, rs, at);
631     }
632   }
633 }
634
635
636 void MacroAssembler::Daddu(Register rd, Register rs, const Operand& rt) {
637   if (rt.is_reg()) {
638     daddu(rd, rs, rt.rm());
639   } else {
640     if (is_int16(rt.imm64_) && !MustUseReg(rt.rmode_)) {
641       daddiu(rd, rs, static_cast<int32_t>(rt.imm64_));
642     } else {
643       // li handles the relocation.
644       DCHECK(!rs.is(at));
645       li(at, rt);
646       daddu(rd, rs, at);
647     }
648   }
649 }
650
651
652 void MacroAssembler::Subu(Register rd, Register rs, const Operand& rt) {
653   if (rt.is_reg()) {
654     subu(rd, rs, rt.rm());
655   } else {
656     if (is_int16(rt.imm64_) && !MustUseReg(rt.rmode_)) {
657       addiu(rd, rs, static_cast<int32_t>(
658                         -rt.imm64_));  // No subiu instr, use addiu(x, y, -imm).
659     } else {
660       // li handles the relocation.
661       DCHECK(!rs.is(at));
662       li(at, rt);
663       subu(rd, rs, at);
664     }
665   }
666 }
667
668
669 void MacroAssembler::Dsubu(Register rd, Register rs, const Operand& rt) {
670   if (rt.is_reg()) {
671     dsubu(rd, rs, rt.rm());
672   } else {
673     if (is_int16(rt.imm64_) && !MustUseReg(rt.rmode_)) {
674       daddiu(rd, rs,
675              static_cast<int32_t>(
676                  -rt.imm64_));  // No subiu instr, use addiu(x, y, -imm).
677     } else {
678       // li handles the relocation.
679       DCHECK(!rs.is(at));
680       li(at, rt);
681       dsubu(rd, rs, at);
682     }
683   }
684 }
685
686
687 void MacroAssembler::Mul(Register rd, Register rs, const Operand& rt) {
688   if (rt.is_reg()) {
689     mul(rd, rs, rt.rm());
690   } else {
691     // li handles the relocation.
692     DCHECK(!rs.is(at));
693     li(at, rt);
694     mul(rd, rs, at);
695   }
696 }
697
698
699 void MacroAssembler::Mulh(Register rd, Register rs, const Operand& rt) {
700   if (rt.is_reg()) {
701     if (kArchVariant != kMips64r6) {
702       mult(rs, rt.rm());
703       mfhi(rd);
704     } else {
705       muh(rd, rs, rt.rm());
706     }
707   } else {
708     // li handles the relocation.
709     DCHECK(!rs.is(at));
710     li(at, rt);
711     if (kArchVariant != kMips64r6) {
712       mult(rs, at);
713       mfhi(rd);
714     } else {
715       muh(rd, rs, at);
716     }
717   }
718 }
719
720
721 void MacroAssembler::Mulhu(Register rd, Register rs, const Operand& rt) {
722   if (rt.is_reg()) {
723     if (kArchVariant != kMips64r6) {
724       multu(rs, rt.rm());
725       mfhi(rd);
726     } else {
727       muhu(rd, rs, rt.rm());
728     }
729   } else {
730     // li handles the relocation.
731     DCHECK(!rs.is(at));
732     li(at, rt);
733     if (kArchVariant != kMips64r6) {
734       multu(rs, at);
735       mfhi(rd);
736     } else {
737       muhu(rd, rs, at);
738     }
739   }
740 }
741
742
743 void MacroAssembler::Dmul(Register rd, Register rs, const Operand& rt) {
744   if (rt.is_reg()) {
745     if (kArchVariant == kMips64r6) {
746       dmul(rd, rs, rt.rm());
747     } else {
748       dmult(rs, rt.rm());
749       mflo(rd);
750     }
751   } else {
752     // li handles the relocation.
753     DCHECK(!rs.is(at));
754     li(at, rt);
755     if (kArchVariant == kMips64r6) {
756       dmul(rd, rs, at);
757     } else {
758       dmult(rs, at);
759       mflo(rd);
760     }
761   }
762 }
763
764
765 void MacroAssembler::Dmulh(Register rd, Register rs, const Operand& rt) {
766   if (rt.is_reg()) {
767     if (kArchVariant == kMips64r6) {
768       dmuh(rd, rs, rt.rm());
769     } else {
770       dmult(rs, rt.rm());
771       mfhi(rd);
772     }
773   } else {
774     // li handles the relocation.
775     DCHECK(!rs.is(at));
776     li(at, rt);
777     if (kArchVariant == kMips64r6) {
778       dmuh(rd, rs, at);
779     } else {
780       dmult(rs, at);
781       mfhi(rd);
782     }
783   }
784 }
785
786
787 void MacroAssembler::Mult(Register rs, const Operand& rt) {
788   if (rt.is_reg()) {
789     mult(rs, rt.rm());
790   } else {
791     // li handles the relocation.
792     DCHECK(!rs.is(at));
793     li(at, rt);
794     mult(rs, at);
795   }
796 }
797
798
799 void MacroAssembler::Dmult(Register rs, const Operand& rt) {
800   if (rt.is_reg()) {
801     dmult(rs, rt.rm());
802   } else {
803     // li handles the relocation.
804     DCHECK(!rs.is(at));
805     li(at, rt);
806     dmult(rs, at);
807   }
808 }
809
810
811 void MacroAssembler::Multu(Register rs, const Operand& rt) {
812   if (rt.is_reg()) {
813     multu(rs, rt.rm());
814   } else {
815     // li handles the relocation.
816     DCHECK(!rs.is(at));
817     li(at, rt);
818     multu(rs, at);
819   }
820 }
821
822
823 void MacroAssembler::Dmultu(Register rs, const Operand& rt) {
824   if (rt.is_reg()) {
825     dmultu(rs, rt.rm());
826   } else {
827     // li handles the relocation.
828     DCHECK(!rs.is(at));
829     li(at, rt);
830     dmultu(rs, at);
831   }
832 }
833
834
835 void MacroAssembler::Div(Register rs, const Operand& rt) {
836   if (rt.is_reg()) {
837     div(rs, rt.rm());
838   } else {
839     // li handles the relocation.
840     DCHECK(!rs.is(at));
841     li(at, rt);
842     div(rs, at);
843   }
844 }
845
846
847 void MacroAssembler::Div(Register res, Register rs, const Operand& rt) {
848   if (rt.is_reg()) {
849     if (kArchVariant != kMips64r6) {
850       div(rs, rt.rm());
851       mflo(res);
852     } else {
853       div(res, rs, rt.rm());
854     }
855   } else {
856     // li handles the relocation.
857     DCHECK(!rs.is(at));
858     li(at, rt);
859     if (kArchVariant != kMips64r6) {
860       div(rs, at);
861       mflo(res);
862     } else {
863       div(res, rs, at);
864     }
865   }
866 }
867
868
869 void MacroAssembler::Mod(Register rd, Register rs, const Operand& rt) {
870   if (rt.is_reg()) {
871     if (kArchVariant != kMips64r6) {
872       div(rs, rt.rm());
873       mfhi(rd);
874     } else {
875       mod(rd, rs, rt.rm());
876     }
877   } else {
878     // li handles the relocation.
879     DCHECK(!rs.is(at));
880     li(at, rt);
881     if (kArchVariant != kMips64r6) {
882       div(rs, at);
883       mfhi(rd);
884     } else {
885       mod(rd, rs, at);
886     }
887   }
888 }
889
890
891 void MacroAssembler::Modu(Register rd, Register rs, const Operand& rt) {
892   if (rt.is_reg()) {
893     if (kArchVariant != kMips64r6) {
894       divu(rs, rt.rm());
895       mfhi(rd);
896     } else {
897       modu(rd, rs, rt.rm());
898     }
899   } else {
900     // li handles the relocation.
901     DCHECK(!rs.is(at));
902     li(at, rt);
903     if (kArchVariant != kMips64r6) {
904       divu(rs, at);
905       mfhi(rd);
906     } else {
907       modu(rd, rs, at);
908     }
909   }
910 }
911
912
913 void MacroAssembler::Ddiv(Register rs, const Operand& rt) {
914   if (rt.is_reg()) {
915     ddiv(rs, rt.rm());
916   } else {
917     // li handles the relocation.
918     DCHECK(!rs.is(at));
919     li(at, rt);
920     ddiv(rs, at);
921   }
922 }
923
924
925 void MacroAssembler::Ddiv(Register rd, Register rs, const Operand& rt) {
926   if (kArchVariant != kMips64r6) {
927     if (rt.is_reg()) {
928       ddiv(rs, rt.rm());
929       mflo(rd);
930     } else {
931       // li handles the relocation.
932       DCHECK(!rs.is(at));
933       li(at, rt);
934       ddiv(rs, at);
935       mflo(rd);
936     }
937   } else {
938     if (rt.is_reg()) {
939       ddiv(rd, rs, rt.rm());
940     } else {
941       // li handles the relocation.
942       DCHECK(!rs.is(at));
943       li(at, rt);
944       ddiv(rd, rs, at);
945     }
946   }
947 }
948
949
950 void MacroAssembler::Divu(Register rs, const Operand& rt) {
951   if (rt.is_reg()) {
952     divu(rs, rt.rm());
953   } else {
954     // li handles the relocation.
955     DCHECK(!rs.is(at));
956     li(at, rt);
957     divu(rs, at);
958   }
959 }
960
961
962 void MacroAssembler::Divu(Register res, Register rs, const Operand& rt) {
963   if (rt.is_reg()) {
964     if (kArchVariant != kMips64r6) {
965       divu(rs, rt.rm());
966       mflo(res);
967     } else {
968       divu(res, rs, rt.rm());
969     }
970   } else {
971     // li handles the relocation.
972     DCHECK(!rs.is(at));
973     li(at, rt);
974     if (kArchVariant != kMips64r6) {
975       divu(rs, at);
976       mflo(res);
977     } else {
978       divu(res, rs, at);
979     }
980   }
981 }
982
983
984 void MacroAssembler::Ddivu(Register rs, const Operand& rt) {
985   if (rt.is_reg()) {
986     ddivu(rs, rt.rm());
987   } else {
988     // li handles the relocation.
989     DCHECK(!rs.is(at));
990     li(at, rt);
991     ddivu(rs, at);
992   }
993 }
994
995
996 void MacroAssembler::Ddivu(Register res, Register rs, const Operand& rt) {
997   if (rt.is_reg()) {
998     if (kArchVariant != kMips64r6) {
999       ddivu(rs, rt.rm());
1000       mflo(res);
1001     } else {
1002       ddivu(res, rs, rt.rm());
1003     }
1004   } else {
1005     // li handles the relocation.
1006     DCHECK(!rs.is(at));
1007     li(at, rt);
1008     if (kArchVariant != kMips64r6) {
1009       ddivu(rs, at);
1010       mflo(res);
1011     } else {
1012       ddivu(res, rs, at);
1013     }
1014   }
1015 }
1016
1017
1018 void MacroAssembler::Dmod(Register rd, Register rs, const Operand& rt) {
1019   if (kArchVariant != kMips64r6) {
1020     if (rt.is_reg()) {
1021       ddiv(rs, rt.rm());
1022       mfhi(rd);
1023     } else {
1024       // li handles the relocation.
1025       DCHECK(!rs.is(at));
1026       li(at, rt);
1027       ddiv(rs, at);
1028       mfhi(rd);
1029     }
1030   } else {
1031     if (rt.is_reg()) {
1032       dmod(rd, rs, rt.rm());
1033     } else {
1034       // li handles the relocation.
1035       DCHECK(!rs.is(at));
1036       li(at, rt);
1037       dmod(rd, rs, at);
1038     }
1039   }
1040 }
1041
1042
1043 void MacroAssembler::Dmodu(Register rd, Register rs, const Operand& rt) {
1044   if (kArchVariant != kMips64r6) {
1045     if (rt.is_reg()) {
1046       ddivu(rs, rt.rm());
1047       mfhi(rd);
1048     } else {
1049       // li handles the relocation.
1050       DCHECK(!rs.is(at));
1051       li(at, rt);
1052       ddivu(rs, at);
1053       mfhi(rd);
1054     }
1055   } else {
1056     if (rt.is_reg()) {
1057       dmodu(rd, rs, rt.rm());
1058     } else {
1059       // li handles the relocation.
1060       DCHECK(!rs.is(at));
1061       li(at, rt);
1062       dmodu(rd, rs, at);
1063     }
1064   }
1065 }
1066
1067
1068 void MacroAssembler::And(Register rd, Register rs, const Operand& rt) {
1069   if (rt.is_reg()) {
1070     and_(rd, rs, rt.rm());
1071   } else {
1072     if (is_uint16(rt.imm64_) && !MustUseReg(rt.rmode_)) {
1073       andi(rd, rs, static_cast<int32_t>(rt.imm64_));
1074     } else {
1075       // li handles the relocation.
1076       DCHECK(!rs.is(at));
1077       li(at, rt);
1078       and_(rd, rs, at);
1079     }
1080   }
1081 }
1082
1083
1084 void MacroAssembler::Or(Register rd, Register rs, const Operand& rt) {
1085   if (rt.is_reg()) {
1086     or_(rd, rs, rt.rm());
1087   } else {
1088     if (is_uint16(rt.imm64_) && !MustUseReg(rt.rmode_)) {
1089       ori(rd, rs, static_cast<int32_t>(rt.imm64_));
1090     } else {
1091       // li handles the relocation.
1092       DCHECK(!rs.is(at));
1093       li(at, rt);
1094       or_(rd, rs, at);
1095     }
1096   }
1097 }
1098
1099
1100 void MacroAssembler::Xor(Register rd, Register rs, const Operand& rt) {
1101   if (rt.is_reg()) {
1102     xor_(rd, rs, rt.rm());
1103   } else {
1104     if (is_uint16(rt.imm64_) && !MustUseReg(rt.rmode_)) {
1105       xori(rd, rs, static_cast<int32_t>(rt.imm64_));
1106     } else {
1107       // li handles the relocation.
1108       DCHECK(!rs.is(at));
1109       li(at, rt);
1110       xor_(rd, rs, at);
1111     }
1112   }
1113 }
1114
1115
1116 void MacroAssembler::Nor(Register rd, Register rs, const Operand& rt) {
1117   if (rt.is_reg()) {
1118     nor(rd, rs, rt.rm());
1119   } else {
1120     // li handles the relocation.
1121     DCHECK(!rs.is(at));
1122     li(at, rt);
1123     nor(rd, rs, at);
1124   }
1125 }
1126
1127
1128 void MacroAssembler::Neg(Register rs, const Operand& rt) {
1129   DCHECK(rt.is_reg());
1130   DCHECK(!at.is(rs));
1131   DCHECK(!at.is(rt.rm()));
1132   li(at, -1);
1133   xor_(rs, rt.rm(), at);
1134 }
1135
1136
1137 void MacroAssembler::Slt(Register rd, Register rs, const Operand& rt) {
1138   if (rt.is_reg()) {
1139     slt(rd, rs, rt.rm());
1140   } else {
1141     if (is_int16(rt.imm64_) && !MustUseReg(rt.rmode_)) {
1142       slti(rd, rs, static_cast<int32_t>(rt.imm64_));
1143     } else {
1144       // li handles the relocation.
1145       DCHECK(!rs.is(at));
1146       li(at, rt);
1147       slt(rd, rs, at);
1148     }
1149   }
1150 }
1151
1152
1153 void MacroAssembler::Sltu(Register rd, Register rs, const Operand& rt) {
1154   if (rt.is_reg()) {
1155     sltu(rd, rs, rt.rm());
1156   } else {
1157     if (is_int16(rt.imm64_) && !MustUseReg(rt.rmode_)) {
1158       sltiu(rd, rs, static_cast<int32_t>(rt.imm64_));
1159     } else {
1160       // li handles the relocation.
1161       DCHECK(!rs.is(at));
1162       li(at, rt);
1163       sltu(rd, rs, at);
1164     }
1165   }
1166 }
1167
1168
1169 void MacroAssembler::Ror(Register rd, Register rs, const Operand& rt) {
1170   if (rt.is_reg()) {
1171     rotrv(rd, rs, rt.rm());
1172   } else {
1173     rotr(rd, rs, rt.imm64_);
1174   }
1175 }
1176
1177
1178 void MacroAssembler::Dror(Register rd, Register rs, const Operand& rt) {
1179   if (rt.is_reg()) {
1180     drotrv(rd, rs, rt.rm());
1181   } else {
1182     drotr(rd, rs, rt.imm64_);
1183   }
1184 }
1185
1186
1187 void MacroAssembler::Pref(int32_t hint, const MemOperand& rs) {
1188     pref(hint, rs);
1189 }
1190
1191
1192 // ------------Pseudo-instructions-------------
1193
1194 void MacroAssembler::Ulw(Register rd, const MemOperand& rs) {
1195   lwr(rd, rs);
1196   lwl(rd, MemOperand(rs.rm(), rs.offset() + 3));
1197 }
1198
1199
1200 void MacroAssembler::Usw(Register rd, const MemOperand& rs) {
1201   swr(rd, rs);
1202   swl(rd, MemOperand(rs.rm(), rs.offset() + 3));
1203 }
1204
1205
1206 // Do 64-bit load from unaligned address. Note this only handles
1207 // the specific case of 32-bit aligned, but not 64-bit aligned.
1208 void MacroAssembler::Uld(Register rd, const MemOperand& rs, Register scratch) {
1209   // Assert fail if the offset from start of object IS actually aligned.
1210   // ONLY use with known misalignment, since there is performance cost.
1211   DCHECK((rs.offset() + kHeapObjectTag) & (kPointerSize - 1));
1212   // TODO(plind): endian dependency.
1213   lwu(rd, rs);
1214   lw(scratch, MemOperand(rs.rm(), rs.offset() + kPointerSize / 2));
1215   dsll32(scratch, scratch, 0);
1216   Daddu(rd, rd, scratch);
1217 }
1218
1219
1220 // Do 64-bit store to unaligned address. Note this only handles
1221 // the specific case of 32-bit aligned, but not 64-bit aligned.
1222 void MacroAssembler::Usd(Register rd, const MemOperand& rs, Register scratch) {
1223   // Assert fail if the offset from start of object IS actually aligned.
1224   // ONLY use with known misalignment, since there is performance cost.
1225   DCHECK((rs.offset() + kHeapObjectTag) & (kPointerSize - 1));
1226   // TODO(plind): endian dependency.
1227   sw(rd, rs);
1228   dsrl32(scratch, rd, 0);
1229   sw(scratch, MemOperand(rs.rm(), rs.offset() + kPointerSize / 2));
1230 }
1231
1232
1233 void MacroAssembler::li(Register dst, Handle<Object> value, LiFlags mode) {
1234   AllowDeferredHandleDereference smi_check;
1235   if (value->IsSmi()) {
1236     li(dst, Operand(value), mode);
1237   } else {
1238     DCHECK(value->IsHeapObject());
1239     if (isolate()->heap()->InNewSpace(*value)) {
1240       Handle<Cell> cell = isolate()->factory()->NewCell(value);
1241       li(dst, Operand(cell));
1242       ld(dst, FieldMemOperand(dst, Cell::kValueOffset));
1243     } else {
1244       li(dst, Operand(value));
1245     }
1246   }
1247 }
1248
1249
1250 void MacroAssembler::li(Register rd, Operand j, LiFlags mode) {
1251   DCHECK(!j.is_reg());
1252   BlockTrampolinePoolScope block_trampoline_pool(this);
1253   if (!MustUseReg(j.rmode_) && mode == OPTIMIZE_SIZE) {
1254     // Normal load of an immediate value which does not need Relocation Info.
1255     if (is_int32(j.imm64_)) {
1256       if (is_int16(j.imm64_)) {
1257         daddiu(rd, zero_reg, (j.imm64_ & kImm16Mask));
1258       } else if (!(j.imm64_ & kHiMask)) {
1259         ori(rd, zero_reg, (j.imm64_ & kImm16Mask));
1260       } else if (!(j.imm64_ & kImm16Mask)) {
1261         lui(rd, (j.imm64_ >> kLuiShift) & kImm16Mask);
1262       } else {
1263         lui(rd, (j.imm64_ >> kLuiShift) & kImm16Mask);
1264         ori(rd, rd, (j.imm64_ & kImm16Mask));
1265       }
1266     } else {
1267       if (is_int48(j.imm64_)) {
1268         if ((j.imm64_ >> 32) & kImm16Mask) {
1269           lui(rd, (j.imm64_ >> 32) & kImm16Mask);
1270           if ((j.imm64_ >> 16) & kImm16Mask) {
1271             ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
1272           }
1273         } else {
1274           ori(rd, zero_reg, (j.imm64_ >> 16) & kImm16Mask);
1275         }
1276         dsll(rd, rd, 16);
1277         if (j.imm64_ & kImm16Mask) {
1278           ori(rd, rd, j.imm64_ & kImm16Mask);
1279         }
1280       } else {
1281         lui(rd, (j.imm64_ >> 48) & kImm16Mask);
1282         if ((j.imm64_ >> 32) & kImm16Mask) {
1283           ori(rd, rd, (j.imm64_ >> 32) & kImm16Mask);
1284         }
1285         if ((j.imm64_ >> 16) & kImm16Mask) {
1286           dsll(rd, rd, 16);
1287           ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
1288           if (j.imm64_ & kImm16Mask) {
1289             dsll(rd, rd, 16);
1290             ori(rd, rd, j.imm64_ & kImm16Mask);
1291           } else {
1292             dsll(rd, rd, 16);
1293           }
1294         } else {
1295           if (j.imm64_ & kImm16Mask) {
1296             dsll32(rd, rd, 0);
1297             ori(rd, rd, j.imm64_ & kImm16Mask);
1298           } else {
1299             dsll32(rd, rd, 0);
1300           }
1301         }
1302       }
1303     }
1304   } else if (MustUseReg(j.rmode_)) {
1305     RecordRelocInfo(j.rmode_, j.imm64_);
1306     lui(rd, (j.imm64_ >> 32) & kImm16Mask);
1307     ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
1308     dsll(rd, rd, 16);
1309     ori(rd, rd, j.imm64_ & kImm16Mask);
1310   } else if (mode == ADDRESS_LOAD)  {
1311     // We always need the same number of instructions as we may need to patch
1312     // this code to load another value which may need all 4 instructions.
1313     lui(rd, (j.imm64_ >> 32) & kImm16Mask);
1314     ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
1315     dsll(rd, rd, 16);
1316     ori(rd, rd, j.imm64_ & kImm16Mask);
1317   } else {
1318     lui(rd, (j.imm64_ >> 48) & kImm16Mask);
1319     ori(rd, rd, (j.imm64_ >> 32) & kImm16Mask);
1320     dsll(rd, rd, 16);
1321     ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
1322     dsll(rd, rd, 16);
1323     ori(rd, rd, j.imm64_ & kImm16Mask);
1324   }
1325 }
1326
1327
1328 void MacroAssembler::MultiPush(RegList regs) {
1329   int16_t num_to_push = NumberOfBitsSet(regs);
1330   int16_t stack_offset = num_to_push * kPointerSize;
1331
1332   Dsubu(sp, sp, Operand(stack_offset));
1333   for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
1334     if ((regs & (1 << i)) != 0) {
1335       stack_offset -= kPointerSize;
1336       sd(ToRegister(i), MemOperand(sp, stack_offset));
1337     }
1338   }
1339 }
1340
1341
1342 void MacroAssembler::MultiPushReversed(RegList regs) {
1343   int16_t num_to_push = NumberOfBitsSet(regs);
1344   int16_t stack_offset = num_to_push * kPointerSize;
1345
1346   Dsubu(sp, sp, Operand(stack_offset));
1347   for (int16_t i = 0; i < kNumRegisters; i++) {
1348     if ((regs & (1 << i)) != 0) {
1349       stack_offset -= kPointerSize;
1350       sd(ToRegister(i), MemOperand(sp, stack_offset));
1351     }
1352   }
1353 }
1354
1355
1356 void MacroAssembler::MultiPop(RegList regs) {
1357   int16_t stack_offset = 0;
1358
1359   for (int16_t i = 0; i < kNumRegisters; i++) {
1360     if ((regs & (1 << i)) != 0) {
1361       ld(ToRegister(i), MemOperand(sp, stack_offset));
1362       stack_offset += kPointerSize;
1363     }
1364   }
1365   daddiu(sp, sp, stack_offset);
1366 }
1367
1368
1369 void MacroAssembler::MultiPopReversed(RegList regs) {
1370   int16_t stack_offset = 0;
1371
1372   for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
1373     if ((regs & (1 << i)) != 0) {
1374       ld(ToRegister(i), MemOperand(sp, stack_offset));
1375       stack_offset += kPointerSize;
1376     }
1377   }
1378   daddiu(sp, sp, stack_offset);
1379 }
1380
1381
1382 void MacroAssembler::MultiPushFPU(RegList regs) {
1383   int16_t num_to_push = NumberOfBitsSet(regs);
1384   int16_t stack_offset = num_to_push * kDoubleSize;
1385
1386   Dsubu(sp, sp, Operand(stack_offset));
1387   for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
1388     if ((regs & (1 << i)) != 0) {
1389       stack_offset -= kDoubleSize;
1390       sdc1(FPURegister::from_code(i), MemOperand(sp, stack_offset));
1391     }
1392   }
1393 }
1394
1395
1396 void MacroAssembler::MultiPushReversedFPU(RegList regs) {
1397   int16_t num_to_push = NumberOfBitsSet(regs);
1398   int16_t stack_offset = num_to_push * kDoubleSize;
1399
1400   Dsubu(sp, sp, Operand(stack_offset));
1401   for (int16_t i = 0; i < kNumRegisters; i++) {
1402     if ((regs & (1 << i)) != 0) {
1403       stack_offset -= kDoubleSize;
1404       sdc1(FPURegister::from_code(i), MemOperand(sp, stack_offset));
1405     }
1406   }
1407 }
1408
1409
1410 void MacroAssembler::MultiPopFPU(RegList regs) {
1411   int16_t stack_offset = 0;
1412
1413   for (int16_t i = 0; i < kNumRegisters; i++) {
1414     if ((regs & (1 << i)) != 0) {
1415       ldc1(FPURegister::from_code(i), MemOperand(sp, stack_offset));
1416       stack_offset += kDoubleSize;
1417     }
1418   }
1419   daddiu(sp, sp, stack_offset);
1420 }
1421
1422
1423 void MacroAssembler::MultiPopReversedFPU(RegList regs) {
1424   int16_t stack_offset = 0;
1425
1426   for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
1427     if ((regs & (1 << i)) != 0) {
1428       ldc1(FPURegister::from_code(i), MemOperand(sp, stack_offset));
1429       stack_offset += kDoubleSize;
1430     }
1431   }
1432   daddiu(sp, sp, stack_offset);
1433 }
1434
1435
1436 void MacroAssembler::FlushICache(Register address, unsigned instructions) {
1437   RegList saved_regs = kJSCallerSaved | ra.bit();
1438   MultiPush(saved_regs);
1439   AllowExternalCallThatCantCauseGC scope(this);
1440
1441   // Save to a0 in case address == a4.
1442   Move(a0, address);
1443   PrepareCallCFunction(2, a4);
1444
1445   li(a1, instructions * kInstrSize);
1446   CallCFunction(ExternalReference::flush_icache_function(isolate()), 2);
1447   MultiPop(saved_regs);
1448 }
1449
1450
1451 void MacroAssembler::Ext(Register rt,
1452                          Register rs,
1453                          uint16_t pos,
1454                          uint16_t size) {
1455   DCHECK(pos < 32);
1456   DCHECK(pos + size < 33);
1457   ext_(rt, rs, pos, size);
1458 }
1459
1460
1461 void MacroAssembler::Dext(Register rt, Register rs, uint16_t pos,
1462                           uint16_t size) {
1463   DCHECK(pos < 32);
1464   DCHECK(pos + size < 33);
1465   dext_(rt, rs, pos, size);
1466 }
1467
1468
1469 void MacroAssembler::Ins(Register rt,
1470                          Register rs,
1471                          uint16_t pos,
1472                          uint16_t size) {
1473   DCHECK(pos < 32);
1474   DCHECK(pos + size <= 32);
1475   DCHECK(size != 0);
1476   ins_(rt, rs, pos, size);
1477 }
1478
1479
1480 void MacroAssembler::Cvt_d_uw(FPURegister fd,
1481                               FPURegister fs,
1482                               FPURegister scratch) {
1483   // Move the data from fs to t8.
1484   mfc1(t8, fs);
1485   Cvt_d_uw(fd, t8, scratch);
1486 }
1487
1488
1489 void MacroAssembler::Cvt_d_uw(FPURegister fd,
1490                               Register rs,
1491                               FPURegister scratch) {
1492   // Convert rs to a FP value in fd (and fd + 1).
1493   // We do this by converting rs minus the MSB to avoid sign conversion,
1494   // then adding 2^31 to the result (if needed).
1495
1496   DCHECK(!fd.is(scratch));
1497   DCHECK(!rs.is(t9));
1498   DCHECK(!rs.is(at));
1499
1500   // Save rs's MSB to t9.
1501   Ext(t9, rs, 31, 1);
1502   // Remove rs's MSB.
1503   Ext(at, rs, 0, 31);
1504   // Move the result to fd.
1505   mtc1(at, fd);
1506   mthc1(zero_reg, fd);
1507
1508   // Convert fd to a real FP value.
1509   cvt_d_w(fd, fd);
1510
1511   Label conversion_done;
1512
1513   // If rs's MSB was 0, it's done.
1514   // Otherwise we need to add that to the FP register.
1515   Branch(&conversion_done, eq, t9, Operand(zero_reg));
1516
1517   // Load 2^31 into f20 as its float representation.
1518   li(at, 0x41E00000);
1519   mtc1(zero_reg, scratch);
1520   mthc1(at, scratch);
1521   // Add it to fd.
1522   add_d(fd, fd, scratch);
1523
1524   bind(&conversion_done);
1525 }
1526
1527
1528 void MacroAssembler::Round_l_d(FPURegister fd, FPURegister fs) {
1529   round_l_d(fd, fs);
1530 }
1531
1532
1533 void MacroAssembler::Floor_l_d(FPURegister fd, FPURegister fs) {
1534   floor_l_d(fd, fs);
1535 }
1536
1537
1538 void MacroAssembler::Ceil_l_d(FPURegister fd, FPURegister fs) {
1539   ceil_l_d(fd, fs);
1540 }
1541
1542
1543 void MacroAssembler::Trunc_l_d(FPURegister fd, FPURegister fs) {
1544   trunc_l_d(fd, fs);
1545 }
1546
1547
1548 void MacroAssembler::Trunc_l_ud(FPURegister fd,
1549                                 FPURegister fs,
1550                                 FPURegister scratch) {
1551   // Load to GPR.
1552   dmfc1(t8, fs);
1553   // Reset sign bit.
1554   li(at, 0x7fffffffffffffff);
1555   and_(t8, t8, at);
1556   dmtc1(t8, fs);
1557   trunc_l_d(fd, fs);
1558 }
1559
1560
1561 void MacroAssembler::Trunc_uw_d(FPURegister fd,
1562                                 FPURegister fs,
1563                                 FPURegister scratch) {
1564   Trunc_uw_d(fs, t8, scratch);
1565   mtc1(t8, fd);
1566 }
1567
1568
1569 void MacroAssembler::Trunc_w_d(FPURegister fd, FPURegister fs) {
1570   trunc_w_d(fd, fs);
1571 }
1572
1573
1574 void MacroAssembler::Round_w_d(FPURegister fd, FPURegister fs) {
1575   round_w_d(fd, fs);
1576 }
1577
1578
1579 void MacroAssembler::Floor_w_d(FPURegister fd, FPURegister fs) {
1580   floor_w_d(fd, fs);
1581 }
1582
1583
1584 void MacroAssembler::Ceil_w_d(FPURegister fd, FPURegister fs) {
1585   ceil_w_d(fd, fs);
1586 }
1587
1588
1589 void MacroAssembler::Trunc_uw_d(FPURegister fd,
1590                                 Register rs,
1591                                 FPURegister scratch) {
1592   DCHECK(!fd.is(scratch));
1593   DCHECK(!rs.is(at));
1594
1595   // Load 2^31 into scratch as its float representation.
1596   li(at, 0x41E00000);
1597   mtc1(zero_reg, scratch);
1598   mthc1(at, scratch);
1599   // Test if scratch > fd.
1600   // If fd < 2^31 we can convert it normally.
1601   Label simple_convert;
1602   BranchF(&simple_convert, NULL, lt, fd, scratch);
1603
1604   // First we subtract 2^31 from fd, then trunc it to rs
1605   // and add 2^31 to rs.
1606   sub_d(scratch, fd, scratch);
1607   trunc_w_d(scratch, scratch);
1608   mfc1(rs, scratch);
1609   Or(rs, rs, 1 << 31);
1610
1611   Label done;
1612   Branch(&done);
1613   // Simple conversion.
1614   bind(&simple_convert);
1615   trunc_w_d(scratch, fd);
1616   mfc1(rs, scratch);
1617
1618   bind(&done);
1619 }
1620
1621
1622 void MacroAssembler::Madd_d(FPURegister fd, FPURegister fr, FPURegister fs,
1623     FPURegister ft, FPURegister scratch) {
1624   if (0) {  // TODO(plind): find reasonable arch-variant symbol names.
1625     madd_d(fd, fr, fs, ft);
1626   } else {
1627     // Can not change source regs's value.
1628     DCHECK(!fr.is(scratch) && !fs.is(scratch) && !ft.is(scratch));
1629     mul_d(scratch, fs, ft);
1630     add_d(fd, fr, scratch);
1631   }
1632 }
1633
1634
1635 void MacroAssembler::BranchFCommon(SecondaryField sizeField, Label* target,
1636                                    Label* nan, Condition cond, FPURegister cmp1,
1637                                    FPURegister cmp2, BranchDelaySlot bd) {
1638   BlockTrampolinePoolScope block_trampoline_pool(this);
1639   if (cond == al) {
1640     Branch(bd, target);
1641     return;
1642   }
1643
1644   if (kArchVariant == kMips64r6) {
1645     sizeField = sizeField == D ? L : W;
1646   }
1647
1648   DCHECK(nan || target);
1649   // Check for unordered (NaN) cases.
1650   if (nan) {
1651     bool long_branch = nan->is_bound() ? is_near(nan) : is_trampoline_emitted();
1652     if (kArchVariant != kMips64r6) {
1653       if (long_branch) {
1654         Label skip;
1655         c(UN, D, cmp1, cmp2);
1656         bc1f(&skip);
1657         nop();
1658         J(nan, bd);
1659         bind(&skip);
1660       } else {
1661         c(UN, D, cmp1, cmp2);
1662         bc1t(nan);
1663         if (bd == PROTECT) {
1664           nop();
1665         }
1666       }
1667     } else {
1668       // Use kDoubleCompareReg for comparison result. It has to be unavailable
1669       // to lithium
1670       // register allocator.
1671       DCHECK(!cmp1.is(kDoubleCompareReg) && !cmp2.is(kDoubleCompareReg));
1672       if (long_branch) {
1673         Label skip;
1674         cmp(UN, L, kDoubleCompareReg, cmp1, cmp2);
1675         bc1eqz(&skip, kDoubleCompareReg);
1676         nop();
1677         J(nan, bd);
1678         bind(&skip);
1679       } else {
1680         cmp(UN, L, kDoubleCompareReg, cmp1, cmp2);
1681         bc1nez(nan, kDoubleCompareReg);
1682         if (bd == PROTECT) {
1683           nop();
1684         }
1685       }
1686     }
1687   }
1688
1689   if (target) {
1690     bool long_branch =
1691         target->is_bound() ? is_near(target) : is_trampoline_emitted();
1692     if (long_branch) {
1693       Label skip;
1694       Condition neg_cond = NegateFpuCondition(cond);
1695       BranchShortF(sizeField, &skip, neg_cond, cmp1, cmp2, bd);
1696       J(target, bd);
1697       bind(&skip);
1698     } else {
1699       BranchShortF(sizeField, target, cond, cmp1, cmp2, bd);
1700     }
1701   }
1702 }
1703
1704
1705 void MacroAssembler::BranchShortF(SecondaryField sizeField, Label* target,
1706                                   Condition cc, FPURegister cmp1,
1707                                   FPURegister cmp2, BranchDelaySlot bd) {
1708   if (kArchVariant != kMips64r6) {
1709     BlockTrampolinePoolScope block_trampoline_pool(this);
1710     if (target) {
1711       // Here NaN cases were either handled by this function or are assumed to
1712       // have been handled by the caller.
1713       switch (cc) {
1714         case lt:
1715           c(OLT, sizeField, cmp1, cmp2);
1716           bc1t(target);
1717           break;
1718         case ult:
1719           c(ULT, sizeField, cmp1, cmp2);
1720           bc1t(target);
1721           break;
1722         case gt:
1723           c(ULE, sizeField, cmp1, cmp2);
1724           bc1f(target);
1725           break;
1726         case ugt:
1727           c(OLE, sizeField, cmp1, cmp2);
1728           bc1f(target);
1729           break;
1730         case ge:
1731           c(ULT, sizeField, cmp1, cmp2);
1732           bc1f(target);
1733           break;
1734         case uge:
1735           c(OLT, sizeField, cmp1, cmp2);
1736           bc1f(target);
1737           break;
1738         case le:
1739           c(OLE, sizeField, cmp1, cmp2);
1740           bc1t(target);
1741           break;
1742         case ule:
1743           c(ULE, sizeField, cmp1, cmp2);
1744           bc1t(target);
1745           break;
1746         case eq:
1747           c(EQ, sizeField, cmp1, cmp2);
1748           bc1t(target);
1749           break;
1750         case ueq:
1751           c(UEQ, sizeField, cmp1, cmp2);
1752           bc1t(target);
1753           break;
1754         case ne:  // Unordered or not equal.
1755           c(EQ, sizeField, cmp1, cmp2);
1756           bc1f(target);
1757           break;
1758         case ogl:
1759           c(UEQ, sizeField, cmp1, cmp2);
1760           bc1f(target);
1761           break;
1762         default:
1763           CHECK(0);
1764       }
1765     }
1766   } else {
1767     BlockTrampolinePoolScope block_trampoline_pool(this);
1768     if (target) {
1769       // Here NaN cases were either handled by this function or are assumed to
1770       // have been handled by the caller.
1771       // Unsigned conditions are treated as their signed counterpart.
1772       // Use kDoubleCompareReg for comparison result, it is valid in fp64 (FR =
1773       // 1) mode.
1774       DCHECK(!cmp1.is(kDoubleCompareReg) && !cmp2.is(kDoubleCompareReg));
1775       switch (cc) {
1776         case lt:
1777           cmp(OLT, sizeField, kDoubleCompareReg, cmp1, cmp2);
1778           bc1nez(target, kDoubleCompareReg);
1779           break;
1780         case ult:
1781           cmp(ULT, sizeField, kDoubleCompareReg, cmp1, cmp2);
1782           bc1nez(target, kDoubleCompareReg);
1783           break;
1784         case gt:
1785           cmp(ULE, sizeField, kDoubleCompareReg, cmp1, cmp2);
1786           bc1eqz(target, kDoubleCompareReg);
1787           break;
1788         case ugt:
1789           cmp(OLE, sizeField, kDoubleCompareReg, cmp1, cmp2);
1790           bc1eqz(target, kDoubleCompareReg);
1791           break;
1792         case ge:
1793           cmp(ULT, sizeField, kDoubleCompareReg, cmp1, cmp2);
1794           bc1eqz(target, kDoubleCompareReg);
1795           break;
1796         case uge:
1797           cmp(OLT, sizeField, kDoubleCompareReg, cmp1, cmp2);
1798           bc1eqz(target, kDoubleCompareReg);
1799           break;
1800         case le:
1801           cmp(OLE, sizeField, kDoubleCompareReg, cmp1, cmp2);
1802           bc1nez(target, kDoubleCompareReg);
1803           break;
1804         case ule:
1805           cmp(ULE, sizeField, kDoubleCompareReg, cmp1, cmp2);
1806           bc1nez(target, kDoubleCompareReg);
1807           break;
1808         case eq:
1809           cmp(EQ, sizeField, kDoubleCompareReg, cmp1, cmp2);
1810           bc1nez(target, kDoubleCompareReg);
1811           break;
1812         case ueq:
1813           cmp(UEQ, sizeField, kDoubleCompareReg, cmp1, cmp2);
1814           bc1nez(target, kDoubleCompareReg);
1815           break;
1816         case ne:
1817           cmp(EQ, sizeField, kDoubleCompareReg, cmp1, cmp2);
1818           bc1eqz(target, kDoubleCompareReg);
1819           break;
1820         case ogl:
1821           cmp(UEQ, sizeField, kDoubleCompareReg, cmp1, cmp2);
1822           bc1eqz(target, kDoubleCompareReg);
1823           break;
1824         default:
1825           CHECK(0);
1826       }
1827     }
1828   }
1829
1830   if (bd == PROTECT) {
1831     nop();
1832   }
1833 }
1834
1835
1836 void MacroAssembler::FmoveLow(FPURegister dst, Register src_low) {
1837   DCHECK(!src_low.is(at));
1838   mfhc1(at, dst);
1839   mtc1(src_low, dst);
1840   mthc1(at, dst);
1841 }
1842
1843
1844 void MacroAssembler::Move(FPURegister dst, float imm) {
1845   li(at, Operand(bit_cast<int32_t>(imm)));
1846   mtc1(at, dst);
1847 }
1848
1849
1850 void MacroAssembler::Move(FPURegister dst, double imm) {
1851   static const DoubleRepresentation minus_zero(-0.0);
1852   static const DoubleRepresentation zero(0.0);
1853   DoubleRepresentation value_rep(imm);
1854   // Handle special values first.
1855   if (value_rep == zero && has_double_zero_reg_set_) {
1856     mov_d(dst, kDoubleRegZero);
1857   } else if (value_rep == minus_zero && has_double_zero_reg_set_) {
1858     neg_d(dst, kDoubleRegZero);
1859   } else {
1860     uint32_t lo, hi;
1861     DoubleAsTwoUInt32(imm, &lo, &hi);
1862     // Move the low part of the double into the lower bits of the corresponding
1863     // FPU register.
1864     if (lo != 0) {
1865       if (!(lo & kImm16Mask)) {
1866         lui(at, (lo >> kLuiShift) & kImm16Mask);
1867         mtc1(at, dst);
1868       } else if (!(lo & kHiMask)) {
1869         ori(at, zero_reg, lo & kImm16Mask);
1870         mtc1(at, dst);
1871       } else {
1872         lui(at, (lo >> kLuiShift) & kImm16Mask);
1873         ori(at, at, lo & kImm16Mask);
1874         mtc1(at, dst);
1875       }
1876     } else {
1877       mtc1(zero_reg, dst);
1878     }
1879     // Move the high part of the double into the high bits of the corresponding
1880     // FPU register.
1881     if (hi != 0) {
1882       if (!(hi & kImm16Mask)) {
1883         lui(at, (hi >> kLuiShift) & kImm16Mask);
1884         mthc1(at, dst);
1885       } else if (!(hi & kHiMask)) {
1886         ori(at, zero_reg, hi & kImm16Mask);
1887         mthc1(at, dst);
1888       } else {
1889         lui(at, (hi >> kLuiShift) & kImm16Mask);
1890         ori(at, at, hi & kImm16Mask);
1891         mthc1(at, dst);
1892       }
1893     } else {
1894       mthc1(zero_reg, dst);
1895     }
1896     if (dst.is(kDoubleRegZero)) has_double_zero_reg_set_ = true;
1897   }
1898 }
1899
1900
1901 void MacroAssembler::Movz(Register rd, Register rs, Register rt) {
1902   if (kArchVariant == kMips64r6) {
1903     Label done;
1904     Branch(&done, ne, rt, Operand(zero_reg));
1905     mov(rd, rs);
1906     bind(&done);
1907   } else {
1908     movz(rd, rs, rt);
1909   }
1910 }
1911
1912
1913 void MacroAssembler::Movn(Register rd, Register rs, Register rt) {
1914   if (kArchVariant == kMips64r6) {
1915     Label done;
1916     Branch(&done, eq, rt, Operand(zero_reg));
1917     mov(rd, rs);
1918     bind(&done);
1919   } else {
1920     movn(rd, rs, rt);
1921   }
1922 }
1923
1924
1925 void MacroAssembler::Movt(Register rd, Register rs, uint16_t cc) {
1926   movt(rd, rs, cc);
1927 }
1928
1929
1930 void MacroAssembler::Movf(Register rd, Register rs, uint16_t cc) {
1931   movf(rd, rs, cc);
1932 }
1933
1934
1935 void MacroAssembler::Clz(Register rd, Register rs) {
1936   clz(rd, rs);
1937 }
1938
1939
1940 void MacroAssembler::EmitFPUTruncate(FPURoundingMode rounding_mode,
1941                                      Register result,
1942                                      DoubleRegister double_input,
1943                                      Register scratch,
1944                                      DoubleRegister double_scratch,
1945                                      Register except_flag,
1946                                      CheckForInexactConversion check_inexact) {
1947   DCHECK(!result.is(scratch));
1948   DCHECK(!double_input.is(double_scratch));
1949   DCHECK(!except_flag.is(scratch));
1950
1951   Label done;
1952
1953   // Clear the except flag (0 = no exception)
1954   mov(except_flag, zero_reg);
1955
1956   // Test for values that can be exactly represented as a signed 32-bit integer.
1957   cvt_w_d(double_scratch, double_input);
1958   mfc1(result, double_scratch);
1959   cvt_d_w(double_scratch, double_scratch);
1960   BranchF(&done, NULL, eq, double_input, double_scratch);
1961
1962   int32_t except_mask = kFCSRFlagMask;  // Assume interested in all exceptions.
1963
1964   if (check_inexact == kDontCheckForInexactConversion) {
1965     // Ignore inexact exceptions.
1966     except_mask &= ~kFCSRInexactFlagMask;
1967   }
1968
1969   // Save FCSR.
1970   cfc1(scratch, FCSR);
1971   // Disable FPU exceptions.
1972   ctc1(zero_reg, FCSR);
1973
1974   // Do operation based on rounding mode.
1975   switch (rounding_mode) {
1976     case kRoundToNearest:
1977       Round_w_d(double_scratch, double_input);
1978       break;
1979     case kRoundToZero:
1980       Trunc_w_d(double_scratch, double_input);
1981       break;
1982     case kRoundToPlusInf:
1983       Ceil_w_d(double_scratch, double_input);
1984       break;
1985     case kRoundToMinusInf:
1986       Floor_w_d(double_scratch, double_input);
1987       break;
1988   }  // End of switch-statement.
1989
1990   // Retrieve FCSR.
1991   cfc1(except_flag, FCSR);
1992   // Restore FCSR.
1993   ctc1(scratch, FCSR);
1994   // Move the converted value into the result register.
1995   mfc1(result, double_scratch);
1996
1997   // Check for fpu exceptions.
1998   And(except_flag, except_flag, Operand(except_mask));
1999
2000   bind(&done);
2001 }
2002
2003
2004 void MacroAssembler::TryInlineTruncateDoubleToI(Register result,
2005                                                 DoubleRegister double_input,
2006                                                 Label* done) {
2007   DoubleRegister single_scratch = kLithiumScratchDouble.low();
2008   Register scratch = at;
2009   Register scratch2 = t9;
2010
2011   // Clear cumulative exception flags and save the FCSR.
2012   cfc1(scratch2, FCSR);
2013   ctc1(zero_reg, FCSR);
2014   // Try a conversion to a signed integer.
2015   trunc_w_d(single_scratch, double_input);
2016   mfc1(result, single_scratch);
2017   // Retrieve and restore the FCSR.
2018   cfc1(scratch, FCSR);
2019   ctc1(scratch2, FCSR);
2020   // Check for overflow and NaNs.
2021   And(scratch,
2022       scratch,
2023       kFCSROverflowFlagMask | kFCSRUnderflowFlagMask | kFCSRInvalidOpFlagMask);
2024   // If we had no exceptions we are done.
2025   Branch(done, eq, scratch, Operand(zero_reg));
2026 }
2027
2028
2029 void MacroAssembler::TruncateDoubleToI(Register result,
2030                                        DoubleRegister double_input) {
2031   Label done;
2032
2033   TryInlineTruncateDoubleToI(result, double_input, &done);
2034
2035   // If we fell through then inline version didn't succeed - call stub instead.
2036   push(ra);
2037   Dsubu(sp, sp, Operand(kDoubleSize));  // Put input on stack.
2038   sdc1(double_input, MemOperand(sp, 0));
2039
2040   DoubleToIStub stub(isolate(), sp, result, 0, true, true);
2041   CallStub(&stub);
2042
2043   Daddu(sp, sp, Operand(kDoubleSize));
2044   pop(ra);
2045
2046   bind(&done);
2047 }
2048
2049
2050 void MacroAssembler::TruncateHeapNumberToI(Register result, Register object) {
2051   Label done;
2052   DoubleRegister double_scratch = f12;
2053   DCHECK(!result.is(object));
2054
2055   ldc1(double_scratch,
2056        MemOperand(object, HeapNumber::kValueOffset - kHeapObjectTag));
2057   TryInlineTruncateDoubleToI(result, double_scratch, &done);
2058
2059   // If we fell through then inline version didn't succeed - call stub instead.
2060   push(ra);
2061   DoubleToIStub stub(isolate(),
2062                      object,
2063                      result,
2064                      HeapNumber::kValueOffset - kHeapObjectTag,
2065                      true,
2066                      true);
2067   CallStub(&stub);
2068   pop(ra);
2069
2070   bind(&done);
2071 }
2072
2073
2074 void MacroAssembler::TruncateNumberToI(Register object,
2075                                        Register result,
2076                                        Register heap_number_map,
2077                                        Register scratch,
2078                                        Label* not_number) {
2079   Label done;
2080   DCHECK(!result.is(object));
2081
2082   UntagAndJumpIfSmi(result, object, &done);
2083   JumpIfNotHeapNumber(object, heap_number_map, scratch, not_number);
2084   TruncateHeapNumberToI(result, object);
2085
2086   bind(&done);
2087 }
2088
2089
2090 void MacroAssembler::GetLeastBitsFromSmi(Register dst,
2091                                          Register src,
2092                                          int num_least_bits) {
2093   // Ext(dst, src, kSmiTagSize, num_least_bits);
2094   SmiUntag(dst, src);
2095   And(dst, dst, Operand((1 << num_least_bits) - 1));
2096 }
2097
2098
2099 void MacroAssembler::GetLeastBitsFromInt32(Register dst,
2100                                            Register src,
2101                                            int num_least_bits) {
2102   DCHECK(!src.is(dst));
2103   And(dst, src, Operand((1 << num_least_bits) - 1));
2104 }
2105
2106
2107 // Emulated condtional branches do not emit a nop in the branch delay slot.
2108 //
2109 // BRANCH_ARGS_CHECK checks that conditional jump arguments are correct.
2110 #define BRANCH_ARGS_CHECK(cond, rs, rt) DCHECK(                                \
2111     (cond == cc_always && rs.is(zero_reg) && rt.rm().is(zero_reg)) ||          \
2112     (cond != cc_always && (!rs.is(zero_reg) || !rt.rm().is(zero_reg))))
2113
2114
2115 void MacroAssembler::Branch(int16_t offset, BranchDelaySlot bdslot) {
2116   BranchShort(offset, bdslot);
2117 }
2118
2119
2120 void MacroAssembler::Branch(int16_t offset, Condition cond, Register rs,
2121                             const Operand& rt,
2122                             BranchDelaySlot bdslot) {
2123   BranchShort(offset, cond, rs, rt, bdslot);
2124 }
2125
2126
2127 void MacroAssembler::Branch(Label* L, BranchDelaySlot bdslot) {
2128   if (L->is_bound()) {
2129     if (is_near(L)) {
2130       BranchShort(L, bdslot);
2131     } else {
2132       J(L, bdslot);
2133     }
2134   } else {
2135     if (is_trampoline_emitted()) {
2136       J(L, bdslot);
2137     } else {
2138       BranchShort(L, bdslot);
2139     }
2140   }
2141 }
2142
2143
2144 void MacroAssembler::Branch(Label* L, Condition cond, Register rs,
2145                             const Operand& rt,
2146                             BranchDelaySlot bdslot) {
2147   if (L->is_bound()) {
2148     if (is_near(L)) {
2149       BranchShort(L, cond, rs, rt, bdslot);
2150     } else {
2151       if (cond != cc_always) {
2152         Label skip;
2153         Condition neg_cond = NegateCondition(cond);
2154         BranchShort(&skip, neg_cond, rs, rt);
2155         J(L, bdslot);
2156         bind(&skip);
2157       } else {
2158         J(L, bdslot);
2159       }
2160     }
2161   } else {
2162     if (is_trampoline_emitted()) {
2163       if (cond != cc_always) {
2164         Label skip;
2165         Condition neg_cond = NegateCondition(cond);
2166         BranchShort(&skip, neg_cond, rs, rt);
2167         J(L, bdslot);
2168         bind(&skip);
2169       } else {
2170         J(L, bdslot);
2171       }
2172     } else {
2173       BranchShort(L, cond, rs, rt, bdslot);
2174     }
2175   }
2176 }
2177
2178
2179 void MacroAssembler::Branch(Label* L,
2180                             Condition cond,
2181                             Register rs,
2182                             Heap::RootListIndex index,
2183                             BranchDelaySlot bdslot) {
2184   LoadRoot(at, index);
2185   Branch(L, cond, rs, Operand(at), bdslot);
2186 }
2187
2188
2189 void MacroAssembler::BranchShort(int16_t offset, BranchDelaySlot bdslot) {
2190   b(offset);
2191
2192   // Emit a nop in the branch delay slot if required.
2193   if (bdslot == PROTECT)
2194     nop();
2195 }
2196
2197
2198 void MacroAssembler::BranchShort(int16_t offset, Condition cond, Register rs,
2199                                  const Operand& rt,
2200                                  BranchDelaySlot bdslot) {
2201   BRANCH_ARGS_CHECK(cond, rs, rt);
2202   DCHECK(!rs.is(zero_reg));
2203   Register r2 = no_reg;
2204   Register scratch = at;
2205
2206   if (rt.is_reg()) {
2207     // NOTE: 'at' can be clobbered by Branch but it is legal to use it as rs or
2208     // rt.
2209     BlockTrampolinePoolScope block_trampoline_pool(this);
2210     r2 = rt.rm_;
2211     switch (cond) {
2212       case cc_always:
2213         b(offset);
2214         break;
2215       case eq:
2216         beq(rs, r2, offset);
2217         break;
2218       case ne:
2219         bne(rs, r2, offset);
2220         break;
2221       // Signed comparison.
2222       case greater:
2223         if (r2.is(zero_reg)) {
2224           bgtz(rs, offset);
2225         } else {
2226           slt(scratch, r2, rs);
2227           bne(scratch, zero_reg, offset);
2228         }
2229         break;
2230       case greater_equal:
2231         if (r2.is(zero_reg)) {
2232           bgez(rs, offset);
2233         } else {
2234           slt(scratch, rs, r2);
2235           beq(scratch, zero_reg, offset);
2236         }
2237         break;
2238       case less:
2239         if (r2.is(zero_reg)) {
2240           bltz(rs, offset);
2241         } else {
2242           slt(scratch, rs, r2);
2243           bne(scratch, zero_reg, offset);
2244         }
2245         break;
2246       case less_equal:
2247         if (r2.is(zero_reg)) {
2248           blez(rs, offset);
2249         } else {
2250           slt(scratch, r2, rs);
2251           beq(scratch, zero_reg, offset);
2252         }
2253         break;
2254       // Unsigned comparison.
2255       case Ugreater:
2256         if (r2.is(zero_reg)) {
2257           bne(rs, zero_reg, offset);
2258         } else {
2259           sltu(scratch, r2, rs);
2260           bne(scratch, zero_reg, offset);
2261         }
2262         break;
2263       case Ugreater_equal:
2264         if (r2.is(zero_reg)) {
2265           b(offset);
2266         } else {
2267           sltu(scratch, rs, r2);
2268           beq(scratch, zero_reg, offset);
2269         }
2270         break;
2271       case Uless:
2272         if (r2.is(zero_reg)) {
2273           // No code needs to be emitted.
2274           return;
2275         } else {
2276           sltu(scratch, rs, r2);
2277           bne(scratch, zero_reg, offset);
2278         }
2279         break;
2280       case Uless_equal:
2281         if (r2.is(zero_reg)) {
2282           beq(rs, zero_reg, offset);
2283         } else {
2284           sltu(scratch, r2, rs);
2285           beq(scratch, zero_reg, offset);
2286         }
2287         break;
2288       default:
2289         UNREACHABLE();
2290     }
2291   } else {
2292     // Be careful to always use shifted_branch_offset only just before the
2293     // branch instruction, as the location will be remember for patching the
2294     // target.
2295     BlockTrampolinePoolScope block_trampoline_pool(this);
2296     switch (cond) {
2297       case cc_always:
2298         b(offset);
2299         break;
2300       case eq:
2301         if (rt.imm64_ == 0) {
2302           beq(rs, zero_reg, offset);
2303         } else {
2304           // We don't want any other register but scratch clobbered.
2305           DCHECK(!scratch.is(rs));
2306           r2 = scratch;
2307           li(r2, rt);
2308           beq(rs, r2, offset);
2309         }
2310         break;
2311       case ne:
2312         if (rt.imm64_ == 0) {
2313           bne(rs, zero_reg, offset);
2314         } else {
2315           // We don't want any other register but scratch clobbered.
2316           DCHECK(!scratch.is(rs));
2317           r2 = scratch;
2318           li(r2, rt);
2319           bne(rs, r2, offset);
2320         }
2321         break;
2322       // Signed comparison.
2323       case greater:
2324         if (rt.imm64_ == 0) {
2325           bgtz(rs, offset);
2326         } else {
2327           r2 = scratch;
2328           li(r2, rt);
2329           slt(scratch, r2, rs);
2330           bne(scratch, zero_reg, offset);
2331         }
2332         break;
2333       case greater_equal:
2334         if (rt.imm64_ == 0) {
2335           bgez(rs, offset);
2336         } else if (is_int16(rt.imm64_)) {
2337           slti(scratch, rs, static_cast<int32_t>(rt.imm64_));
2338           beq(scratch, zero_reg, offset);
2339         } else {
2340           r2 = scratch;
2341           li(r2, rt);
2342           slt(scratch, rs, r2);
2343           beq(scratch, zero_reg, offset);
2344         }
2345         break;
2346       case less:
2347         if (rt.imm64_ == 0) {
2348           bltz(rs, offset);
2349         } else if (is_int16(rt.imm64_)) {
2350           slti(scratch, rs, static_cast<int32_t>(rt.imm64_));
2351           bne(scratch, zero_reg, offset);
2352         } else {
2353           r2 = scratch;
2354           li(r2, rt);
2355           slt(scratch, rs, r2);
2356           bne(scratch, zero_reg, offset);
2357         }
2358         break;
2359       case less_equal:
2360         if (rt.imm64_ == 0) {
2361           blez(rs, offset);
2362         } else {
2363           r2 = scratch;
2364           li(r2, rt);
2365           slt(scratch, r2, rs);
2366           beq(scratch, zero_reg, offset);
2367        }
2368        break;
2369       // Unsigned comparison.
2370       case Ugreater:
2371         if (rt.imm64_ == 0) {
2372           bne(rs, zero_reg, offset);
2373         } else {
2374           r2 = scratch;
2375           li(r2, rt);
2376           sltu(scratch, r2, rs);
2377           bne(scratch, zero_reg, offset);
2378         }
2379         break;
2380       case Ugreater_equal:
2381         if (rt.imm64_ == 0) {
2382           b(offset);
2383         } else if (is_int16(rt.imm64_)) {
2384           sltiu(scratch, rs, static_cast<int32_t>(rt.imm64_));
2385           beq(scratch, zero_reg, offset);
2386         } else {
2387           r2 = scratch;
2388           li(r2, rt);
2389           sltu(scratch, rs, r2);
2390           beq(scratch, zero_reg, offset);
2391         }
2392         break;
2393       case Uless:
2394         if (rt.imm64_ == 0) {
2395           // No code needs to be emitted.
2396           return;
2397         } else if (is_int16(rt.imm64_)) {
2398           sltiu(scratch, rs, static_cast<int32_t>(rt.imm64_));
2399           bne(scratch, zero_reg, offset);
2400         } else {
2401           r2 = scratch;
2402           li(r2, rt);
2403           sltu(scratch, rs, r2);
2404           bne(scratch, zero_reg, offset);
2405         }
2406         break;
2407       case Uless_equal:
2408         if (rt.imm64_ == 0) {
2409           beq(rs, zero_reg, offset);
2410         } else {
2411           r2 = scratch;
2412           li(r2, rt);
2413           sltu(scratch, r2, rs);
2414           beq(scratch, zero_reg, offset);
2415         }
2416         break;
2417       default:
2418         UNREACHABLE();
2419     }
2420   }
2421   // Emit a nop in the branch delay slot if required.
2422   if (bdslot == PROTECT)
2423     nop();
2424 }
2425
2426
2427 void MacroAssembler::BranchShort(Label* L, BranchDelaySlot bdslot) {
2428   // We use branch_offset as an argument for the branch instructions to be sure
2429   // it is called just before generating the branch instruction, as needed.
2430
2431   b(shifted_branch_offset(L, false));
2432
2433   // Emit a nop in the branch delay slot if required.
2434   if (bdslot == PROTECT)
2435     nop();
2436 }
2437
2438
2439 void MacroAssembler::BranchShort(Label* L, Condition cond, Register rs,
2440                                  const Operand& rt,
2441                                  BranchDelaySlot bdslot) {
2442   BRANCH_ARGS_CHECK(cond, rs, rt);
2443
2444   int32_t offset = 0;
2445   Register r2 = no_reg;
2446   Register scratch = at;
2447   if (rt.is_reg()) {
2448     BlockTrampolinePoolScope block_trampoline_pool(this);
2449     r2 = rt.rm_;
2450     // Be careful to always use shifted_branch_offset only just before the
2451     // branch instruction, as the location will be remember for patching the
2452     // target.
2453     switch (cond) {
2454       case cc_always:
2455         offset = shifted_branch_offset(L, false);
2456         b(offset);
2457         break;
2458       case eq:
2459         offset = shifted_branch_offset(L, false);
2460         beq(rs, r2, offset);
2461         break;
2462       case ne:
2463         offset = shifted_branch_offset(L, false);
2464         bne(rs, r2, offset);
2465         break;
2466       // Signed comparison.
2467       case greater:
2468         if (r2.is(zero_reg)) {
2469           offset = shifted_branch_offset(L, false);
2470           bgtz(rs, offset);
2471         } else {
2472           slt(scratch, r2, rs);
2473           offset = shifted_branch_offset(L, false);
2474           bne(scratch, zero_reg, offset);
2475         }
2476         break;
2477       case greater_equal:
2478         if (r2.is(zero_reg)) {
2479           offset = shifted_branch_offset(L, false);
2480           bgez(rs, offset);
2481         } else {
2482           slt(scratch, rs, r2);
2483           offset = shifted_branch_offset(L, false);
2484           beq(scratch, zero_reg, offset);
2485         }
2486         break;
2487       case less:
2488         if (r2.is(zero_reg)) {
2489           offset = shifted_branch_offset(L, false);
2490           bltz(rs, offset);
2491         } else {
2492           slt(scratch, rs, r2);
2493           offset = shifted_branch_offset(L, false);
2494           bne(scratch, zero_reg, offset);
2495         }
2496         break;
2497       case less_equal:
2498         if (r2.is(zero_reg)) {
2499           offset = shifted_branch_offset(L, false);
2500           blez(rs, offset);
2501         } else {
2502           slt(scratch, r2, rs);
2503           offset = shifted_branch_offset(L, false);
2504           beq(scratch, zero_reg, offset);
2505         }
2506         break;
2507       // Unsigned comparison.
2508       case Ugreater:
2509         if (r2.is(zero_reg)) {
2510           offset = shifted_branch_offset(L, false);
2511           bne(rs, zero_reg, offset);
2512         } else {
2513           sltu(scratch, r2, rs);
2514           offset = shifted_branch_offset(L, false);
2515           bne(scratch, zero_reg, offset);
2516         }
2517         break;
2518       case Ugreater_equal:
2519         if (r2.is(zero_reg)) {
2520           offset = shifted_branch_offset(L, false);
2521           b(offset);
2522         } else {
2523           sltu(scratch, rs, r2);
2524           offset = shifted_branch_offset(L, false);
2525           beq(scratch, zero_reg, offset);
2526         }
2527         break;
2528       case Uless:
2529         if (r2.is(zero_reg)) {
2530           // No code needs to be emitted.
2531           return;
2532         } else {
2533           sltu(scratch, rs, r2);
2534           offset = shifted_branch_offset(L, false);
2535           bne(scratch, zero_reg, offset);
2536         }
2537         break;
2538       case Uless_equal:
2539         if (r2.is(zero_reg)) {
2540           offset = shifted_branch_offset(L, false);
2541           beq(rs, zero_reg, offset);
2542         } else {
2543           sltu(scratch, r2, rs);
2544           offset = shifted_branch_offset(L, false);
2545           beq(scratch, zero_reg, offset);
2546         }
2547         break;
2548       default:
2549         UNREACHABLE();
2550     }
2551   } else {
2552     // Be careful to always use shifted_branch_offset only just before the
2553     // branch instruction, as the location will be remember for patching the
2554     // target.
2555     BlockTrampolinePoolScope block_trampoline_pool(this);
2556     switch (cond) {
2557       case cc_always:
2558         offset = shifted_branch_offset(L, false);
2559         b(offset);
2560         break;
2561       case eq:
2562         if (rt.imm64_ == 0) {
2563           offset = shifted_branch_offset(L, false);
2564           beq(rs, zero_reg, offset);
2565         } else {
2566           DCHECK(!scratch.is(rs));
2567           r2 = scratch;
2568           li(r2, rt);
2569           offset = shifted_branch_offset(L, false);
2570           beq(rs, r2, offset);
2571         }
2572         break;
2573       case ne:
2574         if (rt.imm64_ == 0) {
2575           offset = shifted_branch_offset(L, false);
2576           bne(rs, zero_reg, offset);
2577         } else {
2578           DCHECK(!scratch.is(rs));
2579           r2 = scratch;
2580           li(r2, rt);
2581           offset = shifted_branch_offset(L, false);
2582           bne(rs, r2, offset);
2583         }
2584         break;
2585       // Signed comparison.
2586       case greater:
2587         if (rt.imm64_ == 0) {
2588           offset = shifted_branch_offset(L, false);
2589           bgtz(rs, offset);
2590         } else {
2591           DCHECK(!scratch.is(rs));
2592           r2 = scratch;
2593           li(r2, rt);
2594           slt(scratch, r2, rs);
2595           offset = shifted_branch_offset(L, false);
2596           bne(scratch, zero_reg, offset);
2597         }
2598         break;
2599       case greater_equal:
2600         if (rt.imm64_ == 0) {
2601           offset = shifted_branch_offset(L, false);
2602           bgez(rs, offset);
2603         } else if (is_int16(rt.imm64_)) {
2604           slti(scratch, rs, static_cast<int32_t>(rt.imm64_));
2605           offset = shifted_branch_offset(L, false);
2606           beq(scratch, zero_reg, offset);
2607         } else {
2608           DCHECK(!scratch.is(rs));
2609           r2 = scratch;
2610           li(r2, rt);
2611           slt(scratch, rs, r2);
2612           offset = shifted_branch_offset(L, false);
2613           beq(scratch, zero_reg, offset);
2614         }
2615         break;
2616       case less:
2617         if (rt.imm64_ == 0) {
2618           offset = shifted_branch_offset(L, false);
2619           bltz(rs, offset);
2620         } else if (is_int16(rt.imm64_)) {
2621           slti(scratch, rs, static_cast<int32_t>(rt.imm64_));
2622           offset = shifted_branch_offset(L, false);
2623           bne(scratch, zero_reg, offset);
2624         } else {
2625           DCHECK(!scratch.is(rs));
2626           r2 = scratch;
2627           li(r2, rt);
2628           slt(scratch, rs, r2);
2629           offset = shifted_branch_offset(L, false);
2630           bne(scratch, zero_reg, offset);
2631         }
2632         break;
2633       case less_equal:
2634         if (rt.imm64_ == 0) {
2635           offset = shifted_branch_offset(L, false);
2636           blez(rs, offset);
2637         } else {
2638           DCHECK(!scratch.is(rs));
2639           r2 = scratch;
2640           li(r2, rt);
2641           slt(scratch, r2, rs);
2642           offset = shifted_branch_offset(L, false);
2643           beq(scratch, zero_reg, offset);
2644         }
2645         break;
2646       // Unsigned comparison.
2647       case Ugreater:
2648         if (rt.imm64_ == 0) {
2649           offset = shifted_branch_offset(L, false);
2650           bne(rs, zero_reg, offset);
2651         } else {
2652           DCHECK(!scratch.is(rs));
2653           r2 = scratch;
2654           li(r2, rt);
2655           sltu(scratch, r2, rs);
2656           offset = shifted_branch_offset(L, false);
2657           bne(scratch, zero_reg, offset);
2658         }
2659         break;
2660       case Ugreater_equal:
2661         if (rt.imm64_ == 0) {
2662           offset = shifted_branch_offset(L, false);
2663           b(offset);
2664         } else if (is_int16(rt.imm64_)) {
2665           sltiu(scratch, rs, static_cast<int32_t>(rt.imm64_));
2666           offset = shifted_branch_offset(L, false);
2667           beq(scratch, zero_reg, offset);
2668         } else {
2669           DCHECK(!scratch.is(rs));
2670           r2 = scratch;
2671           li(r2, rt);
2672           sltu(scratch, rs, r2);
2673           offset = shifted_branch_offset(L, false);
2674           beq(scratch, zero_reg, offset);
2675         }
2676         break;
2677      case Uless:
2678         if (rt.imm64_ == 0) {
2679           // No code needs to be emitted.
2680           return;
2681         } else if (is_int16(rt.imm64_)) {
2682           sltiu(scratch, rs, static_cast<int32_t>(rt.imm64_));
2683           offset = shifted_branch_offset(L, false);
2684           bne(scratch, zero_reg, offset);
2685         } else {
2686           DCHECK(!scratch.is(rs));
2687           r2 = scratch;
2688           li(r2, rt);
2689           sltu(scratch, rs, r2);
2690           offset = shifted_branch_offset(L, false);
2691           bne(scratch, zero_reg, offset);
2692         }
2693         break;
2694       case Uless_equal:
2695         if (rt.imm64_ == 0) {
2696           offset = shifted_branch_offset(L, false);
2697           beq(rs, zero_reg, offset);
2698         } else {
2699           DCHECK(!scratch.is(rs));
2700           r2 = scratch;
2701           li(r2, rt);
2702           sltu(scratch, r2, rs);
2703           offset = shifted_branch_offset(L, false);
2704           beq(scratch, zero_reg, offset);
2705         }
2706         break;
2707       default:
2708         UNREACHABLE();
2709     }
2710   }
2711   // Check that offset could actually hold on an int16_t.
2712   DCHECK(is_int16(offset));
2713   // Emit a nop in the branch delay slot if required.
2714   if (bdslot == PROTECT)
2715     nop();
2716 }
2717
2718
2719 void MacroAssembler::BranchAndLink(int16_t offset, BranchDelaySlot bdslot) {
2720   BranchAndLinkShort(offset, bdslot);
2721 }
2722
2723
2724 void MacroAssembler::BranchAndLink(int16_t offset, Condition cond, Register rs,
2725                                    const Operand& rt,
2726                                    BranchDelaySlot bdslot) {
2727   BranchAndLinkShort(offset, cond, rs, rt, bdslot);
2728 }
2729
2730
2731 void MacroAssembler::BranchAndLink(Label* L, BranchDelaySlot bdslot) {
2732   if (L->is_bound()) {
2733     if (is_near(L)) {
2734       BranchAndLinkShort(L, bdslot);
2735     } else {
2736       Jal(L, bdslot);
2737     }
2738   } else {
2739     if (is_trampoline_emitted()) {
2740       Jal(L, bdslot);
2741     } else {
2742       BranchAndLinkShort(L, bdslot);
2743     }
2744   }
2745 }
2746
2747
2748 void MacroAssembler::BranchAndLink(Label* L, Condition cond, Register rs,
2749                                    const Operand& rt,
2750                                    BranchDelaySlot bdslot) {
2751   if (L->is_bound()) {
2752     if (is_near(L)) {
2753       BranchAndLinkShort(L, cond, rs, rt, bdslot);
2754     } else {
2755       Label skip;
2756       Condition neg_cond = NegateCondition(cond);
2757       BranchShort(&skip, neg_cond, rs, rt);
2758       Jal(L, bdslot);
2759       bind(&skip);
2760     }
2761   } else {
2762     if (is_trampoline_emitted()) {
2763       Label skip;
2764       Condition neg_cond = NegateCondition(cond);
2765       BranchShort(&skip, neg_cond, rs, rt);
2766       Jal(L, bdslot);
2767       bind(&skip);
2768     } else {
2769       BranchAndLinkShort(L, cond, rs, rt, bdslot);
2770     }
2771   }
2772 }
2773
2774
2775 // We need to use a bgezal or bltzal, but they can't be used directly with the
2776 // slt instructions. We could use sub or add instead but we would miss overflow
2777 // cases, so we keep slt and add an intermediate third instruction.
2778 void MacroAssembler::BranchAndLinkShort(int16_t offset,
2779                                         BranchDelaySlot bdslot) {
2780   bal(offset);
2781
2782   // Emit a nop in the branch delay slot if required.
2783   if (bdslot == PROTECT)
2784     nop();
2785 }
2786
2787
2788 void MacroAssembler::BranchAndLinkShort(int16_t offset, Condition cond,
2789                                         Register rs, const Operand& rt,
2790                                         BranchDelaySlot bdslot) {
2791   BRANCH_ARGS_CHECK(cond, rs, rt);
2792   Register r2 = no_reg;
2793   Register scratch = at;
2794
2795   if (rt.is_reg()) {
2796     r2 = rt.rm_;
2797   } else if (cond != cc_always) {
2798     r2 = scratch;
2799     li(r2, rt);
2800   }
2801
2802   {
2803     BlockTrampolinePoolScope block_trampoline_pool(this);
2804     switch (cond) {
2805       case cc_always:
2806         bal(offset);
2807         break;
2808       case eq:
2809         bne(rs, r2, 2);
2810         nop();
2811         bal(offset);
2812         break;
2813       case ne:
2814         beq(rs, r2, 2);
2815         nop();
2816         bal(offset);
2817         break;
2818
2819       // Signed comparison.
2820       case greater:
2821         // rs > rt
2822         slt(scratch, r2, rs);
2823         beq(scratch, zero_reg, 2);
2824         nop();
2825         bal(offset);
2826         break;
2827       case greater_equal:
2828         // rs >= rt
2829         slt(scratch, rs, r2);
2830         bne(scratch, zero_reg, 2);
2831         nop();
2832         bal(offset);
2833         break;
2834       case less:
2835         // rs < r2
2836         slt(scratch, rs, r2);
2837         bne(scratch, zero_reg, 2);
2838         nop();
2839         bal(offset);
2840         break;
2841       case less_equal:
2842         // rs <= r2
2843         slt(scratch, r2, rs);
2844         bne(scratch, zero_reg, 2);
2845         nop();
2846         bal(offset);
2847         break;
2848
2849
2850       // Unsigned comparison.
2851       case Ugreater:
2852         // rs > rt
2853         sltu(scratch, r2, rs);
2854         beq(scratch, zero_reg, 2);
2855         nop();
2856         bal(offset);
2857         break;
2858       case Ugreater_equal:
2859         // rs >= rt
2860         sltu(scratch, rs, r2);
2861         bne(scratch, zero_reg, 2);
2862         nop();
2863         bal(offset);
2864         break;
2865       case Uless:
2866         // rs < r2
2867         sltu(scratch, rs, r2);
2868         bne(scratch, zero_reg, 2);
2869         nop();
2870         bal(offset);
2871         break;
2872       case Uless_equal:
2873         // rs <= r2
2874         sltu(scratch, r2, rs);
2875         bne(scratch, zero_reg, 2);
2876         nop();
2877         bal(offset);
2878         break;
2879       default:
2880         UNREACHABLE();
2881     }
2882   }
2883   // Emit a nop in the branch delay slot if required.
2884   if (bdslot == PROTECT)
2885     nop();
2886 }
2887
2888
2889 void MacroAssembler::BranchAndLinkShort(Label* L, BranchDelaySlot bdslot) {
2890   bal(shifted_branch_offset(L, false));
2891
2892   // Emit a nop in the branch delay slot if required.
2893   if (bdslot == PROTECT)
2894     nop();
2895 }
2896
2897
2898 void MacroAssembler::BranchAndLinkShort(Label* L, Condition cond, Register rs,
2899                                         const Operand& rt,
2900                                         BranchDelaySlot bdslot) {
2901   BRANCH_ARGS_CHECK(cond, rs, rt);
2902
2903   int32_t offset = 0;
2904   Register r2 = no_reg;
2905   Register scratch = at;
2906   if (rt.is_reg()) {
2907     r2 = rt.rm_;
2908   } else if (cond != cc_always) {
2909     r2 = scratch;
2910     li(r2, rt);
2911   }
2912
2913   {
2914     BlockTrampolinePoolScope block_trampoline_pool(this);
2915     switch (cond) {
2916       case cc_always:
2917         offset = shifted_branch_offset(L, false);
2918         bal(offset);
2919         break;
2920       case eq:
2921         bne(rs, r2, 2);
2922         nop();
2923         offset = shifted_branch_offset(L, false);
2924         bal(offset);
2925         break;
2926       case ne:
2927         beq(rs, r2, 2);
2928         nop();
2929         offset = shifted_branch_offset(L, false);
2930         bal(offset);
2931         break;
2932
2933       // Signed comparison.
2934       case greater:
2935         // rs > rt
2936         slt(scratch, r2, rs);
2937         beq(scratch, zero_reg, 2);
2938         nop();
2939         offset = shifted_branch_offset(L, false);
2940         bal(offset);
2941         break;
2942       case greater_equal:
2943         // rs >= rt
2944         slt(scratch, rs, r2);
2945         bne(scratch, zero_reg, 2);
2946         nop();
2947         offset = shifted_branch_offset(L, false);
2948         bal(offset);
2949         break;
2950       case less:
2951         // rs < r2
2952         slt(scratch, rs, r2);
2953         bne(scratch, zero_reg, 2);
2954         nop();
2955         offset = shifted_branch_offset(L, false);
2956         bal(offset);
2957         break;
2958       case less_equal:
2959         // rs <= r2
2960         slt(scratch, r2, rs);
2961         bne(scratch, zero_reg, 2);
2962         nop();
2963         offset = shifted_branch_offset(L, false);
2964         bal(offset);
2965         break;
2966
2967
2968       // Unsigned comparison.
2969       case Ugreater:
2970         // rs > rt
2971         sltu(scratch, r2, rs);
2972         beq(scratch, zero_reg, 2);
2973         nop();
2974         offset = shifted_branch_offset(L, false);
2975         bal(offset);
2976         break;
2977       case Ugreater_equal:
2978         // rs >= rt
2979         sltu(scratch, rs, r2);
2980         bne(scratch, zero_reg, 2);
2981         nop();
2982         offset = shifted_branch_offset(L, false);
2983         bal(offset);
2984         break;
2985       case Uless:
2986         // rs < r2
2987         sltu(scratch, rs, r2);
2988         bne(scratch, zero_reg, 2);
2989         nop();
2990         offset = shifted_branch_offset(L, false);
2991         bal(offset);
2992         break;
2993       case Uless_equal:
2994         // rs <= r2
2995         sltu(scratch, r2, rs);
2996         bne(scratch, zero_reg, 2);
2997         nop();
2998         offset = shifted_branch_offset(L, false);
2999         bal(offset);
3000         break;
3001
3002       default:
3003         UNREACHABLE();
3004     }
3005   }
3006   // Check that offset could actually hold on an int16_t.
3007   DCHECK(is_int16(offset));
3008
3009   // Emit a nop in the branch delay slot if required.
3010   if (bdslot == PROTECT)
3011     nop();
3012 }
3013
3014
3015 void MacroAssembler::Jump(Register target,
3016                           Condition cond,
3017                           Register rs,
3018                           const Operand& rt,
3019                           BranchDelaySlot bd) {
3020   BlockTrampolinePoolScope block_trampoline_pool(this);
3021   if (cond == cc_always) {
3022     jr(target);
3023   } else {
3024     BRANCH_ARGS_CHECK(cond, rs, rt);
3025     Branch(2, NegateCondition(cond), rs, rt);
3026     jr(target);
3027   }
3028   // Emit a nop in the branch delay slot if required.
3029   if (bd == PROTECT)
3030     nop();
3031 }
3032
3033
3034 void MacroAssembler::Jump(intptr_t target,
3035                           RelocInfo::Mode rmode,
3036                           Condition cond,
3037                           Register rs,
3038                           const Operand& rt,
3039                           BranchDelaySlot bd) {
3040   Label skip;
3041   if (cond != cc_always) {
3042     Branch(USE_DELAY_SLOT, &skip, NegateCondition(cond), rs, rt);
3043   }
3044   // The first instruction of 'li' may be placed in the delay slot.
3045   // This is not an issue, t9 is expected to be clobbered anyway.
3046   li(t9, Operand(target, rmode));
3047   Jump(t9, al, zero_reg, Operand(zero_reg), bd);
3048   bind(&skip);
3049 }
3050
3051
3052 void MacroAssembler::Jump(Address target,
3053                           RelocInfo::Mode rmode,
3054                           Condition cond,
3055                           Register rs,
3056                           const Operand& rt,
3057                           BranchDelaySlot bd) {
3058   DCHECK(!RelocInfo::IsCodeTarget(rmode));
3059   Jump(reinterpret_cast<intptr_t>(target), rmode, cond, rs, rt, bd);
3060 }
3061
3062
3063 void MacroAssembler::Jump(Handle<Code> code,
3064                           RelocInfo::Mode rmode,
3065                           Condition cond,
3066                           Register rs,
3067                           const Operand& rt,
3068                           BranchDelaySlot bd) {
3069   DCHECK(RelocInfo::IsCodeTarget(rmode));
3070   AllowDeferredHandleDereference embedding_raw_address;
3071   Jump(reinterpret_cast<intptr_t>(code.location()), rmode, cond, rs, rt, bd);
3072 }
3073
3074
3075 int MacroAssembler::CallSize(Register target,
3076                              Condition cond,
3077                              Register rs,
3078                              const Operand& rt,
3079                              BranchDelaySlot bd) {
3080   int size = 0;
3081
3082   if (cond == cc_always) {
3083     size += 1;
3084   } else {
3085     size += 3;
3086   }
3087
3088   if (bd == PROTECT)
3089     size += 1;
3090
3091   return size * kInstrSize;
3092 }
3093
3094
3095 // Note: To call gcc-compiled C code on mips, you must call thru t9.
3096 void MacroAssembler::Call(Register target,
3097                           Condition cond,
3098                           Register rs,
3099                           const Operand& rt,
3100                           BranchDelaySlot bd) {
3101   BlockTrampolinePoolScope block_trampoline_pool(this);
3102   Label start;
3103   bind(&start);
3104   if (cond == cc_always) {
3105     jalr(target);
3106   } else {
3107     BRANCH_ARGS_CHECK(cond, rs, rt);
3108     Branch(2, NegateCondition(cond), rs, rt);
3109     jalr(target);
3110   }
3111   // Emit a nop in the branch delay slot if required.
3112   if (bd == PROTECT)
3113     nop();
3114
3115   DCHECK_EQ(CallSize(target, cond, rs, rt, bd),
3116             SizeOfCodeGeneratedSince(&start));
3117 }
3118
3119
3120 int MacroAssembler::CallSize(Address target,
3121                              RelocInfo::Mode rmode,
3122                              Condition cond,
3123                              Register rs,
3124                              const Operand& rt,
3125                              BranchDelaySlot bd) {
3126   int size = CallSize(t9, cond, rs, rt, bd);
3127   return size + 4 * kInstrSize;
3128 }
3129
3130
3131 void MacroAssembler::Call(Address target,
3132                           RelocInfo::Mode rmode,
3133                           Condition cond,
3134                           Register rs,
3135                           const Operand& rt,
3136                           BranchDelaySlot bd) {
3137   BlockTrampolinePoolScope block_trampoline_pool(this);
3138   Label start;
3139   bind(&start);
3140   int64_t target_int = reinterpret_cast<int64_t>(target);
3141   // Must record previous source positions before the
3142   // li() generates a new code target.
3143   positions_recorder()->WriteRecordedPositions();
3144   li(t9, Operand(target_int, rmode), ADDRESS_LOAD);
3145   Call(t9, cond, rs, rt, bd);
3146   DCHECK_EQ(CallSize(target, rmode, cond, rs, rt, bd),
3147             SizeOfCodeGeneratedSince(&start));
3148 }
3149
3150
3151 int MacroAssembler::CallSize(Handle<Code> code,
3152                              RelocInfo::Mode rmode,
3153                              TypeFeedbackId ast_id,
3154                              Condition cond,
3155                              Register rs,
3156                              const Operand& rt,
3157                              BranchDelaySlot bd) {
3158   AllowDeferredHandleDereference using_raw_address;
3159   return CallSize(reinterpret_cast<Address>(code.location()),
3160       rmode, cond, rs, rt, bd);
3161 }
3162
3163
3164 void MacroAssembler::Call(Handle<Code> code,
3165                           RelocInfo::Mode rmode,
3166                           TypeFeedbackId ast_id,
3167                           Condition cond,
3168                           Register rs,
3169                           const Operand& rt,
3170                           BranchDelaySlot bd) {
3171   BlockTrampolinePoolScope block_trampoline_pool(this);
3172   Label start;
3173   bind(&start);
3174   DCHECK(RelocInfo::IsCodeTarget(rmode));
3175   if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) {
3176     SetRecordedAstId(ast_id);
3177     rmode = RelocInfo::CODE_TARGET_WITH_ID;
3178   }
3179   AllowDeferredHandleDereference embedding_raw_address;
3180   Call(reinterpret_cast<Address>(code.location()), rmode, cond, rs, rt, bd);
3181   DCHECK_EQ(CallSize(code, rmode, ast_id, cond, rs, rt, bd),
3182             SizeOfCodeGeneratedSince(&start));
3183 }
3184
3185
3186 void MacroAssembler::Ret(Condition cond,
3187                          Register rs,
3188                          const Operand& rt,
3189                          BranchDelaySlot bd) {
3190   Jump(ra, cond, rs, rt, bd);
3191 }
3192
3193
3194 void MacroAssembler::J(Label* L, BranchDelaySlot bdslot) {
3195   BlockTrampolinePoolScope block_trampoline_pool(this);
3196   {
3197     BlockGrowBufferScope block_buf_growth(this);
3198     // Buffer growth (and relocation) must be blocked for internal references
3199     // until associated instructions are emitted and available to be patched.
3200     RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
3201     j(L);
3202   }
3203   // Emit a nop in the branch delay slot if required.
3204   if (bdslot == PROTECT) nop();
3205 }
3206
3207
3208 void MacroAssembler::Jal(Label* L, BranchDelaySlot bdslot) {
3209   BlockTrampolinePoolScope block_trampoline_pool(this);
3210   {
3211     BlockGrowBufferScope block_buf_growth(this);
3212     // Buffer growth (and relocation) must be blocked for internal references
3213     // until associated instructions are emitted and available to be patched.
3214     RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
3215     jal(L);
3216   }
3217   // Emit a nop in the branch delay slot if required.
3218   if (bdslot == PROTECT) nop();
3219 }
3220
3221
3222 void MacroAssembler::Jr(Label* L, BranchDelaySlot bdslot) {
3223   BlockTrampolinePoolScope block_trampoline_pool(this);
3224
3225   uint64_t imm64;
3226   imm64 = jump_address(L);
3227   { BlockGrowBufferScope block_buf_growth(this);
3228     // Buffer growth (and relocation) must be blocked for internal references
3229     // until associated instructions are emitted and available to be patched.
3230     RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
3231     li(at, Operand(imm64), ADDRESS_LOAD);
3232   }
3233   jr(at);
3234
3235   // Emit a nop in the branch delay slot if required.
3236   if (bdslot == PROTECT)
3237     nop();
3238 }
3239
3240
3241 void MacroAssembler::Jalr(Label* L, BranchDelaySlot bdslot) {
3242   BlockTrampolinePoolScope block_trampoline_pool(this);
3243
3244   uint64_t imm64;
3245   imm64 = jump_address(L);
3246   { BlockGrowBufferScope block_buf_growth(this);
3247     // Buffer growth (and relocation) must be blocked for internal references
3248     // until associated instructions are emitted and available to be patched.
3249     RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
3250     li(at, Operand(imm64), ADDRESS_LOAD);
3251   }
3252   jalr(at);
3253
3254   // Emit a nop in the branch delay slot if required.
3255   if (bdslot == PROTECT)
3256     nop();
3257 }
3258
3259
3260 void MacroAssembler::DropAndRet(int drop) {
3261   DCHECK(is_int16(drop * kPointerSize));
3262   Ret(USE_DELAY_SLOT);
3263   daddiu(sp, sp, drop * kPointerSize);
3264 }
3265
3266 void MacroAssembler::DropAndRet(int drop,
3267                                 Condition cond,
3268                                 Register r1,
3269                                 const Operand& r2) {
3270   // Both Drop and Ret need to be conditional.
3271   Label skip;
3272   if (cond != cc_always) {
3273     Branch(&skip, NegateCondition(cond), r1, r2);
3274   }
3275
3276   Drop(drop);
3277   Ret();
3278
3279   if (cond != cc_always) {
3280     bind(&skip);
3281   }
3282 }
3283
3284
3285 void MacroAssembler::Drop(int count,
3286                           Condition cond,
3287                           Register reg,
3288                           const Operand& op) {
3289   if (count <= 0) {
3290     return;
3291   }
3292
3293   Label skip;
3294
3295   if (cond != al) {
3296      Branch(&skip, NegateCondition(cond), reg, op);
3297   }
3298
3299   Daddu(sp, sp, Operand(count * kPointerSize));
3300
3301   if (cond != al) {
3302     bind(&skip);
3303   }
3304 }
3305
3306
3307
3308 void MacroAssembler::Swap(Register reg1,
3309                           Register reg2,
3310                           Register scratch) {
3311   if (scratch.is(no_reg)) {
3312     Xor(reg1, reg1, Operand(reg2));
3313     Xor(reg2, reg2, Operand(reg1));
3314     Xor(reg1, reg1, Operand(reg2));
3315   } else {
3316     mov(scratch, reg1);
3317     mov(reg1, reg2);
3318     mov(reg2, scratch);
3319   }
3320 }
3321
3322
3323 void MacroAssembler::Call(Label* target) {
3324   BranchAndLink(target);
3325 }
3326
3327
3328 void MacroAssembler::Push(Handle<Object> handle) {
3329   li(at, Operand(handle));
3330   push(at);
3331 }
3332
3333
3334 void MacroAssembler::PushRegisterAsTwoSmis(Register src, Register scratch) {
3335   DCHECK(!src.is(scratch));
3336   mov(scratch, src);
3337   dsrl32(src, src, 0);
3338   dsll32(src, src, 0);
3339   push(src);
3340   dsll32(scratch, scratch, 0);
3341   push(scratch);
3342 }
3343
3344
3345 void MacroAssembler::PopRegisterAsTwoSmis(Register dst, Register scratch) {
3346   DCHECK(!dst.is(scratch));
3347   pop(scratch);
3348   dsrl32(scratch, scratch, 0);
3349   pop(dst);
3350   dsrl32(dst, dst, 0);
3351   dsll32(dst, dst, 0);
3352   or_(dst, dst, scratch);
3353 }
3354
3355
3356 void MacroAssembler::DebugBreak() {
3357   PrepareCEntryArgs(0);
3358   PrepareCEntryFunction(
3359       ExternalReference(Runtime::kHandleDebuggerStatement, isolate()));
3360   CEntryStub ces(isolate(), 1);
3361   DCHECK(AllowThisStubCall(&ces));
3362   Call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT);
3363 }
3364
3365
3366 // ---------------------------------------------------------------------------
3367 // Exception handling.
3368
3369 void MacroAssembler::PushStackHandler() {
3370   // Adjust this code if not the case.
3371   STATIC_ASSERT(StackHandlerConstants::kSize == 1 * kPointerSize);
3372   STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
3373
3374   // Link the current handler as the next handler.
3375   li(a6, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
3376   ld(a5, MemOperand(a6));
3377   push(a5);
3378
3379   // Set this new handler as the current one.
3380   sd(sp, MemOperand(a6));
3381 }
3382
3383
3384 void MacroAssembler::PopStackHandler() {
3385   STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
3386   pop(a1);
3387   Daddu(sp, sp, Operand(static_cast<int64_t>(StackHandlerConstants::kSize -
3388                                              kPointerSize)));
3389   li(at, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
3390   sd(a1, MemOperand(at));
3391 }
3392
3393
3394 void MacroAssembler::Allocate(int object_size,
3395                               Register result,
3396                               Register scratch1,
3397                               Register scratch2,
3398                               Label* gc_required,
3399                               AllocationFlags flags) {
3400   DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
3401   if (!FLAG_inline_new) {
3402     if (emit_debug_code()) {
3403       // Trash the registers to simulate an allocation failure.
3404       li(result, 0x7091);
3405       li(scratch1, 0x7191);
3406       li(scratch2, 0x7291);
3407     }
3408     jmp(gc_required);
3409     return;
3410   }
3411
3412   DCHECK(!result.is(scratch1));
3413   DCHECK(!result.is(scratch2));
3414   DCHECK(!scratch1.is(scratch2));
3415   DCHECK(!scratch1.is(t9));
3416   DCHECK(!scratch2.is(t9));
3417   DCHECK(!result.is(t9));
3418
3419   // Make object size into bytes.
3420   if ((flags & SIZE_IN_WORDS) != 0) {
3421     object_size *= kPointerSize;
3422   }
3423   DCHECK(0 == (object_size & kObjectAlignmentMask));
3424
3425   // Check relative positions of allocation top and limit addresses.
3426   // ARM adds additional checks to make sure the ldm instruction can be
3427   // used. On MIPS we don't have ldm so we don't need additional checks either.
3428   ExternalReference allocation_top =
3429       AllocationUtils::GetAllocationTopReference(isolate(), flags);
3430   ExternalReference allocation_limit =
3431       AllocationUtils::GetAllocationLimitReference(isolate(), flags);
3432
3433   intptr_t top   =
3434       reinterpret_cast<intptr_t>(allocation_top.address());
3435   intptr_t limit =
3436       reinterpret_cast<intptr_t>(allocation_limit.address());
3437   DCHECK((limit - top) == kPointerSize);
3438
3439   // Set up allocation top address and object size registers.
3440   Register topaddr = scratch1;
3441   li(topaddr, Operand(allocation_top));
3442
3443   // This code stores a temporary value in t9.
3444   if ((flags & RESULT_CONTAINS_TOP) == 0) {
3445     // Load allocation top into result and allocation limit into t9.
3446     ld(result, MemOperand(topaddr));
3447     ld(t9, MemOperand(topaddr, kPointerSize));
3448   } else {
3449     if (emit_debug_code()) {
3450       // Assert that result actually contains top on entry. t9 is used
3451       // immediately below so this use of t9 does not cause difference with
3452       // respect to register content between debug and release mode.
3453       ld(t9, MemOperand(topaddr));
3454       Check(eq, kUnexpectedAllocationTop, result, Operand(t9));
3455     }
3456     // Load allocation limit into t9. Result already contains allocation top.
3457     ld(t9, MemOperand(topaddr, static_cast<int32_t>(limit - top)));
3458   }
3459
3460   DCHECK(kPointerSize == kDoubleSize);
3461   if (emit_debug_code()) {
3462     And(at, result, Operand(kDoubleAlignmentMask));
3463     Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg));
3464   }
3465
3466   // Calculate new top and bail out if new space is exhausted. Use result
3467   // to calculate the new top.
3468   Daddu(scratch2, result, Operand(object_size));
3469   Branch(gc_required, Ugreater, scratch2, Operand(t9));
3470   sd(scratch2, MemOperand(topaddr));
3471
3472   // Tag object if requested.
3473   if ((flags & TAG_OBJECT) != 0) {
3474     Daddu(result, result, Operand(kHeapObjectTag));
3475   }
3476 }
3477
3478
3479 void MacroAssembler::Allocate(Register object_size,
3480                               Register result,
3481                               Register scratch1,
3482                               Register scratch2,
3483                               Label* gc_required,
3484                               AllocationFlags flags) {
3485   if (!FLAG_inline_new) {
3486     if (emit_debug_code()) {
3487       // Trash the registers to simulate an allocation failure.
3488       li(result, 0x7091);
3489       li(scratch1, 0x7191);
3490       li(scratch2, 0x7291);
3491     }
3492     jmp(gc_required);
3493     return;
3494   }
3495
3496   DCHECK(!result.is(scratch1));
3497   DCHECK(!result.is(scratch2));
3498   DCHECK(!scratch1.is(scratch2));
3499   DCHECK(!object_size.is(t9));
3500   DCHECK(!scratch1.is(t9) && !scratch2.is(t9) && !result.is(t9));
3501
3502   // Check relative positions of allocation top and limit addresses.
3503   // ARM adds additional checks to make sure the ldm instruction can be
3504   // used. On MIPS we don't have ldm so we don't need additional checks either.
3505   ExternalReference allocation_top =
3506       AllocationUtils::GetAllocationTopReference(isolate(), flags);
3507   ExternalReference allocation_limit =
3508       AllocationUtils::GetAllocationLimitReference(isolate(), flags);
3509   intptr_t top   =
3510       reinterpret_cast<intptr_t>(allocation_top.address());
3511   intptr_t limit =
3512       reinterpret_cast<intptr_t>(allocation_limit.address());
3513   DCHECK((limit - top) == kPointerSize);
3514
3515   // Set up allocation top address and object size registers.
3516   Register topaddr = scratch1;
3517   li(topaddr, Operand(allocation_top));
3518
3519   // This code stores a temporary value in t9.
3520   if ((flags & RESULT_CONTAINS_TOP) == 0) {
3521     // Load allocation top into result and allocation limit into t9.
3522     ld(result, MemOperand(topaddr));
3523     ld(t9, MemOperand(topaddr, kPointerSize));
3524   } else {
3525     if (emit_debug_code()) {
3526       // Assert that result actually contains top on entry. t9 is used
3527       // immediately below so this use of t9 does not cause difference with
3528       // respect to register content between debug and release mode.
3529       ld(t9, MemOperand(topaddr));
3530       Check(eq, kUnexpectedAllocationTop, result, Operand(t9));
3531     }
3532     // Load allocation limit into t9. Result already contains allocation top.
3533     ld(t9, MemOperand(topaddr, static_cast<int32_t>(limit - top)));
3534   }
3535
3536   DCHECK(kPointerSize == kDoubleSize);
3537   if (emit_debug_code()) {
3538     And(at, result, Operand(kDoubleAlignmentMask));
3539     Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg));
3540   }
3541
3542   // Calculate new top and bail out if new space is exhausted. Use result
3543   // to calculate the new top. Object size may be in words so a shift is
3544   // required to get the number of bytes.
3545   if ((flags & SIZE_IN_WORDS) != 0) {
3546     dsll(scratch2, object_size, kPointerSizeLog2);
3547     Daddu(scratch2, result, scratch2);
3548   } else {
3549     Daddu(scratch2, result, Operand(object_size));
3550   }
3551   Branch(gc_required, Ugreater, scratch2, Operand(t9));
3552
3553   // Update allocation top. result temporarily holds the new top.
3554   if (emit_debug_code()) {
3555     And(t9, scratch2, Operand(kObjectAlignmentMask));
3556     Check(eq, kUnalignedAllocationInNewSpace, t9, Operand(zero_reg));
3557   }
3558   sd(scratch2, MemOperand(topaddr));
3559
3560   // Tag object if requested.
3561   if ((flags & TAG_OBJECT) != 0) {
3562     Daddu(result, result, Operand(kHeapObjectTag));
3563   }
3564 }
3565
3566
3567 void MacroAssembler::AllocateTwoByteString(Register result,
3568                                            Register length,
3569                                            Register scratch1,
3570                                            Register scratch2,
3571                                            Register scratch3,
3572                                            Label* gc_required) {
3573   // Calculate the number of bytes needed for the characters in the string while
3574   // observing object alignment.
3575   DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
3576   dsll(scratch1, length, 1);  // Length in bytes, not chars.
3577   daddiu(scratch1, scratch1,
3578        kObjectAlignmentMask + SeqTwoByteString::kHeaderSize);
3579   And(scratch1, scratch1, Operand(~kObjectAlignmentMask));
3580
3581   // Allocate two-byte string in new space.
3582   Allocate(scratch1,
3583            result,
3584            scratch2,
3585            scratch3,
3586            gc_required,
3587            TAG_OBJECT);
3588
3589   // Set the map, length and hash field.
3590   InitializeNewString(result,
3591                       length,
3592                       Heap::kStringMapRootIndex,
3593                       scratch1,
3594                       scratch2);
3595 }
3596
3597
3598 void MacroAssembler::AllocateOneByteString(Register result, Register length,
3599                                            Register scratch1, Register scratch2,
3600                                            Register scratch3,
3601                                            Label* gc_required) {
3602   // Calculate the number of bytes needed for the characters in the string
3603   // while observing object alignment.
3604   DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0);
3605   DCHECK(kCharSize == 1);
3606   daddiu(scratch1, length,
3607       kObjectAlignmentMask + SeqOneByteString::kHeaderSize);
3608   And(scratch1, scratch1, Operand(~kObjectAlignmentMask));
3609
3610   // Allocate one-byte string in new space.
3611   Allocate(scratch1,
3612            result,
3613            scratch2,
3614            scratch3,
3615            gc_required,
3616            TAG_OBJECT);
3617
3618   // Set the map, length and hash field.
3619   InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex,
3620                       scratch1, scratch2);
3621 }
3622
3623
3624 void MacroAssembler::AllocateTwoByteConsString(Register result,
3625                                                Register length,
3626                                                Register scratch1,
3627                                                Register scratch2,
3628                                                Label* gc_required) {
3629   Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
3630            TAG_OBJECT);
3631   InitializeNewString(result,
3632                       length,
3633                       Heap::kConsStringMapRootIndex,
3634                       scratch1,
3635                       scratch2);
3636 }
3637
3638
3639 void MacroAssembler::AllocateOneByteConsString(Register result, Register length,
3640                                                Register scratch1,
3641                                                Register scratch2,
3642                                                Label* gc_required) {
3643   Allocate(ConsString::kSize,
3644            result,
3645            scratch1,
3646            scratch2,
3647            gc_required,
3648            TAG_OBJECT);
3649
3650   InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex,
3651                       scratch1, scratch2);
3652 }
3653
3654
3655 void MacroAssembler::AllocateTwoByteSlicedString(Register result,
3656                                                  Register length,
3657                                                  Register scratch1,
3658                                                  Register scratch2,
3659                                                  Label* gc_required) {
3660   Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
3661            TAG_OBJECT);
3662
3663   InitializeNewString(result,
3664                       length,
3665                       Heap::kSlicedStringMapRootIndex,
3666                       scratch1,
3667                       scratch2);
3668 }
3669
3670
3671 void MacroAssembler::AllocateOneByteSlicedString(Register result,
3672                                                  Register length,
3673                                                  Register scratch1,
3674                                                  Register scratch2,
3675                                                  Label* gc_required) {
3676   Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
3677            TAG_OBJECT);
3678
3679   InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex,
3680                       scratch1, scratch2);
3681 }
3682
3683
3684 void MacroAssembler::JumpIfNotUniqueNameInstanceType(Register reg,
3685                                                      Label* not_unique_name) {
3686   STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
3687   Label succeed;
3688   And(at, reg, Operand(kIsNotStringMask | kIsNotInternalizedMask));
3689   Branch(&succeed, eq, at, Operand(zero_reg));
3690   Branch(not_unique_name, ne, reg, Operand(SYMBOL_TYPE));
3691
3692   bind(&succeed);
3693 }
3694
3695
3696 // Allocates a heap number or jumps to the label if the young space is full and
3697 // a scavenge is needed.
3698 void MacroAssembler::AllocateHeapNumber(Register result,
3699                                         Register scratch1,
3700                                         Register scratch2,
3701                                         Register heap_number_map,
3702                                         Label* need_gc,
3703                                         TaggingMode tagging_mode,
3704                                         MutableMode mode) {
3705   // Allocate an object in the heap for the heap number and tag it as a heap
3706   // object.
3707   Allocate(HeapNumber::kSize, result, scratch1, scratch2, need_gc,
3708            tagging_mode == TAG_RESULT ? TAG_OBJECT : NO_ALLOCATION_FLAGS);
3709
3710   Heap::RootListIndex map_index = mode == MUTABLE
3711       ? Heap::kMutableHeapNumberMapRootIndex
3712       : Heap::kHeapNumberMapRootIndex;
3713   AssertIsRoot(heap_number_map, map_index);
3714
3715   // Store heap number map in the allocated object.
3716   if (tagging_mode == TAG_RESULT) {
3717     sd(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset));
3718   } else {
3719     sd(heap_number_map, MemOperand(result, HeapObject::kMapOffset));
3720   }
3721 }
3722
3723
3724 void MacroAssembler::AllocateHeapNumberWithValue(Register result,
3725                                                  FPURegister value,
3726                                                  Register scratch1,
3727                                                  Register scratch2,
3728                                                  Label* gc_required) {
3729   LoadRoot(t8, Heap::kHeapNumberMapRootIndex);
3730   AllocateHeapNumber(result, scratch1, scratch2, t8, gc_required);
3731   sdc1(value, FieldMemOperand(result, HeapNumber::kValueOffset));
3732 }
3733
3734
3735 // Copies a fixed number of fields of heap objects from src to dst.
3736 void MacroAssembler::CopyFields(Register dst,
3737                                 Register src,
3738                                 RegList temps,
3739                                 int field_count) {
3740   DCHECK((temps & dst.bit()) == 0);
3741   DCHECK((temps & src.bit()) == 0);
3742   // Primitive implementation using only one temporary register.
3743
3744   Register tmp = no_reg;
3745   // Find a temp register in temps list.
3746   for (int i = 0; i < kNumRegisters; i++) {
3747     if ((temps & (1 << i)) != 0) {
3748       tmp.code_ = i;
3749       break;
3750     }
3751   }
3752   DCHECK(!tmp.is(no_reg));
3753
3754   for (int i = 0; i < field_count; i++) {
3755     ld(tmp, FieldMemOperand(src, i * kPointerSize));
3756     sd(tmp, FieldMemOperand(dst, i * kPointerSize));
3757   }
3758 }
3759
3760
3761 void MacroAssembler::CopyBytes(Register src,
3762                                Register dst,
3763                                Register length,
3764                                Register scratch) {
3765   Label align_loop_1, word_loop, byte_loop, byte_loop_1, done;
3766
3767   // Align src before copying in word size chunks.
3768   Branch(&byte_loop, le, length, Operand(kPointerSize));
3769   bind(&align_loop_1);
3770   And(scratch, src, kPointerSize - 1);
3771   Branch(&word_loop, eq, scratch, Operand(zero_reg));
3772   lbu(scratch, MemOperand(src));
3773   Daddu(src, src, 1);
3774   sb(scratch, MemOperand(dst));
3775   Daddu(dst, dst, 1);
3776   Dsubu(length, length, Operand(1));
3777   Branch(&align_loop_1, ne, length, Operand(zero_reg));
3778
3779   // Copy bytes in word size chunks.
3780   bind(&word_loop);
3781   if (emit_debug_code()) {
3782     And(scratch, src, kPointerSize - 1);
3783     Assert(eq, kExpectingAlignmentForCopyBytes,
3784         scratch, Operand(zero_reg));
3785   }
3786   Branch(&byte_loop, lt, length, Operand(kPointerSize));
3787   ld(scratch, MemOperand(src));
3788   Daddu(src, src, kPointerSize);
3789
3790   // TODO(kalmard) check if this can be optimized to use sw in most cases.
3791   // Can't use unaligned access - copy byte by byte.
3792   sb(scratch, MemOperand(dst, 0));
3793   dsrl(scratch, scratch, 8);
3794   sb(scratch, MemOperand(dst, 1));
3795   dsrl(scratch, scratch, 8);
3796   sb(scratch, MemOperand(dst, 2));
3797   dsrl(scratch, scratch, 8);
3798   sb(scratch, MemOperand(dst, 3));
3799   dsrl(scratch, scratch, 8);
3800   sb(scratch, MemOperand(dst, 4));
3801   dsrl(scratch, scratch, 8);
3802   sb(scratch, MemOperand(dst, 5));
3803   dsrl(scratch, scratch, 8);
3804   sb(scratch, MemOperand(dst, 6));
3805   dsrl(scratch, scratch, 8);
3806   sb(scratch, MemOperand(dst, 7));
3807   Daddu(dst, dst, 8);
3808
3809   Dsubu(length, length, Operand(kPointerSize));
3810   Branch(&word_loop);
3811
3812   // Copy the last bytes if any left.
3813   bind(&byte_loop);
3814   Branch(&done, eq, length, Operand(zero_reg));
3815   bind(&byte_loop_1);
3816   lbu(scratch, MemOperand(src));
3817   Daddu(src, src, 1);
3818   sb(scratch, MemOperand(dst));
3819   Daddu(dst, dst, 1);
3820   Dsubu(length, length, Operand(1));
3821   Branch(&byte_loop_1, ne, length, Operand(zero_reg));
3822   bind(&done);
3823 }
3824
3825
3826 void MacroAssembler::InitializeFieldsWithFiller(Register start_offset,
3827                                                 Register end_offset,
3828                                                 Register filler) {
3829   Label loop, entry;
3830   Branch(&entry);
3831   bind(&loop);
3832   sd(filler, MemOperand(start_offset));
3833   Daddu(start_offset, start_offset, kPointerSize);
3834   bind(&entry);
3835   Branch(&loop, ult, start_offset, Operand(end_offset));
3836 }
3837
3838
3839 void MacroAssembler::CheckFastElements(Register map,
3840                                        Register scratch,
3841                                        Label* fail) {
3842   STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
3843   STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
3844   STATIC_ASSERT(FAST_ELEMENTS == 2);
3845   STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
3846   lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset));
3847   Branch(fail, hi, scratch,
3848          Operand(Map::kMaximumBitField2FastHoleyElementValue));
3849 }
3850
3851
3852 void MacroAssembler::CheckFastObjectElements(Register map,
3853                                              Register scratch,
3854                                              Label* fail) {
3855   STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
3856   STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
3857   STATIC_ASSERT(FAST_ELEMENTS == 2);
3858   STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
3859   lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset));
3860   Branch(fail, ls, scratch,
3861          Operand(Map::kMaximumBitField2FastHoleySmiElementValue));
3862   Branch(fail, hi, scratch,
3863          Operand(Map::kMaximumBitField2FastHoleyElementValue));
3864 }
3865
3866
3867 void MacroAssembler::CheckFastSmiElements(Register map,
3868                                           Register scratch,
3869                                           Label* fail) {
3870   STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
3871   STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
3872   lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset));
3873   Branch(fail, hi, scratch,
3874          Operand(Map::kMaximumBitField2FastHoleySmiElementValue));
3875 }
3876
3877
3878 void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
3879                                                  Register key_reg,
3880                                                  Register elements_reg,
3881                                                  Register scratch1,
3882                                                  Register scratch2,
3883                                                  Label* fail,
3884                                                  int elements_offset) {
3885   Label smi_value, done;
3886
3887   // Handle smi values specially.
3888   JumpIfSmi(value_reg, &smi_value);
3889
3890   // Ensure that the object is a heap number.
3891   CheckMap(value_reg,
3892            scratch1,
3893            Heap::kHeapNumberMapRootIndex,
3894            fail,
3895            DONT_DO_SMI_CHECK);
3896
3897   // Double value, turn potential sNaN into qNan.
3898   DoubleRegister double_result = f0;
3899   DoubleRegister double_scratch = f2;
3900
3901   ldc1(double_result, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
3902   Branch(USE_DELAY_SLOT, &done);  // Canonicalization is one instruction.
3903   FPUCanonicalizeNaN(double_result, double_result);
3904
3905   bind(&smi_value);
3906   // scratch1 is now effective address of the double element.
3907   // Untag and transfer.
3908   dsrl32(at, value_reg, 0);
3909   mtc1(at, double_scratch);
3910   cvt_d_w(double_result, double_scratch);
3911
3912   bind(&done);
3913   Daddu(scratch1, elements_reg,
3914       Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag -
3915               elements_offset));
3916   dsra(scratch2, key_reg, 32 - kDoubleSizeLog2);
3917   Daddu(scratch1, scratch1, scratch2);
3918   sdc1(double_result, MemOperand(scratch1, 0));
3919 }
3920
3921
3922 void MacroAssembler::CompareMapAndBranch(Register obj,
3923                                          Register scratch,
3924                                          Handle<Map> map,
3925                                          Label* early_success,
3926                                          Condition cond,
3927                                          Label* branch_to) {
3928   ld(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
3929   CompareMapAndBranch(scratch, map, early_success, cond, branch_to);
3930 }
3931
3932
3933 void MacroAssembler::CompareMapAndBranch(Register obj_map,
3934                                          Handle<Map> map,
3935                                          Label* early_success,
3936                                          Condition cond,
3937                                          Label* branch_to) {
3938   Branch(branch_to, cond, obj_map, Operand(map));
3939 }
3940
3941
3942 void MacroAssembler::CheckMap(Register obj,
3943                               Register scratch,
3944                               Handle<Map> map,
3945                               Label* fail,
3946                               SmiCheckType smi_check_type) {
3947   if (smi_check_type == DO_SMI_CHECK) {
3948     JumpIfSmi(obj, fail);
3949   }
3950   Label success;
3951   CompareMapAndBranch(obj, scratch, map, &success, ne, fail);
3952   bind(&success);
3953 }
3954
3955
3956 void MacroAssembler::DispatchWeakMap(Register obj, Register scratch1,
3957                                      Register scratch2, Handle<WeakCell> cell,
3958                                      Handle<Code> success,
3959                                      SmiCheckType smi_check_type) {
3960   Label fail;
3961   if (smi_check_type == DO_SMI_CHECK) {
3962     JumpIfSmi(obj, &fail);
3963   }
3964   ld(scratch1, FieldMemOperand(obj, HeapObject::kMapOffset));
3965   GetWeakValue(scratch2, cell);
3966   Jump(success, RelocInfo::CODE_TARGET, eq, scratch1, Operand(scratch2));
3967   bind(&fail);
3968 }
3969
3970
3971 void MacroAssembler::CheckMap(Register obj,
3972                               Register scratch,
3973                               Heap::RootListIndex index,
3974                               Label* fail,
3975                               SmiCheckType smi_check_type) {
3976   if (smi_check_type == DO_SMI_CHECK) {
3977     JumpIfSmi(obj, fail);
3978   }
3979   ld(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
3980   LoadRoot(at, index);
3981   Branch(fail, ne, scratch, Operand(at));
3982 }
3983
3984
3985 void MacroAssembler::GetWeakValue(Register value, Handle<WeakCell> cell) {
3986   li(value, Operand(cell));
3987   ld(value, FieldMemOperand(value, WeakCell::kValueOffset));
3988 }
3989
3990 void MacroAssembler::FPUCanonicalizeNaN(const DoubleRegister dst,
3991                                         const DoubleRegister src) {
3992   sub_d(dst, src, kDoubleRegZero);
3993 }
3994
3995 void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell,
3996                                    Label* miss) {
3997   GetWeakValue(value, cell);
3998   JumpIfSmi(value, miss);
3999 }
4000
4001
4002 void MacroAssembler::MovFromFloatResult(const DoubleRegister dst) {
4003   if (IsMipsSoftFloatABI) {
4004     Move(dst, v0, v1);
4005   } else {
4006     Move(dst, f0);  // Reg f0 is o32 ABI FP return value.
4007   }
4008 }
4009
4010
4011 void MacroAssembler::MovFromFloatParameter(const DoubleRegister dst) {
4012   if (IsMipsSoftFloatABI) {
4013     Move(dst, a0, a1);
4014   } else {
4015     Move(dst, f12);  // Reg f12 is o32 ABI FP first argument value.
4016   }
4017 }
4018
4019
4020 void MacroAssembler::MovToFloatParameter(DoubleRegister src) {
4021   if (!IsMipsSoftFloatABI) {
4022     Move(f12, src);
4023   } else {
4024     Move(a0, a1, src);
4025   }
4026 }
4027
4028
4029 void MacroAssembler::MovToFloatResult(DoubleRegister src) {
4030   if (!IsMipsSoftFloatABI) {
4031     Move(f0, src);
4032   } else {
4033     Move(v0, v1, src);
4034   }
4035 }
4036
4037
4038 void MacroAssembler::MovToFloatParameters(DoubleRegister src1,
4039                                           DoubleRegister src2) {
4040   if (!IsMipsSoftFloatABI) {
4041     const DoubleRegister fparg2 = (kMipsAbi == kN64) ? f13 : f14;
4042     if (src2.is(f12)) {
4043       DCHECK(!src1.is(fparg2));
4044       Move(fparg2, src2);
4045       Move(f12, src1);
4046     } else {
4047       Move(f12, src1);
4048       Move(fparg2, src2);
4049     }
4050   } else {
4051     Move(a0, a1, src1);
4052     Move(a2, a3, src2);
4053   }
4054 }
4055
4056
4057 // -----------------------------------------------------------------------------
4058 // JavaScript invokes.
4059
4060 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
4061                                     const ParameterCount& actual,
4062                                     Handle<Code> code_constant,
4063                                     Register code_reg,
4064                                     Label* done,
4065                                     bool* definitely_mismatches,
4066                                     InvokeFlag flag,
4067                                     const CallWrapper& call_wrapper) {
4068   bool definitely_matches = false;
4069   *definitely_mismatches = false;
4070   Label regular_invoke;
4071
4072   // Check whether the expected and actual arguments count match. If not,
4073   // setup registers according to contract with ArgumentsAdaptorTrampoline:
4074   //  a0: actual arguments count
4075   //  a1: function (passed through to callee)
4076   //  a2: expected arguments count
4077
4078   // The code below is made a lot easier because the calling code already sets
4079   // up actual and expected registers according to the contract if values are
4080   // passed in registers.
4081   DCHECK(actual.is_immediate() || actual.reg().is(a0));
4082   DCHECK(expected.is_immediate() || expected.reg().is(a2));
4083   DCHECK((!code_constant.is_null() && code_reg.is(no_reg)) || code_reg.is(a3));
4084
4085   if (expected.is_immediate()) {
4086     DCHECK(actual.is_immediate());
4087     if (expected.immediate() == actual.immediate()) {
4088       definitely_matches = true;
4089     } else {
4090       li(a0, Operand(actual.immediate()));
4091       const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4092       if (expected.immediate() == sentinel) {
4093         // Don't worry about adapting arguments for builtins that
4094         // don't want that done. Skip adaption code by making it look
4095         // like we have a match between expected and actual number of
4096         // arguments.
4097         definitely_matches = true;
4098       } else {
4099         *definitely_mismatches = true;
4100         li(a2, Operand(expected.immediate()));
4101       }
4102     }
4103   } else if (actual.is_immediate()) {
4104     Branch(&regular_invoke, eq, expected.reg(), Operand(actual.immediate()));
4105     li(a0, Operand(actual.immediate()));
4106   } else {
4107     Branch(&regular_invoke, eq, expected.reg(), Operand(actual.reg()));
4108   }
4109
4110   if (!definitely_matches) {
4111     if (!code_constant.is_null()) {
4112       li(a3, Operand(code_constant));
4113       daddiu(a3, a3, Code::kHeaderSize - kHeapObjectTag);
4114     }
4115
4116     Handle<Code> adaptor =
4117         isolate()->builtins()->ArgumentsAdaptorTrampoline();
4118     if (flag == CALL_FUNCTION) {
4119       call_wrapper.BeforeCall(CallSize(adaptor));
4120       Call(adaptor);
4121       call_wrapper.AfterCall();
4122       if (!*definitely_mismatches) {
4123         Branch(done);
4124       }
4125     } else {
4126       Jump(adaptor, RelocInfo::CODE_TARGET);
4127     }
4128     bind(&regular_invoke);
4129   }
4130 }
4131
4132
4133 void MacroAssembler::InvokeCode(Register code,
4134                                 const ParameterCount& expected,
4135                                 const ParameterCount& actual,
4136                                 InvokeFlag flag,
4137                                 const CallWrapper& call_wrapper) {
4138   // You can't call a function without a valid frame.
4139   DCHECK(flag == JUMP_FUNCTION || has_frame());
4140
4141   Label done;
4142
4143   bool definitely_mismatches = false;
4144   InvokePrologue(expected, actual, Handle<Code>::null(), code,
4145                  &done, &definitely_mismatches, flag,
4146                  call_wrapper);
4147   if (!definitely_mismatches) {
4148     if (flag == CALL_FUNCTION) {
4149       call_wrapper.BeforeCall(CallSize(code));
4150       Call(code);
4151       call_wrapper.AfterCall();
4152     } else {
4153       DCHECK(flag == JUMP_FUNCTION);
4154       Jump(code);
4155     }
4156     // Continue here if InvokePrologue does handle the invocation due to
4157     // mismatched parameter counts.
4158     bind(&done);
4159   }
4160 }
4161
4162
4163 void MacroAssembler::InvokeFunction(Register function,
4164                                     const ParameterCount& actual,
4165                                     InvokeFlag flag,
4166                                     const CallWrapper& call_wrapper) {
4167   // You can't call a function without a valid frame.
4168   DCHECK(flag == JUMP_FUNCTION || has_frame());
4169
4170   // Contract with called JS functions requires that function is passed in a1.
4171   DCHECK(function.is(a1));
4172   Register expected_reg = a2;
4173   Register code_reg = a3;
4174   ld(code_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
4175   ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
4176   // The argument count is stored as int32_t on 64-bit platforms.
4177   // TODO(plind): Smi on 32-bit platforms.
4178   lw(expected_reg,
4179       FieldMemOperand(code_reg,
4180                       SharedFunctionInfo::kFormalParameterCountOffset));
4181   ld(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
4182   ParameterCount expected(expected_reg);
4183   InvokeCode(code_reg, expected, actual, flag, call_wrapper);
4184 }
4185
4186
4187 void MacroAssembler::InvokeFunction(Register function,
4188                                     const ParameterCount& expected,
4189                                     const ParameterCount& actual,
4190                                     InvokeFlag flag,
4191                                     const CallWrapper& call_wrapper) {
4192   // You can't call a function without a valid frame.
4193   DCHECK(flag == JUMP_FUNCTION || has_frame());
4194
4195   // Contract with called JS functions requires that function is passed in a1.
4196   DCHECK(function.is(a1));
4197
4198   // Get the function and setup the context.
4199   ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
4200
4201   // We call indirectly through the code field in the function to
4202   // allow recompilation to take effect without changing any of the
4203   // call sites.
4204   ld(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
4205   InvokeCode(a3, expected, actual, flag, call_wrapper);
4206 }
4207
4208
4209 void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
4210                                     const ParameterCount& expected,
4211                                     const ParameterCount& actual,
4212                                     InvokeFlag flag,
4213                                     const CallWrapper& call_wrapper) {
4214   li(a1, function);
4215   InvokeFunction(a1, expected, actual, flag, call_wrapper);
4216 }
4217
4218
4219 void MacroAssembler::IsObjectJSObjectType(Register heap_object,
4220                                           Register map,
4221                                           Register scratch,
4222                                           Label* fail) {
4223   ld(map, FieldMemOperand(heap_object, HeapObject::kMapOffset));
4224   IsInstanceJSObjectType(map, scratch, fail);
4225 }
4226
4227
4228 void MacroAssembler::IsInstanceJSObjectType(Register map,
4229                                             Register scratch,
4230                                             Label* fail) {
4231   lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
4232   Branch(fail, lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
4233   Branch(fail, gt, scratch, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
4234 }
4235
4236
4237 void MacroAssembler::IsObjectJSStringType(Register object,
4238                                           Register scratch,
4239                                           Label* fail) {
4240   DCHECK(kNotStringTag != 0);
4241
4242   ld(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
4243   lbu(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
4244   And(scratch, scratch, Operand(kIsNotStringMask));
4245   Branch(fail, ne, scratch, Operand(zero_reg));
4246 }
4247
4248
4249 void MacroAssembler::IsObjectNameType(Register object,
4250                                       Register scratch,
4251                                       Label* fail) {
4252   ld(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
4253   lbu(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
4254   Branch(fail, hi, scratch, Operand(LAST_NAME_TYPE));
4255 }
4256
4257
4258 // ---------------------------------------------------------------------------
4259 // Support functions.
4260
4261
4262 void MacroAssembler::GetMapConstructor(Register result, Register map,
4263                                        Register temp, Register temp2) {
4264   Label done, loop;
4265   ld(result, FieldMemOperand(map, Map::kConstructorOrBackPointerOffset));
4266   bind(&loop);
4267   JumpIfSmi(result, &done);
4268   GetObjectType(result, temp, temp2);
4269   Branch(&done, ne, temp2, Operand(MAP_TYPE));
4270   ld(result, FieldMemOperand(result, Map::kConstructorOrBackPointerOffset));
4271   Branch(&loop);
4272   bind(&done);
4273 }
4274
4275
4276 void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
4277                                              Register scratch, Label* miss) {
4278   // Get the prototype or initial map from the function.
4279   ld(result,
4280      FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
4281
4282   // If the prototype or initial map is the hole, don't return it and
4283   // simply miss the cache instead. This will allow us to allocate a
4284   // prototype object on-demand in the runtime system.
4285   LoadRoot(t8, Heap::kTheHoleValueRootIndex);
4286   Branch(miss, eq, result, Operand(t8));
4287
4288   // If the function does not have an initial map, we're done.
4289   Label done;
4290   GetObjectType(result, scratch, scratch);
4291   Branch(&done, ne, scratch, Operand(MAP_TYPE));
4292
4293   // Get the prototype from the initial map.
4294   ld(result, FieldMemOperand(result, Map::kPrototypeOffset));
4295
4296   // All done.
4297   bind(&done);
4298 }
4299
4300
4301 void MacroAssembler::GetObjectType(Register object,
4302                                    Register map,
4303                                    Register type_reg) {
4304   ld(map, FieldMemOperand(object, HeapObject::kMapOffset));
4305   lbu(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset));
4306 }
4307
4308
4309 // -----------------------------------------------------------------------------
4310 // Runtime calls.
4311
4312 void MacroAssembler::CallStub(CodeStub* stub,
4313                               TypeFeedbackId ast_id,
4314                               Condition cond,
4315                               Register r1,
4316                               const Operand& r2,
4317                               BranchDelaySlot bd) {
4318   DCHECK(AllowThisStubCall(stub));  // Stub calls are not allowed in some stubs.
4319   Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id,
4320        cond, r1, r2, bd);
4321 }
4322
4323
4324 void MacroAssembler::TailCallStub(CodeStub* stub,
4325                                   Condition cond,
4326                                   Register r1,
4327                                   const Operand& r2,
4328                                   BranchDelaySlot bd) {
4329   Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond, r1, r2, bd);
4330 }
4331
4332
4333 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
4334   return has_frame_ || !stub->SometimesSetsUpAFrame();
4335 }
4336
4337
4338 void MacroAssembler::IndexFromHash(Register hash, Register index) {
4339   // If the hash field contains an array index pick it out. The assert checks
4340   // that the constants for the maximum number of digits for an array index
4341   // cached in the hash field and the number of bits reserved for it does not
4342   // conflict.
4343   DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) <
4344          (1 << String::kArrayIndexValueBits));
4345   DecodeFieldToSmi<String::ArrayIndexValueBits>(index, hash);
4346 }
4347
4348
4349 void MacroAssembler::ObjectToDoubleFPURegister(Register object,
4350                                                FPURegister result,
4351                                                Register scratch1,
4352                                                Register scratch2,
4353                                                Register heap_number_map,
4354                                                Label* not_number,
4355                                                ObjectToDoubleFlags flags) {
4356   Label done;
4357   if ((flags & OBJECT_NOT_SMI) == 0) {
4358     Label not_smi;
4359     JumpIfNotSmi(object, &not_smi);
4360     // Remove smi tag and convert to double.
4361     // dsra(scratch1, object, kSmiTagSize);
4362     dsra32(scratch1, object, 0);
4363     mtc1(scratch1, result);
4364     cvt_d_w(result, result);
4365     Branch(&done);
4366     bind(&not_smi);
4367   }
4368   // Check for heap number and load double value from it.
4369   ld(scratch1, FieldMemOperand(object, HeapObject::kMapOffset));
4370   Branch(not_number, ne, scratch1, Operand(heap_number_map));
4371
4372   if ((flags & AVOID_NANS_AND_INFINITIES) != 0) {
4373     // If exponent is all ones the number is either a NaN or +/-Infinity.
4374     Register exponent = scratch1;
4375     Register mask_reg = scratch2;
4376     lwu(exponent, FieldMemOperand(object, HeapNumber::kExponentOffset));
4377     li(mask_reg, HeapNumber::kExponentMask);
4378
4379     And(exponent, exponent, mask_reg);
4380     Branch(not_number, eq, exponent, Operand(mask_reg));
4381   }
4382   ldc1(result, FieldMemOperand(object, HeapNumber::kValueOffset));
4383   bind(&done);
4384 }
4385
4386
4387 void MacroAssembler::SmiToDoubleFPURegister(Register smi,
4388                                             FPURegister value,
4389                                             Register scratch1) {
4390   dsra32(scratch1, smi, 0);
4391   mtc1(scratch1, value);
4392   cvt_d_w(value, value);
4393 }
4394
4395
4396 void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left,
4397                                              const Operand& right,
4398                                              Register overflow_dst,
4399                                              Register scratch) {
4400   if (right.is_reg()) {
4401     AdduAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch);
4402   } else {
4403     if (dst.is(left)) {
4404       li(t9, right);                         // Load right.
4405       mov(scratch, left);                    // Preserve left.
4406       addu(dst, left, t9);                   // Left is overwritten.
4407       xor_(scratch, dst, scratch);           // Original left.
4408       xor_(overflow_dst, dst, t9);
4409       and_(overflow_dst, overflow_dst, scratch);
4410     } else {
4411       li(t9, right);
4412       addu(dst, left, t9);
4413       xor_(overflow_dst, dst, left);
4414       xor_(scratch, dst, t9);
4415       and_(overflow_dst, scratch, overflow_dst);
4416     }
4417   }
4418 }
4419
4420
4421 void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left,
4422                                              Register right,
4423                                              Register overflow_dst,
4424                                              Register scratch) {
4425   DCHECK(!dst.is(overflow_dst));
4426   DCHECK(!dst.is(scratch));
4427   DCHECK(!overflow_dst.is(scratch));
4428   DCHECK(!overflow_dst.is(left));
4429   DCHECK(!overflow_dst.is(right));
4430
4431   if (left.is(right) && dst.is(left)) {
4432     DCHECK(!dst.is(t9));
4433     DCHECK(!scratch.is(t9));
4434     DCHECK(!left.is(t9));
4435     DCHECK(!right.is(t9));
4436     DCHECK(!overflow_dst.is(t9));
4437     mov(t9, right);
4438     right = t9;
4439   }
4440
4441   if (dst.is(left)) {
4442     mov(scratch, left);           // Preserve left.
4443     addu(dst, left, right);       // Left is overwritten.
4444     xor_(scratch, dst, scratch);  // Original left.
4445     xor_(overflow_dst, dst, right);
4446     and_(overflow_dst, overflow_dst, scratch);
4447   } else if (dst.is(right)) {
4448     mov(scratch, right);          // Preserve right.
4449     addu(dst, left, right);       // Right is overwritten.
4450     xor_(scratch, dst, scratch);  // Original right.
4451     xor_(overflow_dst, dst, left);
4452     and_(overflow_dst, overflow_dst, scratch);
4453   } else {
4454     addu(dst, left, right);
4455     xor_(overflow_dst, dst, left);
4456     xor_(scratch, dst, right);
4457     and_(overflow_dst, scratch, overflow_dst);
4458   }
4459 }
4460
4461
4462 void MacroAssembler::DadduAndCheckForOverflow(Register dst, Register left,
4463                                               const Operand& right,
4464                                               Register overflow_dst,
4465                                               Register scratch) {
4466   if (right.is_reg()) {
4467     DadduAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch);
4468   } else {
4469     if (dst.is(left)) {
4470       li(t9, right);                // Load right.
4471       mov(scratch, left);           // Preserve left.
4472       daddu(dst, left, t9);         // Left is overwritten.
4473       xor_(scratch, dst, scratch);  // Original left.
4474       xor_(overflow_dst, dst, t9);
4475       and_(overflow_dst, overflow_dst, scratch);
4476     } else {
4477       li(t9, right);  // Load right.
4478       Daddu(dst, left, t9);
4479       xor_(overflow_dst, dst, left);
4480       xor_(scratch, dst, t9);
4481       and_(overflow_dst, scratch, overflow_dst);
4482     }
4483   }
4484 }
4485
4486
4487 void MacroAssembler::DadduAndCheckForOverflow(Register dst, Register left,
4488                                               Register right,
4489                                               Register overflow_dst,
4490                                               Register scratch) {
4491   DCHECK(!dst.is(overflow_dst));
4492   DCHECK(!dst.is(scratch));
4493   DCHECK(!overflow_dst.is(scratch));
4494   DCHECK(!overflow_dst.is(left));
4495   DCHECK(!overflow_dst.is(right));
4496
4497   if (left.is(right) && dst.is(left)) {
4498     DCHECK(!dst.is(t9));
4499     DCHECK(!scratch.is(t9));
4500     DCHECK(!left.is(t9));
4501     DCHECK(!right.is(t9));
4502     DCHECK(!overflow_dst.is(t9));
4503     mov(t9, right);
4504     right = t9;
4505   }
4506
4507   if (dst.is(left)) {
4508     mov(scratch, left);  // Preserve left.
4509     daddu(dst, left, right);  // Left is overwritten.
4510     xor_(scratch, dst, scratch);  // Original left.
4511     xor_(overflow_dst, dst, right);
4512     and_(overflow_dst, overflow_dst, scratch);
4513   } else if (dst.is(right)) {
4514     mov(scratch, right);  // Preserve right.
4515     daddu(dst, left, right);  // Right is overwritten.
4516     xor_(scratch, dst, scratch);  // Original right.
4517     xor_(overflow_dst, dst, left);
4518     and_(overflow_dst, overflow_dst, scratch);
4519   } else {
4520     daddu(dst, left, right);
4521     xor_(overflow_dst, dst, left);
4522     xor_(scratch, dst, right);
4523     and_(overflow_dst, scratch, overflow_dst);
4524   }
4525 }
4526
4527
4528 void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left,
4529                                              const Operand& right,
4530                                              Register overflow_dst,
4531                                              Register scratch) {
4532   if (right.is_reg()) {
4533     SubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch);
4534   } else {
4535     if (dst.is(left)) {
4536       li(t9, right);                            // Load right.
4537       mov(scratch, left);                       // Preserve left.
4538       Subu(dst, left, t9);                      // Left is overwritten.
4539       xor_(overflow_dst, dst, scratch);         // scratch is original left.
4540       xor_(scratch, scratch, t9);  // scratch is original left.
4541       and_(overflow_dst, scratch, overflow_dst);
4542     } else {
4543       li(t9, right);
4544       subu(dst, left, t9);
4545       xor_(overflow_dst, dst, left);
4546       xor_(scratch, left, t9);
4547       and_(overflow_dst, scratch, overflow_dst);
4548     }
4549   }
4550 }
4551
4552
4553 void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left,
4554                                              Register right,
4555                                              Register overflow_dst,
4556                                              Register scratch) {
4557   DCHECK(!dst.is(overflow_dst));
4558   DCHECK(!dst.is(scratch));
4559   DCHECK(!overflow_dst.is(scratch));
4560   DCHECK(!overflow_dst.is(left));
4561   DCHECK(!overflow_dst.is(right));
4562   DCHECK(!scratch.is(left));
4563   DCHECK(!scratch.is(right));
4564
4565   // This happens with some crankshaft code. Since Subu works fine if
4566   // left == right, let's not make that restriction here.
4567   if (left.is(right)) {
4568     mov(dst, zero_reg);
4569     mov(overflow_dst, zero_reg);
4570     return;
4571   }
4572
4573   if (dst.is(left)) {
4574     mov(scratch, left);                // Preserve left.
4575     subu(dst, left, right);            // Left is overwritten.
4576     xor_(overflow_dst, dst, scratch);  // scratch is original left.
4577     xor_(scratch, scratch, right);     // scratch is original left.
4578     and_(overflow_dst, scratch, overflow_dst);
4579   } else if (dst.is(right)) {
4580     mov(scratch, right);     // Preserve right.
4581     subu(dst, left, right);  // Right is overwritten.
4582     xor_(overflow_dst, dst, left);
4583     xor_(scratch, left, scratch);  // Original right.
4584     and_(overflow_dst, scratch, overflow_dst);
4585   } else {
4586     subu(dst, left, right);
4587     xor_(overflow_dst, dst, left);
4588     xor_(scratch, left, right);
4589     and_(overflow_dst, scratch, overflow_dst);
4590   }
4591 }
4592
4593
4594 void MacroAssembler::DsubuAndCheckForOverflow(Register dst, Register left,
4595                                               const Operand& right,
4596                                               Register overflow_dst,
4597                                               Register scratch) {
4598   if (right.is_reg()) {
4599     DsubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch);
4600   } else {
4601     if (dst.is(left)) {
4602       li(t9, right);                     // Load right.
4603       mov(scratch, left);                // Preserve left.
4604       dsubu(dst, left, t9);              // Left is overwritten.
4605       xor_(overflow_dst, dst, scratch);  // scratch is original left.
4606       xor_(scratch, scratch, t9);        // scratch is original left.
4607       and_(overflow_dst, scratch, overflow_dst);
4608     } else {
4609       li(t9, right);
4610       dsubu(dst, left, t9);
4611       xor_(overflow_dst, dst, left);
4612       xor_(scratch, left, t9);
4613       and_(overflow_dst, scratch, overflow_dst);
4614     }
4615   }
4616 }
4617
4618
4619 void MacroAssembler::DsubuAndCheckForOverflow(Register dst, Register left,
4620                                               Register right,
4621                                               Register overflow_dst,
4622                                               Register scratch) {
4623   DCHECK(!dst.is(overflow_dst));
4624   DCHECK(!dst.is(scratch));
4625   DCHECK(!overflow_dst.is(scratch));
4626   DCHECK(!overflow_dst.is(left));
4627   DCHECK(!overflow_dst.is(right));
4628   DCHECK(!scratch.is(left));
4629   DCHECK(!scratch.is(right));
4630
4631   // This happens with some crankshaft code. Since Subu works fine if
4632   // left == right, let's not make that restriction here.
4633   if (left.is(right)) {
4634     mov(dst, zero_reg);
4635     mov(overflow_dst, zero_reg);
4636     return;
4637   }
4638
4639   if (dst.is(left)) {
4640     mov(scratch, left);  // Preserve left.
4641     dsubu(dst, left, right);  // Left is overwritten.
4642     xor_(overflow_dst, dst, scratch);  // scratch is original left.
4643     xor_(scratch, scratch, right);  // scratch is original left.
4644     and_(overflow_dst, scratch, overflow_dst);
4645   } else if (dst.is(right)) {
4646     mov(scratch, right);  // Preserve right.
4647     dsubu(dst, left, right);  // Right is overwritten.
4648     xor_(overflow_dst, dst, left);
4649     xor_(scratch, left, scratch);  // Original right.
4650     and_(overflow_dst, scratch, overflow_dst);
4651   } else {
4652     dsubu(dst, left, right);
4653     xor_(overflow_dst, dst, left);
4654     xor_(scratch, left, right);
4655     and_(overflow_dst, scratch, overflow_dst);
4656   }
4657 }
4658
4659 void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
4660                                  SaveFPRegsMode save_doubles,
4661                                  BranchDelaySlot bd) {
4662   // All parameters are on the stack. v0 has the return value after call.
4663
4664   // If the expected number of arguments of the runtime function is
4665   // constant, we check that the actual number of arguments match the
4666   // expectation.
4667   CHECK(f->nargs < 0 || f->nargs == num_arguments);
4668
4669   // TODO(1236192): Most runtime routines don't need the number of
4670   // arguments passed in because it is constant. At some point we
4671   // should remove this need and make the runtime routine entry code
4672   // smarter.
4673   PrepareCEntryArgs(num_arguments);
4674   PrepareCEntryFunction(ExternalReference(f, isolate()));
4675   CEntryStub stub(isolate(), 1, save_doubles);
4676   CallStub(&stub, TypeFeedbackId::None(), al, zero_reg, Operand(zero_reg), bd);
4677 }
4678
4679
4680 void MacroAssembler::CallExternalReference(const ExternalReference& ext,
4681                                            int num_arguments,
4682                                            BranchDelaySlot bd) {
4683   PrepareCEntryArgs(num_arguments);
4684   PrepareCEntryFunction(ext);
4685
4686   CEntryStub stub(isolate(), 1);
4687   CallStub(&stub, TypeFeedbackId::None(), al, zero_reg, Operand(zero_reg), bd);
4688 }
4689
4690
4691 void MacroAssembler::TailCallExternalReference(const ExternalReference& ext,
4692                                                int num_arguments,
4693                                                int result_size) {
4694   // TODO(1236192): Most runtime routines don't need the number of
4695   // arguments passed in because it is constant. At some point we
4696   // should remove this need and make the runtime routine entry code
4697   // smarter.
4698   PrepareCEntryArgs(num_arguments);
4699   JumpToExternalReference(ext);
4700 }
4701
4702
4703 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
4704                                      int num_arguments,
4705                                      int result_size) {
4706   TailCallExternalReference(ExternalReference(fid, isolate()),
4707                             num_arguments,
4708                             result_size);
4709 }
4710
4711
4712 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin,
4713                                              BranchDelaySlot bd) {
4714   PrepareCEntryFunction(builtin);
4715   CEntryStub stub(isolate(), 1);
4716   Jump(stub.GetCode(),
4717        RelocInfo::CODE_TARGET,
4718        al,
4719        zero_reg,
4720        Operand(zero_reg),
4721        bd);
4722 }
4723
4724
4725 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
4726                                    InvokeFlag flag,
4727                                    const CallWrapper& call_wrapper) {
4728   // You can't call a builtin without a valid frame.
4729   DCHECK(flag == JUMP_FUNCTION || has_frame());
4730
4731   GetBuiltinEntry(t9, id);
4732   if (flag == CALL_FUNCTION) {
4733     call_wrapper.BeforeCall(CallSize(t9));
4734     Call(t9);
4735     call_wrapper.AfterCall();
4736   } else {
4737     DCHECK(flag == JUMP_FUNCTION);
4738     Jump(t9);
4739   }
4740 }
4741
4742
4743 void MacroAssembler::GetBuiltinFunction(Register target,
4744                                         Builtins::JavaScript id) {
4745   // Load the builtins object into target register.
4746   ld(target, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
4747   ld(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset));
4748   // Load the JavaScript builtin function from the builtins object.
4749   ld(target, FieldMemOperand(target,
4750                           JSBuiltinsObject::OffsetOfFunctionWithId(id)));
4751 }
4752
4753
4754 void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
4755   DCHECK(!target.is(a1));
4756   GetBuiltinFunction(a1, id);
4757   // Load the code entry point from the builtins object.
4758   ld(target, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
4759 }
4760
4761
4762 void MacroAssembler::SetCounter(StatsCounter* counter, int value,
4763                                 Register scratch1, Register scratch2) {
4764   if (FLAG_native_code_counters && counter->Enabled()) {
4765     li(scratch1, Operand(value));
4766     li(scratch2, Operand(ExternalReference(counter)));
4767     sd(scratch1, MemOperand(scratch2));
4768   }
4769 }
4770
4771
4772 void MacroAssembler::IncrementCounter(StatsCounter* counter, int value,
4773                                       Register scratch1, Register scratch2) {
4774   DCHECK(value > 0);
4775   if (FLAG_native_code_counters && counter->Enabled()) {
4776     li(scratch2, Operand(ExternalReference(counter)));
4777     ld(scratch1, MemOperand(scratch2));
4778     Daddu(scratch1, scratch1, Operand(value));
4779     sd(scratch1, MemOperand(scratch2));
4780   }
4781 }
4782
4783
4784 void MacroAssembler::DecrementCounter(StatsCounter* counter, int value,
4785                                       Register scratch1, Register scratch2) {
4786   DCHECK(value > 0);
4787   if (FLAG_native_code_counters && counter->Enabled()) {
4788     li(scratch2, Operand(ExternalReference(counter)));
4789     ld(scratch1, MemOperand(scratch2));
4790     Dsubu(scratch1, scratch1, Operand(value));
4791     sd(scratch1, MemOperand(scratch2));
4792   }
4793 }
4794
4795
4796 // -----------------------------------------------------------------------------
4797 // Debugging.
4798
4799 void MacroAssembler::Assert(Condition cc, BailoutReason reason,
4800                             Register rs, Operand rt) {
4801   if (emit_debug_code())
4802     Check(cc, reason, rs, rt);
4803 }
4804
4805
4806 void MacroAssembler::AssertFastElements(Register elements) {
4807   if (emit_debug_code()) {
4808     DCHECK(!elements.is(at));
4809     Label ok;
4810     push(elements);
4811     ld(elements, FieldMemOperand(elements, HeapObject::kMapOffset));
4812     LoadRoot(at, Heap::kFixedArrayMapRootIndex);
4813     Branch(&ok, eq, elements, Operand(at));
4814     LoadRoot(at, Heap::kFixedDoubleArrayMapRootIndex);
4815     Branch(&ok, eq, elements, Operand(at));
4816     LoadRoot(at, Heap::kFixedCOWArrayMapRootIndex);
4817     Branch(&ok, eq, elements, Operand(at));
4818     Abort(kJSObjectWithFastElementsMapHasSlowElements);
4819     bind(&ok);
4820     pop(elements);
4821   }
4822 }
4823
4824
4825 void MacroAssembler::Check(Condition cc, BailoutReason reason,
4826                            Register rs, Operand rt) {
4827   Label L;
4828   Branch(&L, cc, rs, rt);
4829   Abort(reason);
4830   // Will not return here.
4831   bind(&L);
4832 }
4833
4834
4835 void MacroAssembler::Abort(BailoutReason reason) {
4836   Label abort_start;
4837   bind(&abort_start);
4838 #ifdef DEBUG
4839   const char* msg = GetBailoutReason(reason);
4840   if (msg != NULL) {
4841     RecordComment("Abort message: ");
4842     RecordComment(msg);
4843   }
4844
4845   if (FLAG_trap_on_abort) {
4846     stop(msg);
4847     return;
4848   }
4849 #endif
4850
4851   li(a0, Operand(Smi::FromInt(reason)));
4852   push(a0);
4853   // Disable stub call restrictions to always allow calls to abort.
4854   if (!has_frame_) {
4855     // We don't actually want to generate a pile of code for this, so just
4856     // claim there is a stack frame, without generating one.
4857     FrameScope scope(this, StackFrame::NONE);
4858     CallRuntime(Runtime::kAbort, 1);
4859   } else {
4860     CallRuntime(Runtime::kAbort, 1);
4861   }
4862   // Will not return here.
4863   if (is_trampoline_pool_blocked()) {
4864     // If the calling code cares about the exact number of
4865     // instructions generated, we insert padding here to keep the size
4866     // of the Abort macro constant.
4867     // Currently in debug mode with debug_code enabled the number of
4868     // generated instructions is 10, so we use this as a maximum value.
4869     static const int kExpectedAbortInstructions = 10;
4870     int abort_instructions = InstructionsGeneratedSince(&abort_start);
4871     DCHECK(abort_instructions <= kExpectedAbortInstructions);
4872     while (abort_instructions++ < kExpectedAbortInstructions) {
4873       nop();
4874     }
4875   }
4876 }
4877
4878
4879 void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
4880   if (context_chain_length > 0) {
4881     // Move up the chain of contexts to the context containing the slot.
4882     ld(dst, MemOperand(cp, Context::SlotOffset(Context::PREVIOUS_INDEX)));
4883     for (int i = 1; i < context_chain_length; i++) {
4884       ld(dst, MemOperand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX)));
4885     }
4886   } else {
4887     // Slot is in the current function context.  Move it into the
4888     // destination register in case we store into it (the write barrier
4889     // cannot be allowed to destroy the context in esi).
4890     Move(dst, cp);
4891   }
4892 }
4893
4894
4895 void MacroAssembler::LoadTransitionedArrayMapConditional(
4896     ElementsKind expected_kind,
4897     ElementsKind transitioned_kind,
4898     Register map_in_out,
4899     Register scratch,
4900     Label* no_map_match) {
4901   // Load the global or builtins object from the current context.
4902   ld(scratch,
4903      MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
4904   ld(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
4905
4906   // Check that the function's map is the same as the expected cached map.
4907   ld(scratch,
4908      MemOperand(scratch,
4909                 Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX)));
4910   int offset = expected_kind * kPointerSize + FixedArrayBase::kHeaderSize;
4911   ld(at, FieldMemOperand(scratch, offset));
4912   Branch(no_map_match, ne, map_in_out, Operand(at));
4913
4914   // Use the transitioned cached map.
4915   offset = transitioned_kind * kPointerSize +
4916       FixedArrayBase::kHeaderSize;
4917   ld(map_in_out, FieldMemOperand(scratch, offset));
4918 }
4919
4920
4921 void MacroAssembler::LoadGlobalFunction(int index, Register function) {
4922   // Load the global or builtins object from the current context.
4923   ld(function,
4924      MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
4925   // Load the native context from the global or builtins object.
4926   ld(function, FieldMemOperand(function,
4927                                GlobalObject::kNativeContextOffset));
4928   // Load the function from the native context.
4929   ld(function, MemOperand(function, Context::SlotOffset(index)));
4930 }
4931
4932
4933 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
4934                                                   Register map,
4935                                                   Register scratch) {
4936   // Load the initial map. The global functions all have initial maps.
4937   ld(map, FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
4938   if (emit_debug_code()) {
4939     Label ok, fail;
4940     CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, DO_SMI_CHECK);
4941     Branch(&ok);
4942     bind(&fail);
4943     Abort(kGlobalFunctionsMustHaveInitialMap);
4944     bind(&ok);
4945   }
4946 }
4947
4948
4949 void MacroAssembler::StubPrologue() {
4950     Push(ra, fp, cp);
4951     Push(Smi::FromInt(StackFrame::STUB));
4952     // Adjust FP to point to saved FP.
4953     Daddu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
4954 }
4955
4956
4957 void MacroAssembler::Prologue(bool code_pre_aging) {
4958   PredictableCodeSizeScope predictible_code_size_scope(
4959       this, kNoCodeAgeSequenceLength);
4960   // The following three instructions must remain together and unmodified
4961   // for code aging to work properly.
4962   if (code_pre_aging) {
4963     // Pre-age the code.
4964     Code* stub = Code::GetPreAgedCodeAgeStub(isolate());
4965     nop(Assembler::CODE_AGE_MARKER_NOP);
4966     // Load the stub address to t9 and call it,
4967     // GetCodeAgeAndParity() extracts the stub address from this instruction.
4968     li(t9,
4969        Operand(reinterpret_cast<uint64_t>(stub->instruction_start())),
4970        ADDRESS_LOAD);
4971     nop();  // Prevent jalr to jal optimization.
4972     jalr(t9, a0);
4973     nop();  // Branch delay slot nop.
4974     nop();  // Pad the empty space.
4975   } else {
4976     Push(ra, fp, cp, a1);
4977     nop(Assembler::CODE_AGE_SEQUENCE_NOP);
4978     nop(Assembler::CODE_AGE_SEQUENCE_NOP);
4979     nop(Assembler::CODE_AGE_SEQUENCE_NOP);
4980     // Adjust fp to point to caller's fp.
4981     Daddu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
4982   }
4983 }
4984
4985
4986 void MacroAssembler::EnterFrame(StackFrame::Type type,
4987                                 bool load_constant_pool_pointer_reg) {
4988   // Out-of-line constant pool not implemented on mips64.
4989   UNREACHABLE();
4990 }
4991
4992
4993 void MacroAssembler::EnterFrame(StackFrame::Type type) {
4994   daddiu(sp, sp, -5 * kPointerSize);
4995   li(t8, Operand(Smi::FromInt(type)));
4996   li(t9, Operand(CodeObject()), CONSTANT_SIZE);
4997   sd(ra, MemOperand(sp, 4 * kPointerSize));
4998   sd(fp, MemOperand(sp, 3 * kPointerSize));
4999   sd(cp, MemOperand(sp, 2 * kPointerSize));
5000   sd(t8, MemOperand(sp, 1 * kPointerSize));
5001   sd(t9, MemOperand(sp, 0 * kPointerSize));
5002   // Adjust FP to point to saved FP.
5003   Daddu(fp, sp,
5004        Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize));
5005 }
5006
5007
5008 void MacroAssembler::LeaveFrame(StackFrame::Type type) {
5009   mov(sp, fp);
5010   ld(fp, MemOperand(sp, 0 * kPointerSize));
5011   ld(ra, MemOperand(sp, 1 * kPointerSize));
5012   daddiu(sp, sp, 2 * kPointerSize);
5013 }
5014
5015
5016 void MacroAssembler::EnterExitFrame(bool save_doubles,
5017                                     int stack_space) {
5018   // Set up the frame structure on the stack.
5019   STATIC_ASSERT(2 * kPointerSize == ExitFrameConstants::kCallerSPDisplacement);
5020   STATIC_ASSERT(1 * kPointerSize == ExitFrameConstants::kCallerPCOffset);
5021   STATIC_ASSERT(0 * kPointerSize == ExitFrameConstants::kCallerFPOffset);
5022
5023   // This is how the stack will look:
5024   // fp + 2 (==kCallerSPDisplacement) - old stack's end
5025   // [fp + 1 (==kCallerPCOffset)] - saved old ra
5026   // [fp + 0 (==kCallerFPOffset)] - saved old fp
5027   // [fp - 1 (==kSPOffset)] - sp of the called function
5028   // [fp - 2 (==kCodeOffset)] - CodeObject
5029   // fp - (2 + stack_space + alignment) == sp == [fp - kSPOffset] - top of the
5030   //   new stack (will contain saved ra)
5031
5032   // Save registers.
5033   daddiu(sp, sp, -4 * kPointerSize);
5034   sd(ra, MemOperand(sp, 3 * kPointerSize));
5035   sd(fp, MemOperand(sp, 2 * kPointerSize));
5036   daddiu(fp, sp, 2 * kPointerSize);  // Set up new frame pointer.
5037
5038   if (emit_debug_code()) {
5039     sd(zero_reg, MemOperand(fp, ExitFrameConstants::kSPOffset));
5040   }
5041
5042   // Accessed from ExitFrame::code_slot.
5043   li(t8, Operand(CodeObject()), CONSTANT_SIZE);
5044   sd(t8, MemOperand(fp, ExitFrameConstants::kCodeOffset));
5045
5046   // Save the frame pointer and the context in top.
5047   li(t8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
5048   sd(fp, MemOperand(t8));
5049   li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
5050   sd(cp, MemOperand(t8));
5051
5052   const int frame_alignment = MacroAssembler::ActivationFrameAlignment();
5053   if (save_doubles) {
5054     // The stack is already aligned to 0 modulo 8 for stores with sdc1.
5055     int kNumOfSavedRegisters = FPURegister::kMaxNumRegisters / 2;
5056     int space = kNumOfSavedRegisters * kDoubleSize ;
5057     Dsubu(sp, sp, Operand(space));
5058     // Remember: we only need to save every 2nd double FPU value.
5059     for (int i = 0; i < kNumOfSavedRegisters; i++) {
5060       FPURegister reg = FPURegister::from_code(2 * i);
5061       sdc1(reg, MemOperand(sp, i * kDoubleSize));
5062     }
5063   }
5064
5065   // Reserve place for the return address, stack space and an optional slot
5066   // (used by the DirectCEntryStub to hold the return value if a struct is
5067   // returned) and align the frame preparing for calling the runtime function.
5068   DCHECK(stack_space >= 0);
5069   Dsubu(sp, sp, Operand((stack_space + 2) * kPointerSize));
5070   if (frame_alignment > 0) {
5071     DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
5072     And(sp, sp, Operand(-frame_alignment));  // Align stack.
5073   }
5074
5075   // Set the exit frame sp value to point just before the return address
5076   // location.
5077   daddiu(at, sp, kPointerSize);
5078   sd(at, MemOperand(fp, ExitFrameConstants::kSPOffset));
5079 }
5080
5081
5082 void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
5083                                     bool restore_context, bool do_return,
5084                                     bool argument_count_is_length) {
5085   // Optionally restore all double registers.
5086   if (save_doubles) {
5087     // Remember: we only need to restore every 2nd double FPU value.
5088     int kNumOfSavedRegisters = FPURegister::kMaxNumRegisters / 2;
5089     Dsubu(t8, fp, Operand(ExitFrameConstants::kFrameSize +
5090         kNumOfSavedRegisters * kDoubleSize));
5091     for (int i = 0; i < kNumOfSavedRegisters; i++) {
5092       FPURegister reg = FPURegister::from_code(2 * i);
5093       ldc1(reg, MemOperand(t8, i  * kDoubleSize));
5094     }
5095   }
5096
5097   // Clear top frame.
5098   li(t8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
5099   sd(zero_reg, MemOperand(t8));
5100
5101   // Restore current context from top and clear it in debug mode.
5102   if (restore_context) {
5103     li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
5104     ld(cp, MemOperand(t8));
5105   }
5106 #ifdef DEBUG
5107   li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
5108   sd(a3, MemOperand(t8));
5109 #endif
5110
5111   // Pop the arguments, restore registers, and return.
5112   mov(sp, fp);  // Respect ABI stack constraint.
5113   ld(fp, MemOperand(sp, ExitFrameConstants::kCallerFPOffset));
5114   ld(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset));
5115
5116   if (argument_count.is_valid()) {
5117     if (argument_count_is_length) {
5118       daddu(sp, sp, argument_count);
5119     } else {
5120       dsll(t8, argument_count, kPointerSizeLog2);
5121       daddu(sp, sp, t8);
5122     }
5123   }
5124
5125   if (do_return) {
5126     Ret(USE_DELAY_SLOT);
5127     // If returning, the instruction in the delay slot will be the addiu below.
5128   }
5129   daddiu(sp, sp, 2 * kPointerSize);
5130 }
5131
5132
5133 void MacroAssembler::InitializeNewString(Register string,
5134                                          Register length,
5135                                          Heap::RootListIndex map_index,
5136                                          Register scratch1,
5137                                          Register scratch2) {
5138   // dsll(scratch1, length, kSmiTagSize);
5139   dsll32(scratch1, length, 0);
5140   LoadRoot(scratch2, map_index);
5141   sd(scratch1, FieldMemOperand(string, String::kLengthOffset));
5142   li(scratch1, Operand(String::kEmptyHashField));
5143   sd(scratch2, FieldMemOperand(string, HeapObject::kMapOffset));
5144   sd(scratch1, FieldMemOperand(string, String::kHashFieldOffset));
5145 }
5146
5147
5148 int MacroAssembler::ActivationFrameAlignment() {
5149 #if V8_HOST_ARCH_MIPS || V8_HOST_ARCH_MIPS64
5150   // Running on the real platform. Use the alignment as mandated by the local
5151   // environment.
5152   // Note: This will break if we ever start generating snapshots on one Mips
5153   // platform for another Mips platform with a different alignment.
5154   return base::OS::ActivationFrameAlignment();
5155 #else  // V8_HOST_ARCH_MIPS
5156   // If we are using the simulator then we should always align to the expected
5157   // alignment. As the simulator is used to generate snapshots we do not know
5158   // if the target platform will need alignment, so this is controlled from a
5159   // flag.
5160   return FLAG_sim_stack_alignment;
5161 #endif  // V8_HOST_ARCH_MIPS
5162 }
5163
5164
5165 void MacroAssembler::AssertStackIsAligned() {
5166   if (emit_debug_code()) {
5167       const int frame_alignment = ActivationFrameAlignment();
5168       const int frame_alignment_mask = frame_alignment - 1;
5169
5170       if (frame_alignment > kPointerSize) {
5171         Label alignment_as_expected;
5172         DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
5173         andi(at, sp, frame_alignment_mask);
5174         Branch(&alignment_as_expected, eq, at, Operand(zero_reg));
5175         // Don't use Check here, as it will call Runtime_Abort re-entering here.
5176         stop("Unexpected stack alignment");
5177         bind(&alignment_as_expected);
5178       }
5179     }
5180 }
5181
5182
5183 void MacroAssembler::JumpIfNotPowerOfTwoOrZero(
5184     Register reg,
5185     Register scratch,
5186     Label* not_power_of_two_or_zero) {
5187   Dsubu(scratch, reg, Operand(1));
5188   Branch(USE_DELAY_SLOT, not_power_of_two_or_zero, lt,
5189          scratch, Operand(zero_reg));
5190   and_(at, scratch, reg);  // In the delay slot.
5191   Branch(not_power_of_two_or_zero, ne, at, Operand(zero_reg));
5192 }
5193
5194
5195 void MacroAssembler::SmiTagCheckOverflow(Register reg, Register overflow) {
5196   DCHECK(!reg.is(overflow));
5197   mov(overflow, reg);  // Save original value.
5198   SmiTag(reg);
5199   xor_(overflow, overflow, reg);  // Overflow if (value ^ 2 * value) < 0.
5200 }
5201
5202
5203 void MacroAssembler::SmiTagCheckOverflow(Register dst,
5204                                          Register src,
5205                                          Register overflow) {
5206   if (dst.is(src)) {
5207     // Fall back to slower case.
5208     SmiTagCheckOverflow(dst, overflow);
5209   } else {
5210     DCHECK(!dst.is(src));
5211     DCHECK(!dst.is(overflow));
5212     DCHECK(!src.is(overflow));
5213     SmiTag(dst, src);
5214     xor_(overflow, dst, src);  // Overflow if (value ^ 2 * value) < 0.
5215   }
5216 }
5217
5218
5219 void MacroAssembler::SmiLoadUntag(Register dst, MemOperand src) {
5220   if (SmiValuesAre32Bits()) {
5221     lw(dst, UntagSmiMemOperand(src.rm(), src.offset()));
5222   } else {
5223     lw(dst, src);
5224     SmiUntag(dst);
5225   }
5226 }
5227
5228
5229 void MacroAssembler::SmiLoadScale(Register dst, MemOperand src, int scale) {
5230   if (SmiValuesAre32Bits()) {
5231     // TODO(plind): not clear if lw or ld faster here, need micro-benchmark.
5232     lw(dst, UntagSmiMemOperand(src.rm(), src.offset()));
5233     dsll(dst, dst, scale);
5234   } else {
5235     lw(dst, src);
5236     DCHECK(scale >= kSmiTagSize);
5237     sll(dst, dst, scale - kSmiTagSize);
5238   }
5239 }
5240
5241
5242 // Returns 2 values: the Smi and a scaled version of the int within the Smi.
5243 void MacroAssembler::SmiLoadWithScale(Register d_smi,
5244                                       Register d_scaled,
5245                                       MemOperand src,
5246                                       int scale) {
5247   if (SmiValuesAre32Bits()) {
5248     ld(d_smi, src);
5249     dsra(d_scaled, d_smi, kSmiShift - scale);
5250   } else {
5251     lw(d_smi, src);
5252     DCHECK(scale >= kSmiTagSize);
5253     sll(d_scaled, d_smi, scale - kSmiTagSize);
5254   }
5255 }
5256
5257
5258 // Returns 2 values: the untagged Smi (int32) and scaled version of that int.
5259 void MacroAssembler::SmiLoadUntagWithScale(Register d_int,
5260                                            Register d_scaled,
5261                                            MemOperand src,
5262                                            int scale) {
5263   if (SmiValuesAre32Bits()) {
5264     lw(d_int, UntagSmiMemOperand(src.rm(), src.offset()));
5265     dsll(d_scaled, d_int, scale);
5266   } else {
5267     lw(d_int, src);
5268     // Need both the int and the scaled in, so use two instructions.
5269     SmiUntag(d_int);
5270     sll(d_scaled, d_int, scale);
5271   }
5272 }
5273
5274
5275 void MacroAssembler::UntagAndJumpIfSmi(Register dst,
5276                                        Register src,
5277                                        Label* smi_case) {
5278   // DCHECK(!dst.is(src));
5279   JumpIfSmi(src, smi_case, at, USE_DELAY_SLOT);
5280   SmiUntag(dst, src);
5281 }
5282
5283
5284 void MacroAssembler::UntagAndJumpIfNotSmi(Register dst,
5285                                           Register src,
5286                                           Label* non_smi_case) {
5287   // DCHECK(!dst.is(src));
5288   JumpIfNotSmi(src, non_smi_case, at, USE_DELAY_SLOT);
5289   SmiUntag(dst, src);
5290 }
5291
5292 void MacroAssembler::JumpIfSmi(Register value,
5293                                Label* smi_label,
5294                                Register scratch,
5295                                BranchDelaySlot bd) {
5296   DCHECK_EQ(0, kSmiTag);
5297   andi(scratch, value, kSmiTagMask);
5298   Branch(bd, smi_label, eq, scratch, Operand(zero_reg));
5299 }
5300
5301 void MacroAssembler::JumpIfNotSmi(Register value,
5302                                   Label* not_smi_label,
5303                                   Register scratch,
5304                                   BranchDelaySlot bd) {
5305   DCHECK_EQ(0, kSmiTag);
5306   andi(scratch, value, kSmiTagMask);
5307   Branch(bd, not_smi_label, ne, scratch, Operand(zero_reg));
5308 }
5309
5310
5311 void MacroAssembler::JumpIfNotBothSmi(Register reg1,
5312                                       Register reg2,
5313                                       Label* on_not_both_smi) {
5314   STATIC_ASSERT(kSmiTag == 0);
5315   // TODO(plind): Find some better to fix this assert issue.
5316 #if defined(__APPLE__)
5317   DCHECK_EQ(1, kSmiTagMask);
5318 #else
5319   DCHECK_EQ((int64_t)1, kSmiTagMask);
5320 #endif
5321   or_(at, reg1, reg2);
5322   JumpIfNotSmi(at, on_not_both_smi);
5323 }
5324
5325
5326 void MacroAssembler::JumpIfEitherSmi(Register reg1,
5327                                      Register reg2,
5328                                      Label* on_either_smi) {
5329   STATIC_ASSERT(kSmiTag == 0);
5330   // TODO(plind): Find some better to fix this assert issue.
5331 #if defined(__APPLE__)
5332   DCHECK_EQ(1, kSmiTagMask);
5333 #else
5334   DCHECK_EQ((int64_t)1, kSmiTagMask);
5335 #endif
5336   // Both Smi tags must be 1 (not Smi).
5337   and_(at, reg1, reg2);
5338   JumpIfSmi(at, on_either_smi);
5339 }
5340
5341
5342 void MacroAssembler::AssertNotSmi(Register object) {
5343   if (emit_debug_code()) {
5344     STATIC_ASSERT(kSmiTag == 0);
5345     andi(at, object, kSmiTagMask);
5346     Check(ne, kOperandIsASmi, at, Operand(zero_reg));
5347   }
5348 }
5349
5350
5351 void MacroAssembler::AssertSmi(Register object) {
5352   if (emit_debug_code()) {
5353     STATIC_ASSERT(kSmiTag == 0);
5354     andi(at, object, kSmiTagMask);
5355     Check(eq, kOperandIsASmi, at, Operand(zero_reg));
5356   }
5357 }
5358
5359
5360 void MacroAssembler::AssertString(Register object) {
5361   if (emit_debug_code()) {
5362     STATIC_ASSERT(kSmiTag == 0);
5363     SmiTst(object, a4);
5364     Check(ne, kOperandIsASmiAndNotAString, a4, Operand(zero_reg));
5365     push(object);
5366     ld(object, FieldMemOperand(object, HeapObject::kMapOffset));
5367     lbu(object, FieldMemOperand(object, Map::kInstanceTypeOffset));
5368     Check(lo, kOperandIsNotAString, object, Operand(FIRST_NONSTRING_TYPE));
5369     pop(object);
5370   }
5371 }
5372
5373
5374 void MacroAssembler::AssertName(Register object) {
5375   if (emit_debug_code()) {
5376     STATIC_ASSERT(kSmiTag == 0);
5377     SmiTst(object, a4);
5378     Check(ne, kOperandIsASmiAndNotAName, a4, Operand(zero_reg));
5379     push(object);
5380     ld(object, FieldMemOperand(object, HeapObject::kMapOffset));
5381     lbu(object, FieldMemOperand(object, Map::kInstanceTypeOffset));
5382     Check(le, kOperandIsNotAName, object, Operand(LAST_NAME_TYPE));
5383     pop(object);
5384   }
5385 }
5386
5387
5388 void MacroAssembler::AssertUndefinedOrAllocationSite(Register object,
5389                                                      Register scratch) {
5390   if (emit_debug_code()) {
5391     Label done_checking;
5392     AssertNotSmi(object);
5393     LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
5394     Branch(&done_checking, eq, object, Operand(scratch));
5395     push(object);
5396     ld(object, FieldMemOperand(object, HeapObject::kMapOffset));
5397     LoadRoot(scratch, Heap::kAllocationSiteMapRootIndex);
5398     Assert(eq, kExpectedUndefinedOrCell, object, Operand(scratch));
5399     pop(object);
5400     bind(&done_checking);
5401   }
5402 }
5403
5404
5405 void MacroAssembler::AssertIsRoot(Register reg, Heap::RootListIndex index) {
5406   if (emit_debug_code()) {
5407     DCHECK(!reg.is(at));
5408     LoadRoot(at, index);
5409     Check(eq, kHeapNumberMapRegisterClobbered, reg, Operand(at));
5410   }
5411 }
5412
5413
5414 void MacroAssembler::JumpIfNotHeapNumber(Register object,
5415                                          Register heap_number_map,
5416                                          Register scratch,
5417                                          Label* on_not_heap_number) {
5418   ld(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
5419   AssertIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
5420   Branch(on_not_heap_number, ne, scratch, Operand(heap_number_map));
5421 }
5422
5423
5424 void MacroAssembler::LookupNumberStringCache(Register object,
5425                                              Register result,
5426                                              Register scratch1,
5427                                              Register scratch2,
5428                                              Register scratch3,
5429                                              Label* not_found) {
5430   // Use of registers. Register result is used as a temporary.
5431   Register number_string_cache = result;
5432   Register mask = scratch3;
5433
5434   // Load the number string cache.
5435   LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);
5436
5437   // Make the hash mask from the length of the number string cache. It
5438   // contains two elements (number and string) for each cache entry.
5439   ld(mask, FieldMemOperand(number_string_cache, FixedArray::kLengthOffset));
5440   // Divide length by two (length is a smi).
5441   // dsra(mask, mask, kSmiTagSize + 1);
5442   dsra32(mask, mask, 1);
5443   Daddu(mask, mask, -1);  // Make mask.
5444
5445   // Calculate the entry in the number string cache. The hash value in the
5446   // number string cache for smis is just the smi value, and the hash for
5447   // doubles is the xor of the upper and lower words. See
5448   // Heap::GetNumberStringCache.
5449   Label is_smi;
5450   Label load_result_from_cache;
5451   JumpIfSmi(object, &is_smi);
5452   CheckMap(object,
5453            scratch1,
5454            Heap::kHeapNumberMapRootIndex,
5455            not_found,
5456            DONT_DO_SMI_CHECK);
5457
5458   STATIC_ASSERT(8 == kDoubleSize);
5459   Daddu(scratch1,
5460        object,
5461        Operand(HeapNumber::kValueOffset - kHeapObjectTag));
5462   ld(scratch2, MemOperand(scratch1, kPointerSize));
5463   ld(scratch1, MemOperand(scratch1, 0));
5464   Xor(scratch1, scratch1, Operand(scratch2));
5465   And(scratch1, scratch1, Operand(mask));
5466
5467   // Calculate address of entry in string cache: each entry consists
5468   // of two pointer sized fields.
5469   dsll(scratch1, scratch1, kPointerSizeLog2 + 1);
5470   Daddu(scratch1, number_string_cache, scratch1);
5471
5472   Register probe = mask;
5473   ld(probe, FieldMemOperand(scratch1, FixedArray::kHeaderSize));
5474   JumpIfSmi(probe, not_found);
5475   ldc1(f12, FieldMemOperand(object, HeapNumber::kValueOffset));
5476   ldc1(f14, FieldMemOperand(probe, HeapNumber::kValueOffset));
5477   BranchF(&load_result_from_cache, NULL, eq, f12, f14);
5478   Branch(not_found);
5479
5480   bind(&is_smi);
5481   Register scratch = scratch1;
5482   // dsra(scratch, object, 1);   // Shift away the tag.
5483   dsra32(scratch, scratch, 0);
5484   And(scratch, mask, Operand(scratch));
5485
5486   // Calculate address of entry in string cache: each entry consists
5487   // of two pointer sized fields.
5488   dsll(scratch, scratch, kPointerSizeLog2 + 1);
5489   Daddu(scratch, number_string_cache, scratch);
5490
5491   // Check if the entry is the smi we are looking for.
5492   ld(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize));
5493   Branch(not_found, ne, object, Operand(probe));
5494
5495   // Get the result from the cache.
5496   bind(&load_result_from_cache);
5497   ld(result, FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize));
5498
5499   IncrementCounter(isolate()->counters()->number_to_string_native(),
5500                    1,
5501                    scratch1,
5502                    scratch2);
5503 }
5504
5505
5506 void MacroAssembler::JumpIfNonSmisNotBothSequentialOneByteStrings(
5507     Register first, Register second, Register scratch1, Register scratch2,
5508     Label* failure) {
5509   // Test that both first and second are sequential one-byte strings.
5510   // Assume that they are non-smis.
5511   ld(scratch1, FieldMemOperand(first, HeapObject::kMapOffset));
5512   ld(scratch2, FieldMemOperand(second, HeapObject::kMapOffset));
5513   lbu(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
5514   lbu(scratch2, FieldMemOperand(scratch2, Map::kInstanceTypeOffset));
5515
5516   JumpIfBothInstanceTypesAreNotSequentialOneByte(scratch1, scratch2, scratch1,
5517                                                  scratch2, failure);
5518 }
5519
5520
5521 void MacroAssembler::JumpIfNotBothSequentialOneByteStrings(Register first,
5522                                                            Register second,
5523                                                            Register scratch1,
5524                                                            Register scratch2,
5525                                                            Label* failure) {
5526   // Check that neither is a smi.
5527   STATIC_ASSERT(kSmiTag == 0);
5528   And(scratch1, first, Operand(second));
5529   JumpIfSmi(scratch1, failure);
5530   JumpIfNonSmisNotBothSequentialOneByteStrings(first, second, scratch1,
5531                                                scratch2, failure);
5532 }
5533
5534
5535 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte(
5536     Register first, Register second, Register scratch1, Register scratch2,
5537     Label* failure) {
5538   const int kFlatOneByteStringMask =
5539       kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask;
5540   const int kFlatOneByteStringTag =
5541       kStringTag | kOneByteStringTag | kSeqStringTag;
5542   DCHECK(kFlatOneByteStringTag <= 0xffff);  // Ensure this fits 16-bit immed.
5543   andi(scratch1, first, kFlatOneByteStringMask);
5544   Branch(failure, ne, scratch1, Operand(kFlatOneByteStringTag));
5545   andi(scratch2, second, kFlatOneByteStringMask);
5546   Branch(failure, ne, scratch2, Operand(kFlatOneByteStringTag));
5547 }
5548
5549
5550 void MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte(Register type,
5551                                                               Register scratch,
5552                                                               Label* failure) {
5553   const int kFlatOneByteStringMask =
5554       kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask;
5555   const int kFlatOneByteStringTag =
5556       kStringTag | kOneByteStringTag | kSeqStringTag;
5557   And(scratch, type, Operand(kFlatOneByteStringMask));
5558   Branch(failure, ne, scratch, Operand(kFlatOneByteStringTag));
5559 }
5560
5561
5562 static const int kRegisterPassedArguments = (kMipsAbi == kN64) ? 8 : 4;
5563
5564 int MacroAssembler::CalculateStackPassedWords(int num_reg_arguments,
5565                                               int num_double_arguments) {
5566   int stack_passed_words = 0;
5567   num_reg_arguments += 2 * num_double_arguments;
5568
5569   // O32: Up to four simple arguments are passed in registers a0..a3.
5570   // N64: Up to eight simple arguments are passed in registers a0..a7.
5571   if (num_reg_arguments > kRegisterPassedArguments) {
5572     stack_passed_words += num_reg_arguments - kRegisterPassedArguments;
5573   }
5574   stack_passed_words += kCArgSlotCount;
5575   return stack_passed_words;
5576 }
5577
5578
5579 void MacroAssembler::EmitSeqStringSetCharCheck(Register string,
5580                                                Register index,
5581                                                Register value,
5582                                                Register scratch,
5583                                                uint32_t encoding_mask) {
5584   Label is_object;
5585   SmiTst(string, at);
5586   Check(ne, kNonObject, at, Operand(zero_reg));
5587
5588   ld(at, FieldMemOperand(string, HeapObject::kMapOffset));
5589   lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset));
5590
5591   andi(at, at, kStringRepresentationMask | kStringEncodingMask);
5592   li(scratch, Operand(encoding_mask));
5593   Check(eq, kUnexpectedStringType, at, Operand(scratch));
5594
5595   // TODO(plind): requires Smi size check code for mips32.
5596
5597   ld(at, FieldMemOperand(string, String::kLengthOffset));
5598   Check(lt, kIndexIsTooLarge, index, Operand(at));
5599
5600   DCHECK(Smi::FromInt(0) == 0);
5601   Check(ge, kIndexIsNegative, index, Operand(zero_reg));
5602 }
5603
5604
5605 void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
5606                                           int num_double_arguments,
5607                                           Register scratch) {
5608   int frame_alignment = ActivationFrameAlignment();
5609
5610   // n64: Up to eight simple arguments in a0..a3, a4..a7, No argument slots.
5611   // O32: Up to four simple arguments are passed in registers a0..a3.
5612   // Those four arguments must have reserved argument slots on the stack for
5613   // mips, even though those argument slots are not normally used.
5614   // Both ABIs: Remaining arguments are pushed on the stack, above (higher
5615   // address than) the (O32) argument slots. (arg slot calculation handled by
5616   // CalculateStackPassedWords()).
5617   int stack_passed_arguments = CalculateStackPassedWords(
5618       num_reg_arguments, num_double_arguments);
5619   if (frame_alignment > kPointerSize) {
5620     // Make stack end at alignment and make room for num_arguments - 4 words
5621     // and the original value of sp.
5622     mov(scratch, sp);
5623     Dsubu(sp, sp, Operand((stack_passed_arguments + 1) * kPointerSize));
5624     DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
5625     And(sp, sp, Operand(-frame_alignment));
5626     sd(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize));
5627   } else {
5628     Dsubu(sp, sp, Operand(stack_passed_arguments * kPointerSize));
5629   }
5630 }
5631
5632
5633 void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
5634                                           Register scratch) {
5635   PrepareCallCFunction(num_reg_arguments, 0, scratch);
5636 }
5637
5638
5639 void MacroAssembler::CallCFunction(ExternalReference function,
5640                                    int num_reg_arguments,
5641                                    int num_double_arguments) {
5642   li(t8, Operand(function));
5643   CallCFunctionHelper(t8, num_reg_arguments, num_double_arguments);
5644 }
5645
5646
5647 void MacroAssembler::CallCFunction(Register function,
5648                                    int num_reg_arguments,
5649                                    int num_double_arguments) {
5650   CallCFunctionHelper(function, num_reg_arguments, num_double_arguments);
5651 }
5652
5653
5654 void MacroAssembler::CallCFunction(ExternalReference function,
5655                                    int num_arguments) {
5656   CallCFunction(function, num_arguments, 0);
5657 }
5658
5659
5660 void MacroAssembler::CallCFunction(Register function,
5661                                    int num_arguments) {
5662   CallCFunction(function, num_arguments, 0);
5663 }
5664
5665
5666 void MacroAssembler::CallCFunctionHelper(Register function,
5667                                          int num_reg_arguments,
5668                                          int num_double_arguments) {
5669   DCHECK(has_frame());
5670   // Make sure that the stack is aligned before calling a C function unless
5671   // running in the simulator. The simulator has its own alignment check which
5672   // provides more information.
5673   // The argument stots are presumed to have been set up by
5674   // PrepareCallCFunction. The C function must be called via t9, for mips ABI.
5675
5676 #if V8_HOST_ARCH_MIPS || V8_HOST_ARCH_MIPS64
5677   if (emit_debug_code()) {
5678     int frame_alignment = base::OS::ActivationFrameAlignment();
5679     int frame_alignment_mask = frame_alignment - 1;
5680     if (frame_alignment > kPointerSize) {
5681       DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
5682       Label alignment_as_expected;
5683       And(at, sp, Operand(frame_alignment_mask));
5684       Branch(&alignment_as_expected, eq, at, Operand(zero_reg));
5685       // Don't use Check here, as it will call Runtime_Abort possibly
5686       // re-entering here.
5687       stop("Unexpected alignment in CallCFunction");
5688       bind(&alignment_as_expected);
5689     }
5690   }
5691 #endif  // V8_HOST_ARCH_MIPS
5692
5693   // Just call directly. The function called cannot cause a GC, or
5694   // allow preemption, so the return address in the link register
5695   // stays correct.
5696
5697   if (!function.is(t9)) {
5698     mov(t9, function);
5699     function = t9;
5700   }
5701
5702   Call(function);
5703
5704   int stack_passed_arguments = CalculateStackPassedWords(
5705       num_reg_arguments, num_double_arguments);
5706
5707   if (base::OS::ActivationFrameAlignment() > kPointerSize) {
5708     ld(sp, MemOperand(sp, stack_passed_arguments * kPointerSize));
5709   } else {
5710     Daddu(sp, sp, Operand(stack_passed_arguments * kPointerSize));
5711   }
5712 }
5713
5714
5715 #undef BRANCH_ARGS_CHECK
5716
5717
5718 void MacroAssembler::CheckPageFlag(
5719     Register object,
5720     Register scratch,
5721     int mask,
5722     Condition cc,
5723     Label* condition_met) {
5724   And(scratch, object, Operand(~Page::kPageAlignmentMask));
5725   ld(scratch, MemOperand(scratch, MemoryChunk::kFlagsOffset));
5726   And(scratch, scratch, Operand(mask));
5727   Branch(condition_met, cc, scratch, Operand(zero_reg));
5728 }
5729
5730
5731 void MacroAssembler::JumpIfBlack(Register object,
5732                                  Register scratch0,
5733                                  Register scratch1,
5734                                  Label* on_black) {
5735   HasColor(object, scratch0, scratch1, on_black, 1, 0);  // kBlackBitPattern.
5736   DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0);
5737 }
5738
5739
5740 void MacroAssembler::HasColor(Register object,
5741                               Register bitmap_scratch,
5742                               Register mask_scratch,
5743                               Label* has_color,
5744                               int first_bit,
5745                               int second_bit) {
5746   DCHECK(!AreAliased(object, bitmap_scratch, mask_scratch, t8));
5747   DCHECK(!AreAliased(object, bitmap_scratch, mask_scratch, t9));
5748
5749   GetMarkBits(object, bitmap_scratch, mask_scratch);
5750
5751   Label other_color;
5752   // Note that we are using a 4-byte aligned 8-byte load.
5753   Uld(t9, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
5754   And(t8, t9, Operand(mask_scratch));
5755   Branch(&other_color, first_bit == 1 ? eq : ne, t8, Operand(zero_reg));
5756   // Shift left 1 by adding.
5757   Daddu(mask_scratch, mask_scratch, Operand(mask_scratch));
5758   And(t8, t9, Operand(mask_scratch));
5759   Branch(has_color, second_bit == 1 ? ne : eq, t8, Operand(zero_reg));
5760
5761   bind(&other_color);
5762 }
5763
5764
5765 // Detect some, but not all, common pointer-free objects.  This is used by the
5766 // incremental write barrier which doesn't care about oddballs (they are always
5767 // marked black immediately so this code is not hit).
5768 void MacroAssembler::JumpIfDataObject(Register value,
5769                                       Register scratch,
5770                                       Label* not_data_object) {
5771   DCHECK(!AreAliased(value, scratch, t8, no_reg));
5772   Label is_data_object;
5773   ld(scratch, FieldMemOperand(value, HeapObject::kMapOffset));
5774   LoadRoot(t8, Heap::kHeapNumberMapRootIndex);
5775   Branch(&is_data_object, eq, t8, Operand(scratch));
5776   DCHECK(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1);
5777   DCHECK(kNotStringTag == 0x80 && kIsNotStringMask == 0x80);
5778   // If it's a string and it's not a cons string then it's an object containing
5779   // no GC pointers.
5780   lbu(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
5781   And(t8, scratch, Operand(kIsIndirectStringMask | kIsNotStringMask));
5782   Branch(not_data_object, ne, t8, Operand(zero_reg));
5783   bind(&is_data_object);
5784 }
5785
5786
5787 void MacroAssembler::GetMarkBits(Register addr_reg,
5788                                  Register bitmap_reg,
5789                                  Register mask_reg) {
5790   DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, no_reg));
5791   // addr_reg is divided into fields:
5792   // |63        page base        20|19    high      8|7   shift   3|2  0|
5793   // 'high' gives the index of the cell holding color bits for the object.
5794   // 'shift' gives the offset in the cell for this object's color.
5795   And(bitmap_reg, addr_reg, Operand(~Page::kPageAlignmentMask));
5796   Ext(mask_reg, addr_reg, kPointerSizeLog2, Bitmap::kBitsPerCellLog2);
5797   const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2;
5798   Ext(t8, addr_reg, kLowBits, kPageSizeBits - kLowBits);
5799   dsll(t8, t8, Bitmap::kBytesPerCellLog2);
5800   Daddu(bitmap_reg, bitmap_reg, t8);
5801   li(t8, Operand(1));
5802   dsllv(mask_reg, t8, mask_reg);
5803 }
5804
5805
5806 void MacroAssembler::EnsureNotWhite(
5807     Register value,
5808     Register bitmap_scratch,
5809     Register mask_scratch,
5810     Register load_scratch,
5811     Label* value_is_white_and_not_data) {
5812   DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, t8));
5813   GetMarkBits(value, bitmap_scratch, mask_scratch);
5814
5815   // If the value is black or grey we don't need to do anything.
5816   DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0);
5817   DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0);
5818   DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0);
5819   DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
5820
5821   Label done;
5822
5823   // Since both black and grey have a 1 in the first position and white does
5824   // not have a 1 there we only need to check one bit.
5825   // Note that we are using a 4-byte aligned 8-byte load.
5826   Uld(load_scratch, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
5827   And(t8, mask_scratch, load_scratch);
5828   Branch(&done, ne, t8, Operand(zero_reg));
5829
5830   if (emit_debug_code()) {
5831     // Check for impossible bit pattern.
5832     Label ok;
5833     // sll may overflow, making the check conservative.
5834     dsll(t8, mask_scratch, 1);
5835     And(t8, load_scratch, t8);
5836     Branch(&ok, eq, t8, Operand(zero_reg));
5837     stop("Impossible marking bit pattern");
5838     bind(&ok);
5839   }
5840
5841   // Value is white.  We check whether it is data that doesn't need scanning.
5842   // Currently only checks for HeapNumber and non-cons strings.
5843   Register map = load_scratch;  // Holds map while checking type.
5844   Register length = load_scratch;  // Holds length of object after testing type.
5845   Label is_data_object;
5846
5847   // Check for heap-number
5848   ld(map, FieldMemOperand(value, HeapObject::kMapOffset));
5849   LoadRoot(t8, Heap::kHeapNumberMapRootIndex);
5850   {
5851     Label skip;
5852     Branch(&skip, ne, t8, Operand(map));
5853     li(length, HeapNumber::kSize);
5854     Branch(&is_data_object);
5855     bind(&skip);
5856   }
5857
5858   // Check for strings.
5859   DCHECK(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1);
5860   DCHECK(kNotStringTag == 0x80 && kIsNotStringMask == 0x80);
5861   // If it's a string and it's not a cons string then it's an object containing
5862   // no GC pointers.
5863   Register instance_type = load_scratch;
5864   lbu(instance_type, FieldMemOperand(map, Map::kInstanceTypeOffset));
5865   And(t8, instance_type, Operand(kIsIndirectStringMask | kIsNotStringMask));
5866   Branch(value_is_white_and_not_data, ne, t8, Operand(zero_reg));
5867   // It's a non-indirect (non-cons and non-slice) string.
5868   // If it's external, the length is just ExternalString::kSize.
5869   // Otherwise it's String::kHeaderSize + string->length() * (1 or 2).
5870   // External strings are the only ones with the kExternalStringTag bit
5871   // set.
5872   DCHECK_EQ(0, kSeqStringTag & kExternalStringTag);
5873   DCHECK_EQ(0, kConsStringTag & kExternalStringTag);
5874   And(t8, instance_type, Operand(kExternalStringTag));
5875   {
5876     Label skip;
5877     Branch(&skip, eq, t8, Operand(zero_reg));
5878     li(length, ExternalString::kSize);
5879     Branch(&is_data_object);
5880     bind(&skip);
5881   }
5882
5883   // Sequential string, either Latin1 or UC16.
5884   // For Latin1 (char-size of 1) we shift the smi tag away to get the length.
5885   // For UC16 (char-size of 2) we just leave the smi tag in place, thereby
5886   // getting the length multiplied by 2.
5887   DCHECK(kOneByteStringTag == 4 && kStringEncodingMask == 4);
5888   DCHECK(kSmiTag == 0 && kSmiTagSize == 1);
5889   lw(t9, UntagSmiFieldMemOperand(value, String::kLengthOffset));
5890   And(t8, instance_type, Operand(kStringEncodingMask));
5891   {
5892     Label skip;
5893     Branch(&skip, ne, t8, Operand(zero_reg));
5894     // Adjust length for UC16.
5895     dsll(t9, t9, 1);
5896     bind(&skip);
5897   }
5898   Daddu(length, t9, Operand(SeqString::kHeaderSize + kObjectAlignmentMask));
5899   DCHECK(!length.is(t8));
5900   And(length, length, Operand(~kObjectAlignmentMask));
5901
5902   bind(&is_data_object);
5903   // Value is a data object, and it is white.  Mark it black.  Since we know
5904   // that the object is white we can make it black by flipping one bit.
5905   Uld(t8, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
5906   Or(t8, t8, Operand(mask_scratch));
5907   Usd(t8, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
5908
5909   And(bitmap_scratch, bitmap_scratch, Operand(~Page::kPageAlignmentMask));
5910   Uld(t8, MemOperand(bitmap_scratch, MemoryChunk::kLiveBytesOffset));
5911   Daddu(t8, t8, Operand(length));
5912   Usd(t8, MemOperand(bitmap_scratch, MemoryChunk::kLiveBytesOffset));
5913
5914   bind(&done);
5915 }
5916
5917
5918 void MacroAssembler::LoadInstanceDescriptors(Register map,
5919                                              Register descriptors) {
5920   ld(descriptors, FieldMemOperand(map, Map::kDescriptorsOffset));
5921 }
5922
5923
5924 void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) {
5925   ld(dst, FieldMemOperand(map, Map::kBitField3Offset));
5926   DecodeField<Map::NumberOfOwnDescriptorsBits>(dst);
5927 }
5928
5929
5930 void MacroAssembler::EnumLength(Register dst, Register map) {
5931   STATIC_ASSERT(Map::EnumLengthBits::kShift == 0);
5932   ld(dst, FieldMemOperand(map, Map::kBitField3Offset));
5933   And(dst, dst, Operand(Map::EnumLengthBits::kMask));
5934   SmiTag(dst);
5935 }
5936
5937
5938 void MacroAssembler::LoadAccessor(Register dst, Register holder,
5939                                   int accessor_index,
5940                                   AccessorComponent accessor) {
5941   ld(dst, FieldMemOperand(holder, HeapObject::kMapOffset));
5942   LoadInstanceDescriptors(dst, dst);
5943   ld(dst,
5944      FieldMemOperand(dst, DescriptorArray::GetValueOffset(accessor_index)));
5945   int offset = accessor == ACCESSOR_GETTER ? AccessorPair::kGetterOffset
5946                                            : AccessorPair::kSetterOffset;
5947   ld(dst, FieldMemOperand(dst, offset));
5948 }
5949
5950
5951 void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) {
5952   Register  empty_fixed_array_value = a6;
5953   LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex);
5954   Label next, start;
5955   mov(a2, a0);
5956
5957   // Check if the enum length field is properly initialized, indicating that
5958   // there is an enum cache.
5959   ld(a1, FieldMemOperand(a2, HeapObject::kMapOffset));
5960
5961   EnumLength(a3, a1);
5962   Branch(
5963       call_runtime, eq, a3, Operand(Smi::FromInt(kInvalidEnumCacheSentinel)));
5964
5965   jmp(&start);
5966
5967   bind(&next);
5968   ld(a1, FieldMemOperand(a2, HeapObject::kMapOffset));
5969
5970   // For all objects but the receiver, check that the cache is empty.
5971   EnumLength(a3, a1);
5972   Branch(call_runtime, ne, a3, Operand(Smi::FromInt(0)));
5973
5974   bind(&start);
5975
5976   // Check that there are no elements. Register a2 contains the current JS
5977   // object we've reached through the prototype chain.
5978   Label no_elements;
5979   ld(a2, FieldMemOperand(a2, JSObject::kElementsOffset));
5980   Branch(&no_elements, eq, a2, Operand(empty_fixed_array_value));
5981
5982   // Second chance, the object may be using the empty slow element dictionary.
5983   LoadRoot(at, Heap::kEmptySlowElementDictionaryRootIndex);
5984   Branch(call_runtime, ne, a2, Operand(at));
5985
5986   bind(&no_elements);
5987   ld(a2, FieldMemOperand(a1, Map::kPrototypeOffset));
5988   Branch(&next, ne, a2, Operand(null_value));
5989 }
5990
5991
5992 void MacroAssembler::ClampUint8(Register output_reg, Register input_reg) {
5993   DCHECK(!output_reg.is(input_reg));
5994   Label done;
5995   li(output_reg, Operand(255));
5996   // Normal branch: nop in delay slot.
5997   Branch(&done, gt, input_reg, Operand(output_reg));
5998   // Use delay slot in this branch.
5999   Branch(USE_DELAY_SLOT, &done, lt, input_reg, Operand(zero_reg));
6000   mov(output_reg, zero_reg);  // In delay slot.
6001   mov(output_reg, input_reg);  // Value is in range 0..255.
6002   bind(&done);
6003 }
6004
6005
6006 void MacroAssembler::ClampDoubleToUint8(Register result_reg,
6007                                         DoubleRegister input_reg,
6008                                         DoubleRegister temp_double_reg) {
6009   Label above_zero;
6010   Label done;
6011   Label in_bounds;
6012
6013   Move(temp_double_reg, 0.0);
6014   BranchF(&above_zero, NULL, gt, input_reg, temp_double_reg);
6015
6016   // Double value is less than zero, NaN or Inf, return 0.
6017   mov(result_reg, zero_reg);
6018   Branch(&done);
6019
6020   // Double value is >= 255, return 255.
6021   bind(&above_zero);
6022   Move(temp_double_reg, 255.0);
6023   BranchF(&in_bounds, NULL, le, input_reg, temp_double_reg);
6024   li(result_reg, Operand(255));
6025   Branch(&done);
6026
6027   // In 0-255 range, round and truncate.
6028   bind(&in_bounds);
6029   cvt_w_d(temp_double_reg, input_reg);
6030   mfc1(result_reg, temp_double_reg);
6031   bind(&done);
6032 }
6033
6034
6035 void MacroAssembler::TestJSArrayForAllocationMemento(
6036     Register receiver_reg,
6037     Register scratch_reg,
6038     Label* no_memento_found,
6039     Condition cond,
6040     Label* allocation_memento_present) {
6041   ExternalReference new_space_start =
6042       ExternalReference::new_space_start(isolate());
6043   ExternalReference new_space_allocation_top =
6044       ExternalReference::new_space_allocation_top_address(isolate());
6045   Daddu(scratch_reg, receiver_reg,
6046        Operand(JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag));
6047   Branch(no_memento_found, lt, scratch_reg, Operand(new_space_start));
6048   li(at, Operand(new_space_allocation_top));
6049   ld(at, MemOperand(at));
6050   Branch(no_memento_found, gt, scratch_reg, Operand(at));
6051   ld(scratch_reg, MemOperand(scratch_reg, -AllocationMemento::kSize));
6052   if (allocation_memento_present) {
6053     Branch(allocation_memento_present, cond, scratch_reg,
6054            Operand(isolate()->factory()->allocation_memento_map()));
6055   }
6056 }
6057
6058
6059 Register GetRegisterThatIsNotOneOf(Register reg1,
6060                                    Register reg2,
6061                                    Register reg3,
6062                                    Register reg4,
6063                                    Register reg5,
6064                                    Register reg6) {
6065   RegList regs = 0;
6066   if (reg1.is_valid()) regs |= reg1.bit();
6067   if (reg2.is_valid()) regs |= reg2.bit();
6068   if (reg3.is_valid()) regs |= reg3.bit();
6069   if (reg4.is_valid()) regs |= reg4.bit();
6070   if (reg5.is_valid()) regs |= reg5.bit();
6071   if (reg6.is_valid()) regs |= reg6.bit();
6072
6073   for (int i = 0; i < Register::NumAllocatableRegisters(); i++) {
6074     Register candidate = Register::FromAllocationIndex(i);
6075     if (regs & candidate.bit()) continue;
6076     return candidate;
6077   }
6078   UNREACHABLE();
6079   return no_reg;
6080 }
6081
6082
6083 void MacroAssembler::JumpIfDictionaryInPrototypeChain(
6084     Register object,
6085     Register scratch0,
6086     Register scratch1,
6087     Label* found) {
6088   DCHECK(!scratch1.is(scratch0));
6089   Factory* factory = isolate()->factory();
6090   Register current = scratch0;
6091   Label loop_again, end;
6092
6093   // Scratch contained elements pointer.
6094   Move(current, object);
6095   ld(current, FieldMemOperand(current, HeapObject::kMapOffset));
6096   ld(current, FieldMemOperand(current, Map::kPrototypeOffset));
6097   Branch(&end, eq, current, Operand(factory->null_value()));
6098
6099   // Loop based on the map going up the prototype chain.
6100   bind(&loop_again);
6101   ld(current, FieldMemOperand(current, HeapObject::kMapOffset));
6102   lbu(scratch1, FieldMemOperand(current, Map::kInstanceTypeOffset));
6103   STATIC_ASSERT(JS_VALUE_TYPE < JS_OBJECT_TYPE);
6104   STATIC_ASSERT(JS_PROXY_TYPE < JS_OBJECT_TYPE);
6105   Branch(found, lo, scratch1, Operand(JS_OBJECT_TYPE));
6106   lb(scratch1, FieldMemOperand(current, Map::kBitField2Offset));
6107   DecodeField<Map::ElementsKindBits>(scratch1);
6108   Branch(found, eq, scratch1, Operand(DICTIONARY_ELEMENTS));
6109   ld(current, FieldMemOperand(current, Map::kPrototypeOffset));
6110   Branch(&loop_again, ne, current, Operand(factory->null_value()));
6111
6112   bind(&end);
6113 }
6114
6115
6116 bool AreAliased(Register reg1,
6117                 Register reg2,
6118                 Register reg3,
6119                 Register reg4,
6120                 Register reg5,
6121                 Register reg6,
6122                 Register reg7,
6123                 Register reg8) {
6124   int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() +
6125       reg3.is_valid() + reg4.is_valid() + reg5.is_valid() + reg6.is_valid() +
6126       reg7.is_valid() + reg8.is_valid();
6127
6128   RegList regs = 0;
6129   if (reg1.is_valid()) regs |= reg1.bit();
6130   if (reg2.is_valid()) regs |= reg2.bit();
6131   if (reg3.is_valid()) regs |= reg3.bit();
6132   if (reg4.is_valid()) regs |= reg4.bit();
6133   if (reg5.is_valid()) regs |= reg5.bit();
6134   if (reg6.is_valid()) regs |= reg6.bit();
6135   if (reg7.is_valid()) regs |= reg7.bit();
6136   if (reg8.is_valid()) regs |= reg8.bit();
6137   int n_of_non_aliasing_regs = NumRegs(regs);
6138
6139   return n_of_valid_regs != n_of_non_aliasing_regs;
6140 }
6141
6142
6143 CodePatcher::CodePatcher(byte* address,
6144                          int instructions,
6145                          FlushICache flush_cache)
6146     : address_(address),
6147       size_(instructions * Assembler::kInstrSize),
6148       masm_(NULL, address, size_ + Assembler::kGap),
6149       flush_cache_(flush_cache) {
6150   // Create a new macro assembler pointing to the address of the code to patch.
6151   // The size is adjusted with kGap on order for the assembler to generate size
6152   // bytes of instructions without failing with buffer size constraints.
6153   DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
6154 }
6155
6156
6157 CodePatcher::~CodePatcher() {
6158   // Indicate that code has changed.
6159   if (flush_cache_ == FLUSH) {
6160     CpuFeatures::FlushICache(address_, size_);
6161   }
6162   // Check that the code was patched as expected.
6163   DCHECK(masm_.pc_ == address_ + size_);
6164   DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
6165 }
6166
6167
6168 void CodePatcher::Emit(Instr instr) {
6169   masm()->emit(instr);
6170 }
6171
6172
6173 void CodePatcher::Emit(Address addr) {
6174   // masm()->emit(reinterpret_cast<Instr>(addr));
6175 }
6176
6177
6178 void CodePatcher::ChangeBranchCondition(Condition cond) {
6179   Instr instr = Assembler::instr_at(masm_.pc_);
6180   DCHECK(Assembler::IsBranch(instr));
6181   uint32_t opcode = Assembler::GetOpcodeField(instr);
6182   // Currently only the 'eq' and 'ne' cond values are supported and the simple
6183   // branch instructions (with opcode being the branch type).
6184   // There are some special cases (see Assembler::IsBranch()) so extending this
6185   // would be tricky.
6186   DCHECK(opcode == BEQ ||
6187          opcode == BNE ||
6188         opcode == BLEZ ||
6189         opcode == BGTZ ||
6190         opcode == BEQL ||
6191         opcode == BNEL ||
6192        opcode == BLEZL ||
6193        opcode == BGTZL);
6194   opcode = (cond == eq) ? BEQ : BNE;
6195   instr = (instr & ~kOpcodeMask) | opcode;
6196   masm_.emit(instr);
6197 }
6198
6199
6200 void MacroAssembler::TruncatingDiv(Register result,
6201                                    Register dividend,
6202                                    int32_t divisor) {
6203   DCHECK(!dividend.is(result));
6204   DCHECK(!dividend.is(at));
6205   DCHECK(!result.is(at));
6206   base::MagicNumbersForDivision<uint32_t> mag =
6207   base::SignedDivisionByConstant(static_cast<uint32_t>(divisor));
6208   li(at, Operand(static_cast<int32_t>(mag.multiplier)));
6209   Mulh(result, dividend, Operand(at));
6210   bool neg = (mag.multiplier & (static_cast<uint32_t>(1) << 31)) != 0;
6211   if (divisor > 0 && neg) {
6212     Addu(result, result, Operand(dividend));
6213   }
6214   if (divisor < 0 && !neg && mag.multiplier > 0) {
6215     Subu(result, result, Operand(dividend));
6216   }
6217   if (mag.shift > 0) sra(result, result, mag.shift);
6218   srl(at, dividend, 31);
6219   Addu(result, result, Operand(at));
6220 }
6221
6222
6223 }  // namespace internal
6224 }  // namespace v8
6225
6226 #endif  // V8_TARGET_ARCH_MIPS64