655d5904d043c6b7f6ad598e6988fdd700151135
[platform/upstream/v8.git] / src / mips64 / builtins-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 #if V8_TARGET_ARCH_MIPS64
6
7 #include "src/codegen.h"
8 #include "src/debug/debug.h"
9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h"
11 #include "src/runtime/runtime.h"
12
13 namespace v8 {
14 namespace internal {
15
16
17 #define __ ACCESS_MASM(masm)
18
19
20 void Builtins::Generate_Adaptor(MacroAssembler* masm,
21                                 CFunctionId id,
22                                 BuiltinExtraArguments extra_args) {
23   // ----------- S t a t e -------------
24   //  -- a0                 : number of arguments excluding receiver
25   //  -- a1                 : called function (only guaranteed when
26   //  --                      extra_args requires it)
27   //  -- cp                 : context
28   //  -- sp[0]              : last argument
29   //  -- ...
30   //  -- sp[8 * (argc - 1)] : first argument
31   //  -- sp[8 * agrc]       : receiver
32   // -----------------------------------
33
34   // Insert extra arguments.
35   int num_extra_args = 0;
36   if (extra_args == NEEDS_CALLED_FUNCTION) {
37     num_extra_args = 1;
38     __ push(a1);
39   } else {
40     DCHECK(extra_args == NO_EXTRA_ARGUMENTS);
41   }
42
43   // JumpToExternalReference expects a0 to contain the number of arguments
44   // including the receiver and the extra arguments.
45   __ Daddu(a0, a0, num_extra_args + 1);
46   __ JumpToExternalReference(ExternalReference(id, masm->isolate()));
47 }
48
49
50 // Load the built-in InternalArray function from the current context.
51 static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
52                                               Register result) {
53   // Load the native context.
54
55   __ ld(result,
56         MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
57   __ ld(result,
58         FieldMemOperand(result, GlobalObject::kNativeContextOffset));
59   // Load the InternalArray function from the native context.
60   __ ld(result,
61          MemOperand(result,
62                     Context::SlotOffset(
63                         Context::INTERNAL_ARRAY_FUNCTION_INDEX)));
64 }
65
66
67 // Load the built-in Array function from the current context.
68 static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
69   // Load the native context.
70
71   __ ld(result,
72         MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
73   __ ld(result,
74         FieldMemOperand(result, GlobalObject::kNativeContextOffset));
75   // Load the Array function from the native context.
76   __ ld(result,
77         MemOperand(result,
78                    Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
79 }
80
81
82 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
83   // ----------- S t a t e -------------
84   //  -- a0     : number of arguments
85   //  -- ra     : return address
86   //  -- sp[...]: constructor arguments
87   // -----------------------------------
88   Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
89
90   // Get the InternalArray function.
91   GenerateLoadInternalArrayFunction(masm, a1);
92
93   if (FLAG_debug_code) {
94     // Initial map for the builtin InternalArray functions should be maps.
95     __ ld(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
96     __ SmiTst(a2, a4);
97     __ Assert(ne, kUnexpectedInitialMapForInternalArrayFunction,
98               a4, Operand(zero_reg));
99     __ GetObjectType(a2, a3, a4);
100     __ Assert(eq, kUnexpectedInitialMapForInternalArrayFunction,
101               a4, Operand(MAP_TYPE));
102   }
103
104   // Run the native code for the InternalArray function called as a normal
105   // function.
106   // Tail call a stub.
107   InternalArrayConstructorStub stub(masm->isolate());
108   __ TailCallStub(&stub);
109 }
110
111
112 void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
113   // ----------- S t a t e -------------
114   //  -- a0     : number of arguments
115   //  -- ra     : return address
116   //  -- sp[...]: constructor arguments
117   // -----------------------------------
118   Label generic_array_code;
119
120   // Get the Array function.
121   GenerateLoadArrayFunction(masm, a1);
122
123   if (FLAG_debug_code) {
124     // Initial map for the builtin Array functions should be maps.
125     __ ld(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
126     __ SmiTst(a2, a4);
127     __ Assert(ne, kUnexpectedInitialMapForArrayFunction1,
128               a4, Operand(zero_reg));
129     __ GetObjectType(a2, a3, a4);
130     __ Assert(eq, kUnexpectedInitialMapForArrayFunction2,
131               a4, Operand(MAP_TYPE));
132   }
133
134   // Run the native code for the Array function called as a normal function.
135   // Tail call a stub.
136   __ mov(a3, a1);
137   __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
138   ArrayConstructorStub stub(masm->isolate());
139   __ TailCallStub(&stub);
140 }
141
142
143 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
144   // ----------- S t a t e -------------
145   //  -- a0                     : number of arguments
146   //  -- a1                     : constructor function
147   //  -- ra                     : return address
148   //  -- sp[(argc - n - 1) * 8] : arg[n] (zero based)
149   //  -- sp[argc * 8]           : receiver
150   // -----------------------------------
151   Counters* counters = masm->isolate()->counters();
152   __ IncrementCounter(counters->string_ctor_calls(), 1, a2, a3);
153
154   Register function = a1;
155   if (FLAG_debug_code) {
156     __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, a2);
157     __ Assert(eq, kUnexpectedStringFunction, function, Operand(a2));
158   }
159
160   // Load the first arguments in a0 and get rid of the rest.
161   Label no_arguments;
162   __ Branch(&no_arguments, eq, a0, Operand(zero_reg));
163   // First args = sp[(argc - 1) * 8].
164   __ Dsubu(a0, a0, Operand(1));
165   __ dsll(a0, a0, kPointerSizeLog2);
166   __ Daddu(sp, a0, sp);
167   __ ld(a0, MemOperand(sp));
168   // sp now point to args[0], drop args[0] + receiver.
169   __ Drop(2);
170
171   Register argument = a2;
172   Label not_cached, argument_is_string;
173   __ LookupNumberStringCache(a0,        // Input.
174                              argument,  // Result.
175                              a3,        // Scratch.
176                              a4,        // Scratch.
177                              a5,        // Scratch.
178                              &not_cached);
179   __ IncrementCounter(counters->string_ctor_cached_number(), 1, a3, a4);
180   __ bind(&argument_is_string);
181
182   // ----------- S t a t e -------------
183   //  -- a2     : argument converted to string
184   //  -- a1     : constructor function
185   //  -- ra     : return address
186   // -----------------------------------
187
188   Label gc_required;
189   __ Allocate(JSValue::kSize,
190               v0,  // Result.
191               a3,  // Scratch.
192               a4,  // Scratch.
193               &gc_required,
194               TAG_OBJECT);
195
196   // Initialising the String Object.
197   Register map = a3;
198   __ LoadGlobalFunctionInitialMap(function, map, a4);
199   if (FLAG_debug_code) {
200     __ lbu(a4, FieldMemOperand(map, Map::kInstanceSizeOffset));
201     __ Assert(eq, kUnexpectedStringWrapperInstanceSize,
202         a4, Operand(JSValue::kSize >> kPointerSizeLog2));
203     __ lbu(a4, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset));
204     __ Assert(eq, kUnexpectedUnusedPropertiesOfStringWrapper,
205         a4, Operand(zero_reg));
206   }
207   __ sd(map, FieldMemOperand(v0, HeapObject::kMapOffset));
208
209   __ LoadRoot(a3, Heap::kEmptyFixedArrayRootIndex);
210   __ sd(a3, FieldMemOperand(v0, JSObject::kPropertiesOffset));
211   __ sd(a3, FieldMemOperand(v0, JSObject::kElementsOffset));
212
213   __ sd(argument, FieldMemOperand(v0, JSValue::kValueOffset));
214
215   // Ensure the object is fully initialized.
216   STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
217
218   __ Ret();
219
220   // The argument was not found in the number to string cache. Check
221   // if it's a string already before calling the conversion builtin.
222   Label convert_argument;
223   __ bind(&not_cached);
224   __ JumpIfSmi(a0, &convert_argument);
225
226   // Is it a String?
227   __ ld(a2, FieldMemOperand(a0, HeapObject::kMapOffset));
228   __ lbu(a3, FieldMemOperand(a2, Map::kInstanceTypeOffset));
229   STATIC_ASSERT(kNotStringTag != 0);
230   __ And(a4, a3, Operand(kIsNotStringMask));
231   __ Branch(&convert_argument, ne, a4, Operand(zero_reg));
232   __ mov(argument, a0);
233   __ IncrementCounter(counters->string_ctor_conversions(), 1, a3, a4);
234   __ Branch(&argument_is_string);
235
236   // Invoke the conversion builtin and put the result into a2.
237   __ bind(&convert_argument);
238   __ push(function);  // Preserve the function.
239   __ IncrementCounter(counters->string_ctor_conversions(), 1, a3, a4);
240   {
241     FrameScope scope(masm, StackFrame::INTERNAL);
242     ToStringStub stub(masm->isolate());
243     __ CallStub(&stub);
244   }
245   __ pop(function);
246   __ mov(argument, v0);
247   __ Branch(&argument_is_string);
248
249   // Load the empty string into a2, remove the receiver from the
250   // stack, and jump back to the case where the argument is a string.
251   __ bind(&no_arguments);
252   __ LoadRoot(argument, Heap::kempty_stringRootIndex);
253   __ Drop(1);
254   __ Branch(&argument_is_string);
255
256   // At this point the argument is already a string. Call runtime to
257   // create a string wrapper.
258   __ bind(&gc_required);
259   __ IncrementCounter(counters->string_ctor_gc_required(), 1, a3, a4);
260   {
261     FrameScope scope(masm, StackFrame::INTERNAL);
262     __ push(argument);
263     __ CallRuntime(Runtime::kNewStringWrapper, 1);
264   }
265   __ Ret();
266 }
267
268
269 static void CallRuntimePassFunction(
270     MacroAssembler* masm, Runtime::FunctionId function_id) {
271   FrameScope scope(masm, StackFrame::INTERNAL);
272   // Push a copy of the function onto the stack.
273   // Push call kind information and function as parameter to the runtime call.
274   __ Push(a1, a1);
275
276   __ CallRuntime(function_id, 1);
277   // Restore call kind information and receiver.
278   __ Pop(a1);
279 }
280
281
282 static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
283   __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
284   __ ld(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset));
285   __ Daddu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag));
286   __ Jump(at);
287 }
288
289
290 static void GenerateTailCallToReturnedCode(MacroAssembler* masm) {
291   __ Daddu(at, v0, Operand(Code::kHeaderSize - kHeapObjectTag));
292   __ Jump(at);
293 }
294
295
296 void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) {
297   // Checking whether the queued function is ready for install is optional,
298   // since we come across interrupts and stack checks elsewhere.  However,
299   // not checking may delay installing ready functions, and always checking
300   // would be quite expensive.  A good compromise is to first check against
301   // stack limit as a cue for an interrupt signal.
302   Label ok;
303   __ LoadRoot(a4, Heap::kStackLimitRootIndex);
304   __ Branch(&ok, hs, sp, Operand(a4));
305
306   CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode);
307   GenerateTailCallToReturnedCode(masm);
308
309   __ bind(&ok);
310   GenerateTailCallToSharedCode(masm);
311 }
312
313
314 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
315                                            bool is_api_function,
316                                            bool create_memento) {
317   // ----------- S t a t e -------------
318   //  -- a0     : number of arguments
319   //  -- a1     : constructor function
320   //  -- a2     : allocation site or undefined
321   //  -- a3     : original constructor
322   //  -- ra     : return address
323   //  -- sp[...]: constructor arguments
324   // -----------------------------------
325
326   // Should never create mementos for api functions.
327   DCHECK(!is_api_function || !create_memento);
328
329   Isolate* isolate = masm->isolate();
330
331   // Enter a construct frame.
332   {
333     FrameScope scope(masm, StackFrame::CONSTRUCT);
334
335     // Preserve the incoming parameters on the stack.
336     __ AssertUndefinedOrAllocationSite(a2, t0);
337     __ SmiTag(a0);
338     __ Push(a2, a0, a1, a3);
339
340     // Try to allocate the object without transitioning into C code. If any of
341     // the preconditions is not met, the code bails out to the runtime call.
342     Label rt_call, allocated;
343     if (FLAG_inline_new) {
344       ExternalReference debug_step_in_fp =
345           ExternalReference::debug_step_in_fp_address(isolate);
346       __ li(a2, Operand(debug_step_in_fp));
347       __ ld(a2, MemOperand(a2));
348       __ Branch(&rt_call, ne, a2, Operand(zero_reg));
349
350       // Fall back to runtime if the original constructor and function differ.
351       __ Branch(&rt_call, ne, a1, Operand(a3));
352
353       // Load the initial map and verify that it is in fact a map.
354       // a1: constructor function
355       __ ld(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
356       __ JumpIfSmi(a2, &rt_call);
357       __ GetObjectType(a2, t1, t0);
358       __ Branch(&rt_call, ne, t0, Operand(MAP_TYPE));
359
360       // Check that the constructor is not constructing a JSFunction (see
361       // comments in Runtime_NewObject in runtime.cc). In which case the
362       // initial map's instance type would be JS_FUNCTION_TYPE.
363       // a1: constructor function
364       // a2: initial map
365       __ lbu(t1, FieldMemOperand(a2, Map::kInstanceTypeOffset));
366       __ Branch(&rt_call, eq, t1, Operand(JS_FUNCTION_TYPE));
367
368       if (!is_api_function) {
369         Label allocate;
370         MemOperand bit_field3 = FieldMemOperand(a2, Map::kBitField3Offset);
371         // Check if slack tracking is enabled.
372         __ lwu(a4, bit_field3);
373         __ DecodeField<Map::Counter>(a6, a4);
374         __ Branch(&allocate, lt, a6,
375                   Operand(static_cast<int64_t>(Map::kSlackTrackingCounterEnd)));
376         // Decrease generous allocation count.
377         __ Dsubu(a4, a4, Operand(1 << Map::Counter::kShift));
378         __ Branch(USE_DELAY_SLOT, &allocate, ne, a6,
379                   Operand(Map::kSlackTrackingCounterEnd));
380         __ sw(a4, bit_field3);  // In delay slot.
381
382         __ Push(a1, a2, a1);  // a1 = Constructor.
383         __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
384
385         __ Pop(a1, a2);
386         __ li(a6, Operand(Map::kSlackTrackingCounterEnd - 1));
387
388         __ bind(&allocate);
389       }
390
391       // Now allocate the JSObject on the heap.
392       // a1: constructor function
393       // a2: initial map
394       Label rt_call_reload_new_target;
395       __ lbu(a3, FieldMemOperand(a2, Map::kInstanceSizeOffset));
396       if (create_memento) {
397         __ Daddu(a3, a3, Operand(AllocationMemento::kSize / kPointerSize));
398       }
399
400       __ Allocate(a3, t0, t1, t2, &rt_call_reload_new_target, SIZE_IN_WORDS);
401
402       // Allocated the JSObject, now initialize the fields. Map is set to
403       // initial map and properties and elements are set to empty fixed array.
404       // a1: constructor function
405       // a2: initial map
406       // a3: object size (including memento if create_memento)
407       // t0: JSObject (not tagged)
408       __ LoadRoot(t2, Heap::kEmptyFixedArrayRootIndex);
409       __ mov(t1, t0);
410       __ sd(a2, MemOperand(t1, JSObject::kMapOffset));
411       __ sd(t2, MemOperand(t1, JSObject::kPropertiesOffset));
412       __ sd(t2, MemOperand(t1, JSObject::kElementsOffset));
413       __ Daddu(t1, t1, Operand(3*kPointerSize));
414       DCHECK_EQ(0 * kPointerSize, JSObject::kMapOffset);
415       DCHECK_EQ(1 * kPointerSize, JSObject::kPropertiesOffset);
416       DCHECK_EQ(2 * kPointerSize, JSObject::kElementsOffset);
417
418       // Fill all the in-object properties with appropriate filler.
419       // a1: constructor function
420       // a2: initial map
421       // a3: object size (in words, including memento if create_memento)
422       // t0: JSObject (not tagged)
423       // t1: First in-object property of JSObject (not tagged)
424       // a6: slack tracking counter (non-API function case)
425       DCHECK_EQ(3 * kPointerSize, JSObject::kHeaderSize);
426
427       // Use t3 to hold undefined, which is used in several places below.
428       __ LoadRoot(t3, Heap::kUndefinedValueRootIndex);
429
430       if (!is_api_function) {
431         Label no_inobject_slack_tracking;
432
433         // Check if slack tracking is enabled.
434         __ Branch(&no_inobject_slack_tracking, lt, a6,
435                   Operand(static_cast<int64_t>(Map::kSlackTrackingCounterEnd)));
436
437         // Allocate object with a slack.
438         __ lbu(
439             a0,
440             FieldMemOperand(
441                 a2, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset));
442         __ lbu(a2, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset));
443         __ dsubu(a0, a0, a2);
444         __ dsll(at, a0, kPointerSizeLog2);
445         __ daddu(a0, t1, at);
446         // a0: offset of first field after pre-allocated fields
447         if (FLAG_debug_code) {
448           __ dsll(at, a3, kPointerSizeLog2);
449           __ Daddu(t2, t0, Operand(at));   // End of object.
450           __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields,
451               a0, Operand(t2));
452         }
453         __ InitializeFieldsWithFiller(t1, a0, t3);
454         // To allow for truncation.
455         __ LoadRoot(t3, Heap::kOnePointerFillerMapRootIndex);
456         // Fill the remaining fields with one pointer filler map.
457
458         __ bind(&no_inobject_slack_tracking);
459       }
460
461       if (create_memento) {
462         __ Dsubu(a0, a3, Operand(AllocationMemento::kSize / kPointerSize));
463         __ dsll(a0, a0, kPointerSizeLog2);
464         __ Daddu(a0, t0, Operand(a0));  // End of object.
465         __ InitializeFieldsWithFiller(t1, a0, t3);
466
467         // Fill in memento fields.
468         // t1: points to the allocated but uninitialized memento.
469         __ LoadRoot(t3, Heap::kAllocationMementoMapRootIndex);
470         DCHECK_EQ(0 * kPointerSize, AllocationMemento::kMapOffset);
471         __ sd(t3, MemOperand(t1));
472         __ Daddu(t1, t1, kPointerSize);
473         // Load the AllocationSite.
474         __ ld(t3, MemOperand(sp, 3 * kPointerSize));
475         __ AssertUndefinedOrAllocationSite(t3, a0);
476         DCHECK_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset);
477         __ sd(t3, MemOperand(t1));
478         __ Daddu(t1, t1, kPointerSize);
479       } else {
480         __ dsll(at, a3, kPointerSizeLog2);
481         __ Daddu(a0, t0, Operand(at));  // End of object.
482         __ InitializeFieldsWithFiller(t1, a0, t3);
483       }
484
485       // Add the object tag to make the JSObject real, so that we can continue
486       // and jump into the continuation code at any time from now on.
487       __ Daddu(t0, t0, Operand(kHeapObjectTag));
488
489       // Continue with JSObject being successfully allocated.
490       // a4: JSObject
491       __ jmp(&allocated);
492
493       // Reload the original constructor and fall-through.
494       __ bind(&rt_call_reload_new_target);
495       __ ld(a3, MemOperand(sp, 0 * kPointerSize));
496     }
497
498     // Allocate the new receiver object using the runtime call.
499     // a1: constructor function
500     // a3: original constructor
501     __ bind(&rt_call);
502     if (create_memento) {
503       // Get the cell or allocation site.
504       __ ld(a2, MemOperand(sp, 3 * kPointerSize));
505       __ push(a2);  // argument 1: allocation site
506     }
507
508     __ Push(a1, a3);  // arguments 2-3 / 1-2
509     if (create_memento) {
510       __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3);
511     } else {
512       __ CallRuntime(Runtime::kNewObject, 2);
513     }
514     __ mov(t0, v0);
515
516     // Runtime_NewObjectWithAllocationSite increments allocation count.
517     // Skip the increment.
518     Label count_incremented;
519     if (create_memento) {
520       __ jmp(&count_incremented);
521     }
522
523     // Receiver for constructor call allocated.
524     // t0: JSObject
525     __ bind(&allocated);
526
527     if (create_memento) {
528       __ ld(a2, MemOperand(sp, 3 * kPointerSize));
529       __ LoadRoot(t1, Heap::kUndefinedValueRootIndex);
530       __ Branch(&count_incremented, eq, a2, Operand(t1));
531       // a2 is an AllocationSite. We are creating a memento from it, so we
532       // need to increment the memento create count.
533       __ ld(a3, FieldMemOperand(a2,
534                                 AllocationSite::kPretenureCreateCountOffset));
535       __ Daddu(a3, a3, Operand(Smi::FromInt(1)));
536       __ sd(a3, FieldMemOperand(a2,
537                                 AllocationSite::kPretenureCreateCountOffset));
538       __ bind(&count_incremented);
539     }
540
541     // Restore the parameters.
542     __ Pop(a3);  // new.target
543     __ Pop(a1);
544
545     __ ld(a0, MemOperand(sp));
546     __ SmiUntag(a0);
547
548     __ Push(a3, t0, t0);
549
550     // Set up pointer to last argument.
551     __ Daddu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
552
553     // Copy arguments and receiver to the expression stack.
554     // a0: number of arguments
555     // a1: constructor function
556     // a2: address of last argument (caller sp)
557     // a3: number of arguments (smi-tagged)
558     // sp[0]: receiver
559     // sp[1]: receiver
560     // sp[2]: new.target
561     // sp[3]: number of arguments (smi-tagged)
562     Label loop, entry;
563     __ mov(a3, a0);
564     __ jmp(&entry);
565     __ bind(&loop);
566     __ dsll(a4, a3, kPointerSizeLog2);
567     __ Daddu(a4, a2, Operand(a4));
568     __ ld(a5, MemOperand(a4));
569     __ push(a5);
570     __ bind(&entry);
571     __ Daddu(a3, a3, Operand(-1));
572     __ Branch(&loop, greater_equal, a3, Operand(zero_reg));
573
574     // Call the function.
575     // a0: number of arguments
576     // a1: constructor function
577     if (is_api_function) {
578       __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
579       Handle<Code> code =
580           masm->isolate()->builtins()->HandleApiCallConstruct();
581       __ Call(code, RelocInfo::CODE_TARGET);
582     } else {
583       ParameterCount actual(a0);
584       __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper());
585     }
586
587     // Store offset of return address for deoptimizer.
588     if (!is_api_function) {
589       masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
590     }
591
592     // Restore context from the frame.
593     __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
594
595     // If the result is an object (in the ECMA sense), we should get rid
596     // of the receiver and use the result; see ECMA-262 section 13.2.2-7
597     // on page 74.
598     Label use_receiver, exit;
599
600     // If the result is a smi, it is *not* an object in the ECMA sense.
601     // v0: result
602     // sp[0]: receiver (newly allocated object)
603     // sp[1]: new.target
604     // sp[2]: number of arguments (smi-tagged)
605     __ JumpIfSmi(v0, &use_receiver);
606
607     // If the type of the result (stored in its map) is less than
608     // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
609     __ GetObjectType(v0, a1, a3);
610     __ Branch(&exit, greater_equal, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
611
612     // Throw away the result of the constructor invocation and use the
613     // on-stack receiver as the result.
614     __ bind(&use_receiver);
615     __ ld(v0, MemOperand(sp));
616
617     // Remove receiver from the stack, remove caller arguments, and
618     // return.
619     __ bind(&exit);
620     // v0: result
621     // sp[0]: receiver (newly allocated object)
622     // sp[1]: new.target (original constructor)
623     // sp[2]: number of arguments (smi-tagged)
624     __ ld(a1, MemOperand(sp, 2 * kPointerSize));
625
626     // Leave construct frame.
627   }
628
629   __ SmiScale(a4, a1, kPointerSizeLog2);
630   __ Daddu(sp, sp, a4);
631   __ Daddu(sp, sp, kPointerSize);
632   __ IncrementCounter(isolate->counters()->constructed_objects(), 1, a1, a2);
633   __ Ret();
634 }
635
636
637 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
638   Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new);
639 }
640
641
642 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
643   Generate_JSConstructStubHelper(masm, true, false);
644 }
645
646
647 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
648   // ----------- S t a t e -------------
649   //  -- a0     : number of arguments
650   //  -- a1     : constructor function
651   //  -- a2     : allocation site or undefined
652   //  -- a3     : original constructor
653   //  -- ra     : return address
654   //  -- sp[...]: constructor arguments
655   // -----------------------------------
656
657   {
658     FrameScope frame_scope(masm, StackFrame::CONSTRUCT);
659
660     __ AssertUndefinedOrAllocationSite(a2, t0);
661     __ push(a2);
662
663     __ mov(a4, a0);
664     __ SmiTag(a4);
665     __ push(a4);  // Smi-tagged arguments count.
666
667     // Push new.target.
668     __ push(a3);
669
670     // receiver is the hole.
671     __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
672     __ push(at);
673
674     // Set up pointer to last argument.
675     __ Daddu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
676
677     // Copy arguments and receiver to the expression stack.
678     // a0: number of arguments
679     // a1: constructor function
680     // a2: address of last argument (caller sp)
681     // a4: number of arguments (smi-tagged)
682     // sp[0]: receiver
683     // sp[1]: new.target
684     // sp[2]: number of arguments (smi-tagged)
685     Label loop, entry;
686     __ SmiUntag(a4);
687     __ jmp(&entry);
688     __ bind(&loop);
689     __ dsll(at, a4, kPointerSizeLog2);
690     __ Daddu(at, a2, Operand(at));
691     __ ld(at, MemOperand(at));
692     __ push(at);
693     __ bind(&entry);
694     __ Daddu(a4, a4, Operand(-1));
695     __ Branch(&loop, ge, a4, Operand(zero_reg));
696
697     // Handle step in.
698     Label skip_step_in;
699     ExternalReference debug_step_in_fp =
700         ExternalReference::debug_step_in_fp_address(masm->isolate());
701     __ li(a2, Operand(debug_step_in_fp));
702     __ ld(a2, MemOperand(a2));
703     __ Branch(&skip_step_in, eq, a2, Operand(zero_reg));
704
705     __ Push(a0, a1, a1);
706     __ CallRuntime(Runtime::kHandleStepInForDerivedConstructors, 1);
707     __ Pop(a0, a1);
708
709     __ bind(&skip_step_in);
710
711
712     // Call the function.
713     // a0: number of arguments
714     // a1: constructor function
715     ParameterCount actual(a0);
716     __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper());
717
718     // Restore context from the frame.
719     // v0: result
720     // sp[0]: new.target
721     // sp[1]: number of arguments (smi-tagged)
722     __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
723     __ ld(a1, MemOperand(sp, kPointerSize));
724
725     // Leave construct frame.
726   }
727
728   __ SmiScale(at, a1, kPointerSizeLog2);
729   __ Daddu(sp, sp, Operand(at));
730   __ Daddu(sp, sp, Operand(kPointerSize));
731   __ Jump(ra);
732 }
733
734
735 enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt };
736
737
738 // Clobbers a2; preserves all other registers.
739 static void Generate_CheckStackOverflow(MacroAssembler* masm,
740                                         const int calleeOffset, Register argc,
741                                         IsTagged argc_is_tagged) {
742   // Check the stack for overflow. We are not trying to catch
743   // interruptions (e.g. debug break and preemption) here, so the "real stack
744   // limit" is checked.
745   Label okay;
746   __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
747   // Make a2 the space we have left. The stack might already be overflowed
748   // here which will cause r2 to become negative.
749   __ dsubu(a2, sp, a2);
750   // Check if the arguments will overflow the stack.
751   if (argc_is_tagged == kArgcIsSmiTagged) {
752     __ SmiScale(a7, v0, kPointerSizeLog2);
753   } else {
754     DCHECK(argc_is_tagged == kArgcIsUntaggedInt);
755     __ dsll(a7, argc, kPointerSizeLog2);
756   }
757   __ Branch(&okay, gt, a2, Operand(a7));  // Signed comparison.
758
759   // Out of stack space.
760   __ ld(a1, MemOperand(fp, calleeOffset));
761   if (argc_is_tagged == kArgcIsUntaggedInt) {
762     __ SmiTag(argc);
763   }
764   __ Push(a1, argc);
765   __ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
766
767   __ bind(&okay);
768 }
769
770
771 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
772                                              bool is_construct) {
773   // Called from JSEntryStub::GenerateBody
774
775   // ----------- S t a t e -------------
776   //  -- a0: code entry
777   //  -- a1: function
778   //  -- a2: receiver_pointer
779   //  -- a3: argc
780   //  -- s0: argv
781   // -----------------------------------
782   ProfileEntryHookStub::MaybeCallEntryHook(masm);
783   // Clear the context before we push it when entering the JS frame.
784   __ mov(cp, zero_reg);
785
786   // Enter an internal frame.
787   {
788     FrameScope scope(masm, StackFrame::INTERNAL);
789
790     // Set up the context from the function argument.
791     __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
792
793     // Push the function and the receiver onto the stack.
794     __ Push(a1, a2);
795
796     // Check if we have enough stack space to push all arguments.
797     // The function is the first thing that was pushed above after entering
798     // the internal frame.
799     const int kFunctionOffset =
800         InternalFrameConstants::kCodeOffset - kPointerSize;
801     // Clobbers a2.
802     Generate_CheckStackOverflow(masm, kFunctionOffset, a3, kArgcIsUntaggedInt);
803
804     // Copy arguments to the stack in a loop.
805     // a3: argc
806     // s0: argv, i.e. points to first arg
807     Label loop, entry;
808     __ dsll(a4, a3, kPointerSizeLog2);
809     __ daddu(a6, s0, a4);
810     __ b(&entry);
811     __ nop();   // Branch delay slot nop.
812     // a6 points past last arg.
813     __ bind(&loop);
814     __ ld(a4, MemOperand(s0));  // Read next parameter.
815     __ daddiu(s0, s0, kPointerSize);
816     __ ld(a4, MemOperand(a4));  // Dereference handle.
817     __ push(a4);  // Push parameter.
818     __ bind(&entry);
819     __ Branch(&loop, ne, s0, Operand(a6));
820
821     // Initialize all JavaScript callee-saved registers, since they will be seen
822     // by the garbage collector as part of handlers.
823     __ LoadRoot(a4, Heap::kUndefinedValueRootIndex);
824     __ mov(s1, a4);
825     __ mov(s2, a4);
826     __ mov(s3, a4);
827     __ mov(s4, a4);
828     __ mov(s5, a4);
829     // s6 holds the root address. Do not clobber.
830     // s7 is cp. Do not init.
831
832     // Invoke the code and pass argc as a0.
833     __ mov(a0, a3);
834     if (is_construct) {
835       // No type feedback cell is available
836       __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
837       CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
838       __ CallStub(&stub);
839     } else {
840       ParameterCount actual(a0);
841       __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper());
842     }
843
844     // Leave internal frame.
845   }
846   __ Jump(ra);
847 }
848
849
850 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
851   Generate_JSEntryTrampolineHelper(masm, false);
852 }
853
854
855 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
856   Generate_JSEntryTrampolineHelper(masm, true);
857 }
858
859
860 // Generate code for entering a JS function with the interpreter.
861 // On entry to the function the receiver and arguments have been pushed on the
862 // stack left to right.  The actual argument count matches the formal parameter
863 // count expected by the function.
864 //
865 // The live registers are:
866 //   o a1: the JS function object being called.
867 //   o cp: our context
868 //   o fp: the caller's frame pointer
869 //   o sp: stack pointer
870 //   o ra: return address
871 //
872 // The function builds a JS frame. Please see JavaScriptFrameConstants in
873 // frames-mips.h for its layout.
874 // TODO(rmcilroy): We will need to include the current bytecode pointer in the
875 // frame.
876 void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
877   // Open a frame scope to indicate that there is a frame on the stack.  The
878   // MANUAL indicates that the scope shouldn't actually generate code to set up
879   // the frame (that is done below).
880   FrameScope frame_scope(masm, StackFrame::MANUAL);
881
882   __ Push(ra, fp, cp, a1);
883   __ Daddu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
884
885   // Get the bytecode array from the function object and load the pointer to the
886   // first entry into kInterpreterBytecodeRegister.
887   __ ld(a0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
888   __ ld(kInterpreterBytecodeArrayRegister,
889         FieldMemOperand(a0, SharedFunctionInfo::kFunctionDataOffset));
890
891   if (FLAG_debug_code) {
892     // Check function data field is actually a BytecodeArray object.
893     __ SmiTst(kInterpreterBytecodeArrayRegister, a4);
894     __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry, a4,
895               Operand(zero_reg));
896     __ GetObjectType(kInterpreterBytecodeArrayRegister, a4, a4);
897     __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry, a4,
898               Operand(BYTECODE_ARRAY_TYPE));
899   }
900
901   // Allocate the local and temporary register file on the stack.
902   {
903     // Load frame size (word) from the BytecodeArray object.
904     __ lw(a4, FieldMemOperand(kInterpreterBytecodeArrayRegister,
905                               BytecodeArray::kFrameSizeOffset));
906
907     // Do a stack check to ensure we don't go over the limit.
908     Label ok;
909     __ Dsubu(a5, sp, Operand(a4));
910     __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
911     __ Branch(&ok, hs, a5, Operand(a2));
912     __ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
913     __ bind(&ok);
914
915     // If ok, push undefined as the initial value for all register file entries.
916     Label loop_header;
917     Label loop_check;
918     __ LoadRoot(a5, Heap::kUndefinedValueRootIndex);
919     __ Branch(&loop_check);
920     __ bind(&loop_header);
921     // TODO(rmcilroy): Consider doing more than one push per loop iteration.
922     __ push(a5);
923     // Continue loop if not done.
924     __ bind(&loop_check);
925     __ Dsubu(a4, a4, Operand(kPointerSize));
926     __ Branch(&loop_header, ge, a4, Operand(zero_reg));
927   }
928
929   // TODO(rmcilroy): List of things not currently dealt with here but done in
930   // fullcodegen's prologue:
931   //  - Support profiler (specifically profiling_counter).
932   //  - Call ProfileEntryHookStub when isolate has a function_entry_hook.
933   //  - Allow simulator stop operations if FLAG_stop_at is set.
934   //  - Deal with sloppy mode functions which need to replace the
935   //    receiver with the global proxy when called as functions (without an
936   //    explicit receiver object).
937   //  - Code aging of the BytecodeArray object.
938   //  - Supporting FLAG_trace.
939   //
940   // The following items are also not done here, and will probably be done using
941   // explicit bytecodes instead:
942   //  - Allocating a new local context if applicable.
943   //  - Setting up a local binding to the this function, which is used in
944   //    derived constructors with super calls.
945   //  - Setting new.target if required.
946   //  - Dealing with REST parameters (only if
947   //    https://codereview.chromium.org/1235153006 doesn't land by then).
948   //  - Dealing with argument objects.
949
950   // Perform stack guard check.
951   {
952     Label ok;
953     __ LoadRoot(at, Heap::kStackLimitRootIndex);
954     __ Branch(&ok, hs, sp, Operand(at));
955     __ CallRuntime(Runtime::kStackGuard, 0);
956     __ bind(&ok);
957   }
958
959   // Load bytecode offset and dispatch table into registers.
960   __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
961   __ Dsubu(
962       kInterpreterRegisterFileRegister, fp,
963       Operand(kPointerSize + StandardFrameConstants::kFixedFrameSizeFromFp));
964   __ li(kInterpreterBytecodeOffsetRegister,
965         Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
966   __ LoadRoot(kInterpreterDispatchTableRegister,
967               Heap::kInterpreterTableRootIndex);
968   __ Daddu(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
969            Operand(FixedArray::kHeaderSize - kHeapObjectTag));
970
971   // Dispatch to the first bytecode handler for the function.
972   __ Daddu(a0, kInterpreterBytecodeArrayRegister,
973            kInterpreterBytecodeOffsetRegister);
974   __ lbu(a0, MemOperand(a0));
975   __ dsll(at, a0, kPointerSizeLog2);
976   __ Daddu(at, kInterpreterDispatchTableRegister, at);
977   __ ld(at, MemOperand(at));
978   // TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging
979   // and header removal.
980   __ Daddu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag));
981   __ Call(at);
982 }
983
984
985 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
986   // TODO(rmcilroy): List of things not currently dealt with here but done in
987   // fullcodegen's EmitReturnSequence.
988   //  - Supporting FLAG_trace for Runtime::TraceExit.
989   //  - Support profiler (specifically decrementing profiling_counter
990   //    appropriately and calling out to HandleInterrupts if necessary).
991
992   // The return value is in accumulator, which is already in v0.
993
994   // Leave the frame (also dropping the register file).
995   __ LeaveFrame(StackFrame::JAVA_SCRIPT);
996
997   // Drop receiver + arguments and return.
998   __ lw(at, FieldMemOperand(kInterpreterBytecodeArrayRegister,
999                             BytecodeArray::kParameterSizeOffset));
1000   __ Daddu(sp, sp, at);
1001   __ Jump(ra);
1002 }
1003
1004
1005 void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
1006   CallRuntimePassFunction(masm, Runtime::kCompileLazy);
1007   GenerateTailCallToReturnedCode(masm);
1008 }
1009
1010
1011 static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) {
1012   FrameScope scope(masm, StackFrame::INTERNAL);
1013   // Push a copy of the function onto the stack.
1014   // Push function as parameter to the runtime call.
1015   __ Push(a1, a1);
1016   // Whether to compile in a background thread.
1017   __ LoadRoot(
1018       at, concurrent ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex);
1019   __ push(at);
1020
1021   __ CallRuntime(Runtime::kCompileOptimized, 2);
1022   // Restore receiver.
1023   __ Pop(a1);
1024 }
1025
1026
1027 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) {
1028   CallCompileOptimized(masm, false);
1029   GenerateTailCallToReturnedCode(masm);
1030 }
1031
1032
1033 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
1034   CallCompileOptimized(masm, true);
1035   GenerateTailCallToReturnedCode(masm);
1036 }
1037
1038
1039 static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
1040   // For now, we are relying on the fact that make_code_young doesn't do any
1041   // garbage collection which allows us to save/restore the registers without
1042   // worrying about which of them contain pointers. We also don't build an
1043   // internal frame to make the code faster, since we shouldn't have to do stack
1044   // crawls in MakeCodeYoung. This seems a bit fragile.
1045
1046   // Set a0 to point to the head of the PlatformCodeAge sequence.
1047   __ Dsubu(a0, a0,
1048       Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize));
1049
1050   // The following registers must be saved and restored when calling through to
1051   // the runtime:
1052   //   a0 - contains return address (beginning of patch sequence)
1053   //   a1 - isolate
1054   RegList saved_regs =
1055       (a0.bit() | a1.bit() | ra.bit() | fp.bit()) & ~sp.bit();
1056   FrameScope scope(masm, StackFrame::MANUAL);
1057   __ MultiPush(saved_regs);
1058   __ PrepareCallCFunction(2, 0, a2);
1059   __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate())));
1060   __ CallCFunction(
1061       ExternalReference::get_make_code_young_function(masm->isolate()), 2);
1062   __ MultiPop(saved_regs);
1063   __ Jump(a0);
1064 }
1065
1066 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C)                 \
1067 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking(  \
1068     MacroAssembler* masm) {                                  \
1069   GenerateMakeCodeYoungAgainCommon(masm);                    \
1070 }                                                            \
1071 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking(   \
1072     MacroAssembler* masm) {                                  \
1073   GenerateMakeCodeYoungAgainCommon(masm);                    \
1074 }
1075 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR)
1076 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
1077
1078
1079 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
1080   // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact
1081   // that make_code_young doesn't do any garbage collection which allows us to
1082   // save/restore the registers without worrying about which of them contain
1083   // pointers.
1084
1085   // Set a0 to point to the head of the PlatformCodeAge sequence.
1086   __ Dsubu(a0, a0,
1087       Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize));
1088
1089   // The following registers must be saved and restored when calling through to
1090   // the runtime:
1091   //   a0 - contains return address (beginning of patch sequence)
1092   //   a1 - isolate
1093   RegList saved_regs =
1094       (a0.bit() | a1.bit() | ra.bit() | fp.bit()) & ~sp.bit();
1095   FrameScope scope(masm, StackFrame::MANUAL);
1096   __ MultiPush(saved_regs);
1097   __ PrepareCallCFunction(2, 0, a2);
1098   __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate())));
1099   __ CallCFunction(
1100       ExternalReference::get_mark_code_as_executed_function(masm->isolate()),
1101       2);
1102   __ MultiPop(saved_regs);
1103
1104   // Perform prologue operations usually performed by the young code stub.
1105   __ Push(ra, fp, cp, a1);
1106   __ Daddu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
1107
1108   // Jump to point after the code-age stub.
1109   __ Daddu(a0, a0, Operand((kNoCodeAgeSequenceLength)));
1110   __ Jump(a0);
1111 }
1112
1113
1114 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
1115   GenerateMakeCodeYoungAgainCommon(masm);
1116 }
1117
1118
1119 void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
1120   Generate_MarkCodeAsExecutedOnce(masm);
1121 }
1122
1123
1124 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
1125                                              SaveFPRegsMode save_doubles) {
1126   {
1127     FrameScope scope(masm, StackFrame::INTERNAL);
1128
1129     // Preserve registers across notification, this is important for compiled
1130     // stubs that tail call the runtime on deopts passing their parameters in
1131     // registers.
1132     __ MultiPush(kJSCallerSaved | kCalleeSaved);
1133     // Pass the function and deoptimization type to the runtime system.
1134     __ CallRuntime(Runtime::kNotifyStubFailure, 0, save_doubles);
1135     __ MultiPop(kJSCallerSaved | kCalleeSaved);
1136   }
1137
1138   __ Daddu(sp, sp, Operand(kPointerSize));  // Ignore state
1139   __ Jump(ra);  // Jump to miss handler
1140 }
1141
1142
1143 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
1144   Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs);
1145 }
1146
1147
1148 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
1149   Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
1150 }
1151
1152
1153 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
1154                                              Deoptimizer::BailoutType type) {
1155   {
1156     FrameScope scope(masm, StackFrame::INTERNAL);
1157     // Pass the function and deoptimization type to the runtime system.
1158     __ li(a0, Operand(Smi::FromInt(static_cast<int>(type))));
1159     __ push(a0);
1160     __ CallRuntime(Runtime::kNotifyDeoptimized, 1);
1161   }
1162
1163   // Get the full codegen state from the stack and untag it -> a6.
1164   __ ld(a6, MemOperand(sp, 0 * kPointerSize));
1165   __ SmiUntag(a6);
1166   // Switch on the state.
1167   Label with_tos_register, unknown_state;
1168   __ Branch(&with_tos_register,
1169             ne, a6, Operand(FullCodeGenerator::NO_REGISTERS));
1170   __ Ret(USE_DELAY_SLOT);
1171   // Safe to fill delay slot Addu will emit one instruction.
1172   __ Daddu(sp, sp, Operand(1 * kPointerSize));  // Remove state.
1173
1174   __ bind(&with_tos_register);
1175   __ ld(v0, MemOperand(sp, 1 * kPointerSize));
1176   __ Branch(&unknown_state, ne, a6, Operand(FullCodeGenerator::TOS_REG));
1177
1178   __ Ret(USE_DELAY_SLOT);
1179   // Safe to fill delay slot Addu will emit one instruction.
1180   __ Daddu(sp, sp, Operand(2 * kPointerSize));  // Remove state.
1181
1182   __ bind(&unknown_state);
1183   __ stop("no cases left");
1184 }
1185
1186
1187 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
1188   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
1189 }
1190
1191
1192 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) {
1193   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
1194 }
1195
1196
1197 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
1198   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
1199 }
1200
1201
1202 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
1203   // Lookup the function in the JavaScript frame.
1204   __ ld(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1205   {
1206     FrameScope scope(masm, StackFrame::INTERNAL);
1207     // Pass function as argument.
1208     __ push(a0);
1209     __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
1210   }
1211
1212   // If the code object is null, just return to the unoptimized code.
1213   __ Ret(eq, v0, Operand(Smi::FromInt(0)));
1214
1215   // Load deoptimization data from the code object.
1216   // <deopt_data> = <code>[#deoptimization_data_offset]
1217   __ ld(a1, MemOperand(v0, Code::kDeoptimizationDataOffset - kHeapObjectTag));
1218
1219   // Load the OSR entrypoint offset from the deoptimization data.
1220   // <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset]
1221   __ ld(a1, MemOperand(a1, FixedArray::OffsetOfElementAt(
1222       DeoptimizationInputData::kOsrPcOffsetIndex) - kHeapObjectTag));
1223   __ SmiUntag(a1);
1224
1225   // Compute the target address = code_obj + header_size + osr_offset
1226   // <entry_addr> = <code_obj> + #header_size + <osr_offset>
1227   __ daddu(v0, v0, a1);
1228   __ daddiu(ra, v0, Code::kHeaderSize - kHeapObjectTag);
1229
1230   // And "return" to the OSR entry point of the function.
1231   __ Ret();
1232 }
1233
1234
1235 void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) {
1236   // We check the stack limit as indicator that recompilation might be done.
1237   Label ok;
1238   __ LoadRoot(at, Heap::kStackLimitRootIndex);
1239   __ Branch(&ok, hs, sp, Operand(at));
1240   {
1241     FrameScope scope(masm, StackFrame::INTERNAL);
1242     __ CallRuntime(Runtime::kStackGuard, 0);
1243   }
1244   __ Jump(masm->isolate()->builtins()->OnStackReplacement(),
1245           RelocInfo::CODE_TARGET);
1246
1247   __ bind(&ok);
1248   __ Ret();
1249 }
1250
1251
1252 // static
1253 void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
1254   // 1. Make sure we have at least one argument.
1255   // a0: actual number of arguments
1256   {
1257     Label done;
1258     __ Branch(&done, ne, a0, Operand(zero_reg));
1259     __ PushRoot(Heap::kUndefinedValueRootIndex);
1260     __ Daddu(a0, a0, Operand(1));
1261     __ bind(&done);
1262   }
1263
1264   // 2. Get the function to call (passed as receiver) from the stack.
1265   // a0: actual number of arguments
1266   __ dsll(at, a0, kPointerSizeLog2);
1267   __ daddu(at, sp, at);
1268   __ ld(a1, MemOperand(at));
1269
1270   // 3. Shift arguments and return address one slot down on the stack
1271   //    (overwriting the original receiver).  Adjust argument count to make
1272   //    the original first argument the new receiver.
1273   // a0: actual number of arguments
1274   // a1: function
1275   {
1276     Label loop;
1277     // Calculate the copy start address (destination). Copy end address is sp.
1278     __ dsll(at, a0, kPointerSizeLog2);
1279     __ daddu(a2, sp, at);
1280
1281     __ bind(&loop);
1282     __ ld(at, MemOperand(a2, -kPointerSize));
1283     __ sd(at, MemOperand(a2));
1284     __ Dsubu(a2, a2, Operand(kPointerSize));
1285     __ Branch(&loop, ne, a2, Operand(sp));
1286     // Adjust the actual number of arguments and remove the top element
1287     // (which is a copy of the last argument).
1288     __ Dsubu(a0, a0, Operand(1));
1289     __ Pop();
1290   }
1291
1292   // 4. Call the callable.
1293   __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1294 }
1295
1296
1297 static void Generate_PushAppliedArguments(MacroAssembler* masm,
1298                                           const int argumentsOffset,
1299                                           const int indexOffset,
1300                                           const int limitOffset) {
1301   Label entry, loop;
1302   Register receiver = LoadDescriptor::ReceiverRegister();
1303   Register key = LoadDescriptor::NameRegister();
1304   Register slot = LoadDescriptor::SlotRegister();
1305   Register vector = LoadWithVectorDescriptor::VectorRegister();
1306
1307   __ ld(key, MemOperand(fp, indexOffset));
1308   __ Branch(&entry);
1309
1310   // Load the current argument from the arguments array.
1311   __ bind(&loop);
1312   __ ld(receiver, MemOperand(fp, argumentsOffset));
1313
1314   // Use inline caching to speed up access to arguments.
1315   Code::Kind kinds[] = {Code::KEYED_LOAD_IC};
1316   FeedbackVectorSpec spec(0, 1, kinds);
1317   Handle<TypeFeedbackVector> feedback_vector =
1318       masm->isolate()->factory()->NewTypeFeedbackVector(&spec);
1319   int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0));
1320   __ li(slot, Operand(Smi::FromInt(index)));
1321   __ li(vector, feedback_vector);
1322   Handle<Code> ic =
1323       KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode();
1324   __ Call(ic, RelocInfo::CODE_TARGET);
1325
1326   __ push(v0);
1327
1328   // Use inline caching to access the arguments.
1329   __ ld(key, MemOperand(fp, indexOffset));
1330   __ Daddu(key, key, Operand(Smi::FromInt(1)));
1331   __ sd(key, MemOperand(fp, indexOffset));
1332
1333   // Test if the copy loop has finished copying all the elements from the
1334   // arguments object.
1335   __ bind(&entry);
1336   __ ld(a1, MemOperand(fp, limitOffset));
1337   __ Branch(&loop, ne, key, Operand(a1));
1338
1339   // On exit, the pushed arguments count is in a0, untagged
1340   __ mov(a0, key);
1341   __ SmiUntag(a0);
1342 }
1343
1344
1345 // Used by FunctionApply and ReflectApply
1346 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
1347   const int kFormalParameters = targetIsArgument ? 3 : 2;
1348   const int kStackSize = kFormalParameters + 1;
1349
1350   {
1351     FrameScope frame_scope(masm, StackFrame::INTERNAL);
1352     const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
1353     const int kReceiverOffset = kArgumentsOffset + kPointerSize;
1354     const int kFunctionOffset = kReceiverOffset + kPointerSize;
1355
1356     __ ld(a0, MemOperand(fp, kFunctionOffset));  // Get the function.
1357     __ ld(a1, MemOperand(fp, kArgumentsOffset));  // Get the args array.
1358     __ Push(a0, a1);
1359
1360     // Returns (in v0) number of arguments to copy to stack as Smi.
1361     if (targetIsArgument) {
1362       __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
1363                        CALL_FUNCTION);
1364     } else {
1365       __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
1366     }
1367
1368     // Returns the result in v0.
1369     Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged);
1370
1371     // Push current limit and index.
1372     const int kIndexOffset =
1373         StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
1374     const int kLimitOffset =
1375         StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
1376     __ mov(a1, zero_reg);
1377     __ ld(a2, MemOperand(fp, kReceiverOffset));
1378     __ Push(v0, a1, a2);  // limit, initial index and receiver.
1379
1380     // Copy all arguments from the array to the stack.
1381     Generate_PushAppliedArguments(masm, kArgumentsOffset, kIndexOffset,
1382                                   kLimitOffset);
1383
1384     // Call the callable.
1385     // TODO(bmeurer): This should be a tail call according to ES6.
1386     __ ld(a1, MemOperand(fp, kFunctionOffset));
1387     __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1388
1389     // Tear down the internal frame and remove function, receiver and args.
1390   }
1391
1392   __ Ret(USE_DELAY_SLOT);
1393   __ Daddu(sp, sp, Operand(kStackSize * kPointerSize));  // In delay slot.
1394 }
1395
1396
1397 static void Generate_ConstructHelper(MacroAssembler* masm) {
1398   const int kFormalParameters = 3;
1399   const int kStackSize = kFormalParameters + 1;
1400
1401   {
1402     FrameScope frame_scope(masm, StackFrame::INTERNAL);
1403     const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
1404     const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
1405     const int kFunctionOffset = kArgumentsOffset + kPointerSize;
1406
1407     // If newTarget is not supplied, set it to constructor
1408     Label validate_arguments;
1409     __ ld(a0, MemOperand(fp, kNewTargetOffset));
1410     __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
1411     __ Branch(&validate_arguments, ne, a0, Operand(at));
1412     __ ld(a0, MemOperand(fp, kFunctionOffset));
1413     __ sd(a0, MemOperand(fp, kNewTargetOffset));
1414
1415     // Validate arguments
1416     __ bind(&validate_arguments);
1417     __ ld(a0, MemOperand(fp, kFunctionOffset));  // get the function
1418     __ push(a0);
1419     __ ld(a0, MemOperand(fp, kArgumentsOffset));  // get the args array
1420     __ push(a0);
1421     __ ld(a0, MemOperand(fp, kNewTargetOffset));  // get the new.target
1422     __ push(a0);
1423     // Returns argument count in v0.
1424     __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX,
1425                      CALL_FUNCTION);
1426
1427     // Returns result in v0.
1428     Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged);
1429
1430     // Push current limit and index.
1431     const int kIndexOffset =
1432         StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
1433     const int kLimitOffset =
1434         StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
1435     __ push(v0);  // limit
1436     __ mov(a1, zero_reg);  // initial index
1437     __ push(a1);
1438     // Push the constructor function as callee.
1439     __ ld(a0, MemOperand(fp, kFunctionOffset));
1440     __ push(a0);
1441
1442     // Copy all arguments from the array to the stack.
1443     Generate_PushAppliedArguments(
1444         masm, kArgumentsOffset, kIndexOffset, kLimitOffset);
1445
1446     // Use undefined feedback vector
1447     __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
1448     __ ld(a1, MemOperand(fp, kFunctionOffset));
1449     __ ld(a4, MemOperand(fp, kNewTargetOffset));
1450
1451     // Call the function.
1452     CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL);
1453     __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
1454
1455     // Leave internal frame.
1456   }
1457   __ jr(ra);
1458   __ Daddu(sp, sp, Operand(kStackSize * kPointerSize));  // In delay slot.
1459 }
1460
1461
1462 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
1463   Generate_ApplyHelper(masm, false);
1464 }
1465
1466
1467 void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1468   Generate_ApplyHelper(masm, true);
1469 }
1470
1471
1472 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
1473   Generate_ConstructHelper(masm);
1474 }
1475
1476
1477 static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
1478                                       Label* stack_overflow) {
1479   // ----------- S t a t e -------------
1480   //  -- a0 : actual number of arguments
1481   //  -- a1 : function (passed through to callee)
1482   //  -- a2 : expected number of arguments
1483   // -----------------------------------
1484   // Check the stack for overflow. We are not trying to catch
1485   // interruptions (e.g. debug break and preemption) here, so the "real stack
1486   // limit" is checked.
1487   __ LoadRoot(a5, Heap::kRealStackLimitRootIndex);
1488   // Make a5 the space we have left. The stack might already be overflowed
1489   // here which will cause a5 to become negative.
1490   __ dsubu(a5, sp, a5);
1491   // Check if the arguments will overflow the stack.
1492   __ dsll(at, a2, kPointerSizeLog2);
1493   // Signed comparison.
1494   __ Branch(stack_overflow, le, a5, Operand(at));
1495 }
1496
1497
1498 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
1499   // __ sll(a0, a0, kSmiTagSize);
1500   __ dsll32(a0, a0, 0);
1501   __ li(a4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1502   __ MultiPush(a0.bit() | a1.bit() | a4.bit() | fp.bit() | ra.bit());
1503   __ Daddu(fp, sp,
1504       Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize));
1505 }
1506
1507
1508 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
1509   // ----------- S t a t e -------------
1510   //  -- v0 : result being passed through
1511   // -----------------------------------
1512   // Get the number of arguments passed (as a smi), tear down the frame and
1513   // then tear down the parameters.
1514   __ ld(a1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
1515                              kPointerSize)));
1516   __ mov(sp, fp);
1517   __ MultiPop(fp.bit() | ra.bit());
1518   __ SmiScale(a4, a1, kPointerSizeLog2);
1519   __ Daddu(sp, sp, a4);
1520   // Adjust for the receiver.
1521   __ Daddu(sp, sp, Operand(kPointerSize));
1522 }
1523
1524
1525 // static
1526 void Builtins::Generate_CallFunction(MacroAssembler* masm) {
1527   // ----------- S t a t e -------------
1528   //  -- a0 : the number of arguments (not including the receiver)
1529   //  -- a1 : the function to call (checked to be a JSFunction)
1530   // -----------------------------------
1531
1532   Label convert, convert_global_proxy, convert_to_object, done_convert;
1533   __ AssertFunction(a1);
1534   // TODO(bmeurer): Throw a TypeError if function's [[FunctionKind]] internal
1535   // slot is "classConstructor".
1536   // Enter the context of the function; ToObject has to run in the function
1537   // context, and we also need to take the global proxy from the function
1538   // context in case of conversion.
1539   // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
1540   STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset ==
1541                 SharedFunctionInfo::kStrictModeByteOffset);
1542   __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
1543   __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1544   // We need to convert the receiver for non-native sloppy mode functions.
1545   __ lbu(a3, FieldMemOperand(a2, SharedFunctionInfo::kNativeByteOffset));
1546   __ And(at, a3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) |
1547                          (1 << SharedFunctionInfo::kStrictModeBitWithinByte)));
1548   __ Branch(&done_convert, ne, at, Operand(zero_reg));
1549   {
1550     __ dsll(at, a0, kPointerSizeLog2);
1551     __ daddu(at, sp, at);
1552     __ ld(a3, MemOperand(at));
1553
1554     // ----------- S t a t e -------------
1555     //  -- a0 : the number of arguments (not including the receiver)
1556     //  -- a1 : the function to call (checked to be a JSFunction)
1557     //  -- a2 : the shared function info.
1558     //  -- a3 : the receiver
1559     //  -- cp : the function context.
1560     // -----------------------------------
1561
1562     Label convert_receiver;
1563     __ JumpIfSmi(a3, &convert_to_object);
1564     STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
1565     __ GetObjectType(a3, a4, a4);
1566     __ Branch(&done_convert, hs, a4, Operand(FIRST_JS_RECEIVER_TYPE));
1567     __ JumpIfRoot(a3, Heap::kUndefinedValueRootIndex, &convert_global_proxy);
1568     __ JumpIfNotRoot(a3, Heap::kNullValueRootIndex, &convert_to_object);
1569     __ bind(&convert_global_proxy);
1570     {
1571       // Patch receiver to global proxy.
1572       __ LoadGlobalProxy(a3);
1573     }
1574     __ Branch(&convert_receiver);
1575     __ bind(&convert_to_object);
1576     {
1577       // Convert receiver using ToObject.
1578       // TODO(bmeurer): Inline the allocation here to avoid building the frame
1579       // in the fast case? (fall back to AllocateInNewSpace?)
1580       FrameScope scope(masm, StackFrame::INTERNAL);
1581       __ SmiTag(a0);
1582       __ Push(a0, a1);
1583       __ mov(a0, a3);
1584       ToObjectStub stub(masm->isolate());
1585       __ CallStub(&stub);
1586       __ mov(a3, v0);
1587       __ Pop(a0, a1);
1588       __ SmiUntag(a0);
1589     }
1590     __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1591     __ bind(&convert_receiver);
1592     __ dsll(at, a0, kPointerSizeLog2);
1593     __ daddu(at, sp, at);
1594     __ sd(a3, MemOperand(at));
1595   }
1596   __ bind(&done_convert);
1597
1598   // ----------- S t a t e -------------
1599   //  -- a0 : the number of arguments (not including the receiver)
1600   //  -- a1 : the function to call (checked to be a JSFunction)
1601   //  -- a2 : the shared function info.
1602   //  -- cp : the function context.
1603   // -----------------------------------
1604
1605   __ lw(a2,
1606         FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset));
1607   __ ld(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
1608   ParameterCount actual(a0);
1609   ParameterCount expected(a2);
1610   __ InvokeCode(a3, expected, actual, JUMP_FUNCTION, NullCallWrapper());
1611 }
1612
1613
1614 // static
1615 void Builtins::Generate_Call(MacroAssembler* masm) {
1616   // ----------- S t a t e -------------
1617   //  -- a0 : the number of arguments (not including the receiver)
1618   //  -- a1 : the target to call (can be any Object).
1619   // -----------------------------------
1620
1621   Label non_smi, non_function;
1622   __ JumpIfSmi(a1, &non_function);
1623   __ bind(&non_smi);
1624   __ GetObjectType(a1, a2, a2);
1625   __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET,
1626           eq, a2, Operand(JS_FUNCTION_TYPE));
1627   __ Branch(&non_function, ne, a2, Operand(JS_FUNCTION_PROXY_TYPE));
1628
1629   // 1. Call to function proxy.
1630   // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies.
1631   __ ld(a1, FieldMemOperand(a1, JSFunctionProxy::kCallTrapOffset));
1632   __ AssertNotSmi(a1);
1633   __ Branch(&non_smi);
1634
1635   // 2. Call to something else, which might have a [[Call]] internal method (if
1636   // not we raise an exception).
1637   __ bind(&non_function);
1638   // TODO(bmeurer): I wonder why we prefer to have slow API calls? This could
1639   // be awesome instead; i.e. a trivial improvement would be to call into the
1640   // runtime and just deal with the API function there instead of returning a
1641   // delegate from a runtime call that just jumps back to the runtime once
1642   // called. Or, bonus points, call directly into the C API function here, as
1643   // we do in some Crankshaft fast cases.
1644   // Overwrite the original receiver with the (original) target.
1645   __ dsll(at, a0, kPointerSizeLog2);
1646   __ daddu(at, sp, at);
1647   __ sd(a1, MemOperand(at));
1648   {
1649     // Determine the delegate for the target (if any).
1650     FrameScope scope(masm, StackFrame::INTERNAL);
1651     __ SmiTag(a0);
1652     __ Push(a0, a1);
1653     __ CallRuntime(Runtime::kGetFunctionDelegate, 1);
1654     __ mov(a1, v0);
1655     __ Pop(a0);
1656     __ SmiUntag(a0);
1657   }
1658   // The delegate is always a regular function.
1659   __ AssertFunction(a1);
1660   __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
1661 }
1662
1663
1664 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
1665   // State setup as expected by MacroAssembler::InvokePrologue.
1666   // ----------- S t a t e -------------
1667   //  -- a0: actual arguments count
1668   //  -- a1: function (passed through to callee)
1669   //  -- a2: expected arguments count
1670   // -----------------------------------
1671
1672   Label stack_overflow;
1673   ArgumentAdaptorStackCheck(masm, &stack_overflow);
1674   Label invoke, dont_adapt_arguments;
1675
1676   Label enough, too_few;
1677   __ ld(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
1678   __ Branch(&dont_adapt_arguments, eq,
1679       a2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
1680   // We use Uless as the number of argument should always be greater than 0.
1681   __ Branch(&too_few, Uless, a0, Operand(a2));
1682
1683   {  // Enough parameters: actual >= expected.
1684     // a0: actual number of arguments as a smi
1685     // a1: function
1686     // a2: expected number of arguments
1687     // a3: code entry to call
1688     __ bind(&enough);
1689     EnterArgumentsAdaptorFrame(masm);
1690
1691     // Calculate copy start address into a0 and copy end address into a4.
1692     __ SmiScale(a0, a0, kPointerSizeLog2);
1693     __ Daddu(a0, fp, a0);
1694     // Adjust for return address and receiver.
1695     __ Daddu(a0, a0, Operand(2 * kPointerSize));
1696     // Compute copy end address.
1697     __ dsll(a4, a2, kPointerSizeLog2);
1698     __ dsubu(a4, a0, a4);
1699
1700     // Copy the arguments (including the receiver) to the new stack frame.
1701     // a0: copy start address
1702     // a1: function
1703     // a2: expected number of arguments
1704     // a3: code entry to call
1705     // a4: copy end address
1706
1707     Label copy;
1708     __ bind(&copy);
1709     __ ld(a5, MemOperand(a0));
1710     __ push(a5);
1711     __ Branch(USE_DELAY_SLOT, &copy, ne, a0, Operand(a4));
1712     __ daddiu(a0, a0, -kPointerSize);  // In delay slot.
1713
1714     __ jmp(&invoke);
1715   }
1716
1717   {  // Too few parameters: Actual < expected.
1718     __ bind(&too_few);
1719
1720     // If the function is strong we need to throw an error.
1721     Label no_strong_error;
1722     __ ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1723     __ lbu(a5, FieldMemOperand(a4, SharedFunctionInfo::kStrongModeByteOffset));
1724     __ And(a5, a5, Operand(1 << SharedFunctionInfo::kStrongModeBitWithinByte));
1725     __ Branch(&no_strong_error, eq, a5, Operand(zero_reg));
1726
1727     // What we really care about is the required number of arguments.
1728     DCHECK_EQ(kPointerSize, kInt64Size);
1729     __ lw(a5, FieldMemOperand(a4, SharedFunctionInfo::kLengthOffset));
1730     __ srl(a5, a5, 1);
1731     __ Branch(&no_strong_error, ge, a0, Operand(a5));
1732
1733     {
1734       FrameScope frame(masm, StackFrame::MANUAL);
1735       EnterArgumentsAdaptorFrame(masm);
1736       __ CallRuntime(Runtime::kThrowStrongModeTooFewArguments, 0);
1737     }
1738
1739     __ bind(&no_strong_error);
1740     EnterArgumentsAdaptorFrame(masm);
1741
1742     // Calculate copy start address into a0 and copy end address into a7.
1743     // a0: actual number of arguments as a smi
1744     // a1: function
1745     // a2: expected number of arguments
1746     // a3: code entry to call
1747     __ SmiScale(a0, a0, kPointerSizeLog2);
1748     __ Daddu(a0, fp, a0);
1749     // Adjust for return address and receiver.
1750     __ Daddu(a0, a0, Operand(2 * kPointerSize));
1751     // Compute copy end address. Also adjust for return address.
1752     __ Daddu(a7, fp, kPointerSize);
1753
1754     // Copy the arguments (including the receiver) to the new stack frame.
1755     // a0: copy start address
1756     // a1: function
1757     // a2: expected number of arguments
1758     // a3: code entry to call
1759     // a7: copy end address
1760     Label copy;
1761     __ bind(&copy);
1762     __ ld(a4, MemOperand(a0));  // Adjusted above for return addr and receiver.
1763     __ Dsubu(sp, sp, kPointerSize);
1764     __ Dsubu(a0, a0, kPointerSize);
1765     __ Branch(USE_DELAY_SLOT, &copy, ne, a0, Operand(a7));
1766     __ sd(a4, MemOperand(sp));  // In the delay slot.
1767
1768     // Fill the remaining expected arguments with undefined.
1769     // a1: function
1770     // a2: expected number of arguments
1771     // a3: code entry to call
1772     __ LoadRoot(a5, Heap::kUndefinedValueRootIndex);
1773     __ dsll(a6, a2, kPointerSizeLog2);
1774     __ Dsubu(a4, fp, Operand(a6));
1775     // Adjust for frame.
1776     __ Dsubu(a4, a4, Operand(StandardFrameConstants::kFixedFrameSizeFromFp +
1777                              2 * kPointerSize));
1778
1779     Label fill;
1780     __ bind(&fill);
1781     __ Dsubu(sp, sp, kPointerSize);
1782     __ Branch(USE_DELAY_SLOT, &fill, ne, sp, Operand(a4));
1783     __ sd(a5, MemOperand(sp));
1784   }
1785
1786   // Call the entry point.
1787   __ bind(&invoke);
1788   __ mov(a0, a2);
1789   // a0 : expected number of arguments
1790   // a1 : function (passed through to callee)
1791   __ Call(a3);
1792
1793   // Store offset of return address for deoptimizer.
1794   masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
1795
1796   // Exit frame and return.
1797   LeaveArgumentsAdaptorFrame(masm);
1798   __ Ret();
1799
1800
1801   // -------------------------------------------
1802   // Don't adapt arguments.
1803   // -------------------------------------------
1804   __ bind(&dont_adapt_arguments);
1805   __ Jump(a3);
1806
1807   __ bind(&stack_overflow);
1808   {
1809     FrameScope frame(masm, StackFrame::MANUAL);
1810     EnterArgumentsAdaptorFrame(masm);
1811     __ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
1812     __ break_(0xCC);
1813   }
1814 }
1815
1816
1817 #undef __
1818
1819 }  // namespace internal
1820 }  // namespace v8
1821
1822 #endif  // V8_TARGET_ARCH_MIPS64