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