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
13namespace v8 {
14namespace internal {
15
16#define __ ACCESS_MASM(masm)
17
18void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
19                                ExitFrameType exit_frame_type) {
20  // ----------- S t a t e -------------
21  //  -- a0                 : number of arguments excluding receiver
22  //  -- a1                 : target
23  //  -- a3                 : new.target
24  //  -- sp[0]              : last argument
25  //  -- ...
26  //  -- sp[4 * (argc - 1)] : first argument
27  //  -- sp[4 * agrc]       : receiver
28  // -----------------------------------
29  __ AssertFunction(a1);
30
31  // Make sure we operate in the context of the called function (for example
32  // ConstructStubs implemented in C++ will be run in the context of the caller
33  // instead of the callee, due to the way that [[Construct]] is defined for
34  // ordinary functions).
35  __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
36
37  // JumpToExternalReference expects a0 to contain the number of arguments
38  // including the receiver and the extra arguments.
39  const int num_extra_args = 3;
40  __ Addu(a0, a0, num_extra_args + 1);
41
42  // Insert extra arguments.
43  __ SmiTag(a0);
44  __ Push(a0, a1, a3);
45  __ SmiUntag(a0);
46
47  __ JumpToExternalReference(ExternalReference(address, masm->isolate()),
48                             PROTECT, exit_frame_type == BUILTIN_EXIT);
49}
50
51// Load the built-in InternalArray function from the current context.
52static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
53                                              Register result) {
54  // Load the InternalArray function from the native context.
55  __ LoadNativeContextSlot(Context::INTERNAL_ARRAY_FUNCTION_INDEX, result);
56}
57
58// Load the built-in Array function from the current context.
59static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
60  // Load the Array function from the native context.
61  __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, result);
62}
63
64void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
65  // ----------- S t a t e -------------
66  //  -- a0     : number of arguments
67  //  -- ra     : return address
68  //  -- sp[...]: constructor arguments
69  // -----------------------------------
70  Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
71
72  // Get the InternalArray function.
73  GenerateLoadInternalArrayFunction(masm, a1);
74
75  if (FLAG_debug_code) {
76    // Initial map for the builtin InternalArray functions should be maps.
77    __ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
78    __ SmiTst(a2, t0);
79    __ Assert(ne, kUnexpectedInitialMapForInternalArrayFunction, t0,
80              Operand(zero_reg));
81    __ GetObjectType(a2, a3, t0);
82    __ Assert(eq, kUnexpectedInitialMapForInternalArrayFunction, t0,
83              Operand(MAP_TYPE));
84  }
85
86  // Run the native code for the InternalArray function called as a normal
87  // function.
88  // Tail call a stub.
89  InternalArrayConstructorStub stub(masm->isolate());
90  __ TailCallStub(&stub);
91}
92
93void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
94  // ----------- S t a t e -------------
95  //  -- a0     : number of arguments
96  //  -- ra     : return address
97  //  -- sp[...]: constructor arguments
98  // -----------------------------------
99  Label generic_array_code;
100
101  // Get the Array function.
102  GenerateLoadArrayFunction(masm, a1);
103
104  if (FLAG_debug_code) {
105    // Initial map for the builtin Array functions should be maps.
106    __ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
107    __ SmiTst(a2, t0);
108    __ Assert(ne, kUnexpectedInitialMapForArrayFunction1, t0,
109              Operand(zero_reg));
110    __ GetObjectType(a2, a3, t0);
111    __ Assert(eq, kUnexpectedInitialMapForArrayFunction2, t0,
112              Operand(MAP_TYPE));
113  }
114
115  // Run the native code for the Array function called as a normal function.
116  // Tail call a stub.
117  __ mov(a3, a1);
118  __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
119  ArrayConstructorStub stub(masm->isolate());
120  __ TailCallStub(&stub);
121}
122
123// static
124void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
125  // ----------- S t a t e -------------
126  //  -- a0                     : number of arguments
127  //  -- a1                     : function
128  //  -- cp                     : context
129  //  -- ra                     : return address
130  //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
131  //  -- sp[argc * 4]           : receiver
132  // -----------------------------------
133  Heap::RootListIndex const root_index =
134      (kind == MathMaxMinKind::kMin) ? Heap::kInfinityValueRootIndex
135                                     : Heap::kMinusInfinityValueRootIndex;
136
137  // Load the accumulator with the default return value (either -Infinity or
138  // +Infinity), with the tagged value in t2 and the double value in f0.
139  __ LoadRoot(t2, root_index);
140  __ ldc1(f0, FieldMemOperand(t2, HeapNumber::kValueOffset));
141
142  Label done_loop, loop, done;
143  __ mov(a3, a0);
144  __ bind(&loop);
145  {
146    // Check if all parameters done.
147    __ Subu(a3, a3, Operand(1));
148    __ Branch(&done_loop, lt, a3, Operand(zero_reg));
149
150    // Load the next parameter tagged value into a2.
151    __ Lsa(at, sp, a3, kPointerSizeLog2);
152    __ lw(a2, MemOperand(at));
153
154    // Load the double value of the parameter into f2, maybe converting the
155    // parameter to a number first using the ToNumber builtin if necessary.
156    Label convert, convert_smi, convert_number, done_convert;
157    __ bind(&convert);
158    __ JumpIfSmi(a2, &convert_smi);
159    __ lw(t0, FieldMemOperand(a2, HeapObject::kMapOffset));
160    __ JumpIfRoot(t0, Heap::kHeapNumberMapRootIndex, &convert_number);
161    {
162      // Parameter is not a Number, use the ToNumber builtin to convert it.
163      FrameScope scope(masm, StackFrame::MANUAL);
164      __ SmiTag(a0);
165      __ SmiTag(a3);
166      __ EnterBuiltinFrame(cp, a1, a0);
167      __ Push(t2, a3);
168      __ mov(a0, a2);
169      __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
170      __ mov(a2, v0);
171      __ Pop(t2, a3);
172      __ LeaveBuiltinFrame(cp, a1, a0);
173      __ SmiUntag(a3);
174      __ SmiUntag(a0);
175      {
176        // Restore the double accumulator value (f0).
177        Label restore_smi, done_restore;
178        __ JumpIfSmi(t2, &restore_smi);
179        __ ldc1(f0, FieldMemOperand(t2, HeapNumber::kValueOffset));
180        __ jmp(&done_restore);
181        __ bind(&restore_smi);
182        __ SmiToDoubleFPURegister(t2, f0, t0);
183        __ bind(&done_restore);
184      }
185    }
186    __ jmp(&convert);
187    __ bind(&convert_number);
188    __ ldc1(f2, FieldMemOperand(a2, HeapNumber::kValueOffset));
189    __ jmp(&done_convert);
190    __ bind(&convert_smi);
191    __ SmiToDoubleFPURegister(a2, f2, t0);
192    __ bind(&done_convert);
193
194    // Perform the actual comparison with using Min/Max macro instructions the
195    // accumulator value on the left hand side (f0) and the next parameter value
196    // on the right hand side (f2).
197    // We need to work out which HeapNumber (or smi) the result came from.
198    Label compare_nan, set_value, ool_min, ool_max;
199    __ BranchF(nullptr, &compare_nan, eq, f0, f2);
200    __ Move(t0, t1, f0);
201    if (kind == MathMaxMinKind::kMin) {
202      __ Float64Min(f0, f0, f2, &ool_min);
203    } else {
204      DCHECK(kind == MathMaxMinKind::kMax);
205      __ Float64Max(f0, f0, f2, &ool_max);
206    }
207    __ jmp(&done);
208
209    __ bind(&ool_min);
210    __ Float64MinOutOfLine(f0, f0, f2);
211    __ jmp(&done);
212
213    __ bind(&ool_max);
214    __ Float64MaxOutOfLine(f0, f0, f2);
215
216    __ bind(&done);
217    __ Move(at, t8, f0);
218    __ Branch(&set_value, ne, t0, Operand(at));
219    __ Branch(&set_value, ne, t1, Operand(t8));
220    __ jmp(&loop);
221    __ bind(&set_value);
222    __ mov(t2, a2);
223    __ jmp(&loop);
224
225    // At least one side is NaN, which means that the result will be NaN too.
226    __ bind(&compare_nan);
227    __ LoadRoot(t2, Heap::kNanValueRootIndex);
228    __ ldc1(f0, FieldMemOperand(t2, HeapNumber::kValueOffset));
229    __ jmp(&loop);
230  }
231
232  __ bind(&done_loop);
233  // Drop all slots, including the receiver.
234  __ Addu(a0, a0, Operand(1));
235  __ Lsa(sp, sp, a0, kPointerSizeLog2);
236  __ Ret(USE_DELAY_SLOT);
237  __ mov(v0, t2);  // In delay slot.
238}
239
240// static
241void Builtins::Generate_NumberConstructor(MacroAssembler* masm) {
242  // ----------- S t a t e -------------
243  //  -- a0                     : number of arguments
244  //  -- a1                     : constructor function
245  //  -- cp                     : context
246  //  -- ra                     : return address
247  //  -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
248  //  -- sp[argc * 4]           : receiver
249  // -----------------------------------
250
251  // 1. Load the first argument into a0.
252  Label no_arguments;
253  {
254    __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg));
255    __ Subu(t1, a0, Operand(1));  // In delay slot.
256    __ mov(t0, a0);               // Store argc in t0.
257    __ Lsa(at, sp, t1, kPointerSizeLog2);
258    __ lw(a0, MemOperand(at));
259  }
260
261  // 2a. Convert first argument to number.
262  {
263    FrameScope scope(masm, StackFrame::MANUAL);
264    __ SmiTag(t0);
265    __ EnterBuiltinFrame(cp, a1, t0);
266    __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
267    __ LeaveBuiltinFrame(cp, a1, t0);
268    __ SmiUntag(t0);
269  }
270
271  {
272    // Drop all arguments including the receiver.
273    __ Lsa(sp, sp, t0, kPointerSizeLog2);
274    __ DropAndRet(1);
275  }
276
277  // 2b. No arguments, return +0.
278  __ bind(&no_arguments);
279  __ Move(v0, Smi::kZero);
280  __ DropAndRet(1);
281}
282
283// static
284void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
285  // ----------- S t a t e -------------
286  //  -- a0                     : number of arguments
287  //  -- a1                     : constructor function
288  //  -- a3                     : new target
289  //  -- cp                     : context
290  //  -- ra                     : return address
291  //  -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
292  //  -- sp[argc * 4]           : receiver
293  // -----------------------------------
294
295  // 1. Make sure we operate in the context of the called function.
296  __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
297
298  // 2. Load the first argument into a0.
299  {
300    Label no_arguments, done;
301    __ mov(t0, a0);  // Store argc in t0.
302    __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg));
303    __ Subu(t1, a0, Operand(1));  // In delay slot.
304    __ Lsa(at, sp, t1, kPointerSizeLog2);
305    __ lw(a0, MemOperand(at));
306    __ jmp(&done);
307    __ bind(&no_arguments);
308    __ Move(a0, Smi::kZero);
309    __ bind(&done);
310  }
311
312  // 3. Make sure a0 is a number.
313  {
314    Label done_convert;
315    __ JumpIfSmi(a0, &done_convert);
316    __ GetObjectType(a0, a2, a2);
317    __ Branch(&done_convert, eq, a2, Operand(HEAP_NUMBER_TYPE));
318    {
319      FrameScope scope(masm, StackFrame::MANUAL);
320      __ SmiTag(t0);
321      __ EnterBuiltinFrame(cp, a1, t0);
322      __ Push(a3);
323      __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
324      __ Move(a0, v0);
325      __ Pop(a3);
326      __ LeaveBuiltinFrame(cp, a1, t0);
327      __ SmiUntag(t0);
328    }
329    __ bind(&done_convert);
330  }
331
332  // 4. Check if new target and constructor differ.
333  Label drop_frame_and_ret, new_object;
334  __ Branch(&new_object, ne, a1, Operand(a3));
335
336  // 5. Allocate a JSValue wrapper for the number.
337  __ AllocateJSValue(v0, a1, a0, a2, t1, &new_object);
338  __ jmp(&drop_frame_and_ret);
339
340  // 6. Fallback to the runtime to create new object.
341  __ bind(&new_object);
342  {
343    FrameScope scope(masm, StackFrame::MANUAL);
344    __ SmiTag(t0);
345    __ EnterBuiltinFrame(cp, a1, t0);
346    __ Push(a0);  // first argument
347    __ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
348            RelocInfo::CODE_TARGET);
349    __ Pop(a0);
350    __ LeaveBuiltinFrame(cp, a1, t0);
351    __ SmiUntag(t0);
352  }
353  __ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset));
354
355  __ bind(&drop_frame_and_ret);
356  {
357    __ Lsa(sp, sp, t0, kPointerSizeLog2);
358    __ DropAndRet(1);
359  }
360}
361
362// static
363void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
364  // ----------- S t a t e -------------
365  //  -- a0                     : number of arguments
366  //  -- a1                     : constructor function
367  //  -- cp                     : context
368  //  -- ra                     : return address
369  //  -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
370  //  -- sp[argc * 4]           : receiver
371  // -----------------------------------
372
373  // 1. Load the first argument into a0.
374  Label no_arguments;
375  {
376    __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg));
377    __ Subu(t1, a0, Operand(1));
378    __ mov(t0, a0);  // Store argc in t0.
379    __ Lsa(at, sp, t1, kPointerSizeLog2);
380    __ lw(a0, MemOperand(at));
381  }
382
383  // 2a. At least one argument, return a0 if it's a string, otherwise
384  // dispatch to appropriate conversion.
385  Label drop_frame_and_ret, to_string, symbol_descriptive_string;
386  {
387    __ JumpIfSmi(a0, &to_string);
388    __ GetObjectType(a0, t1, t1);
389    STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE);
390    __ Subu(t1, t1, Operand(FIRST_NONSTRING_TYPE));
391    __ Branch(&symbol_descriptive_string, eq, t1, Operand(zero_reg));
392    __ Branch(&to_string, gt, t1, Operand(zero_reg));
393    __ mov(v0, a0);
394    __ jmp(&drop_frame_and_ret);
395  }
396
397  // 2b. No arguments, return the empty string (and pop the receiver).
398  __ bind(&no_arguments);
399  {
400    __ LoadRoot(v0, Heap::kempty_stringRootIndex);
401    __ DropAndRet(1);
402  }
403
404  // 3a. Convert a0 to a string.
405  __ bind(&to_string);
406  {
407    FrameScope scope(masm, StackFrame::MANUAL);
408    __ SmiTag(t0);
409    __ EnterBuiltinFrame(cp, a1, t0);
410    __ Call(masm->isolate()->builtins()->ToString(), RelocInfo::CODE_TARGET);
411    __ LeaveBuiltinFrame(cp, a1, t0);
412    __ SmiUntag(t0);
413  }
414  __ jmp(&drop_frame_and_ret);
415
416  // 3b. Convert symbol in a0 to a string.
417  __ bind(&symbol_descriptive_string);
418  {
419    __ Lsa(sp, sp, t0, kPointerSizeLog2);
420    __ Drop(1);
421    __ Push(a0);
422    __ TailCallRuntime(Runtime::kSymbolDescriptiveString);
423  }
424
425  __ bind(&drop_frame_and_ret);
426  {
427    __ Lsa(sp, sp, t0, kPointerSizeLog2);
428    __ DropAndRet(1);
429  }
430}
431
432// static
433void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
434  // ----------- S t a t e -------------
435  //  -- a0                     : number of arguments
436  //  -- a1                     : constructor function
437  //  -- a3                     : new target
438  //  -- cp                     : context
439  //  -- ra                     : return address
440  //  -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
441  //  -- sp[argc * 4]           : receiver
442  // -----------------------------------
443
444  // 1. Make sure we operate in the context of the called function.
445  __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
446
447  // 2. Load the first argument into a0.
448  {
449    Label no_arguments, done;
450    __ mov(t0, a0);  // Store argc in t0.
451    __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg));
452    __ Subu(t1, a0, Operand(1));
453    __ Lsa(at, sp, t1, kPointerSizeLog2);
454    __ lw(a0, MemOperand(at));
455    __ jmp(&done);
456    __ bind(&no_arguments);
457    __ LoadRoot(a0, Heap::kempty_stringRootIndex);
458    __ bind(&done);
459  }
460
461  // 3. Make sure a0 is a string.
462  {
463    Label convert, done_convert;
464    __ JumpIfSmi(a0, &convert);
465    __ GetObjectType(a0, a2, a2);
466    __ And(t1, a2, Operand(kIsNotStringMask));
467    __ Branch(&done_convert, eq, t1, Operand(zero_reg));
468    __ bind(&convert);
469    {
470      FrameScope scope(masm, StackFrame::MANUAL);
471      __ SmiTag(t0);
472      __ EnterBuiltinFrame(cp, a1, t0);
473      __ Push(a3);
474      __ Call(masm->isolate()->builtins()->ToString(), RelocInfo::CODE_TARGET);
475      __ Move(a0, v0);
476      __ Pop(a3);
477      __ LeaveBuiltinFrame(cp, a1, t0);
478      __ SmiUntag(t0);
479    }
480    __ bind(&done_convert);
481  }
482
483  // 4. Check if new target and constructor differ.
484  Label drop_frame_and_ret, new_object;
485  __ Branch(&new_object, ne, a1, Operand(a3));
486
487  // 5. Allocate a JSValue wrapper for the string.
488  __ AllocateJSValue(v0, a1, a0, a2, t1, &new_object);
489  __ jmp(&drop_frame_and_ret);
490
491  // 6. Fallback to the runtime to create new object.
492  __ bind(&new_object);
493  {
494    FrameScope scope(masm, StackFrame::MANUAL);
495    __ SmiTag(t0);
496    __ EnterBuiltinFrame(cp, a1, t0);
497    __ Push(a0);  // first argument
498    __ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
499            RelocInfo::CODE_TARGET);
500    __ Pop(a0);
501    __ LeaveBuiltinFrame(cp, a1, t0);
502    __ SmiUntag(t0);
503  }
504  __ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset));
505
506  __ bind(&drop_frame_and_ret);
507  {
508    __ Lsa(sp, sp, t0, kPointerSizeLog2);
509    __ DropAndRet(1);
510  }
511}
512
513static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
514  __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
515  __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset));
516  __ Addu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag));
517  __ Jump(at);
518}
519
520static void GenerateTailCallToReturnedCode(MacroAssembler* masm,
521                                           Runtime::FunctionId function_id) {
522  // ----------- S t a t e -------------
523  //  -- a0 : argument count (preserved for callee)
524  //  -- a1 : target function (preserved for callee)
525  //  -- a3 : new target (preserved for callee)
526  // -----------------------------------
527  {
528    FrameScope scope(masm, StackFrame::INTERNAL);
529    // Push a copy of the target function and the new target.
530    // Push function as parameter to the runtime call.
531    __ SmiTag(a0);
532    __ Push(a0, a1, a3, a1);
533
534    __ CallRuntime(function_id, 1);
535
536    // Restore target function and new target.
537    __ Pop(a0, a1, a3);
538    __ SmiUntag(a0);
539  }
540
541  __ Addu(at, v0, Operand(Code::kHeaderSize - kHeapObjectTag));
542  __ Jump(at);
543}
544
545void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) {
546  // Checking whether the queued function is ready for install is optional,
547  // since we come across interrupts and stack checks elsewhere.  However,
548  // not checking may delay installing ready functions, and always checking
549  // would be quite expensive.  A good compromise is to first check against
550  // stack limit as a cue for an interrupt signal.
551  Label ok;
552  __ LoadRoot(t0, Heap::kStackLimitRootIndex);
553  __ Branch(&ok, hs, sp, Operand(t0));
554
555  GenerateTailCallToReturnedCode(masm, Runtime::kTryInstallOptimizedCode);
556
557  __ bind(&ok);
558  GenerateTailCallToSharedCode(masm);
559}
560
561namespace {
562
563void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function,
564                                    bool create_implicit_receiver,
565                                    bool check_derived_construct) {
566  Label post_instantiation_deopt_entry;
567
568  // ----------- S t a t e -------------
569  //  -- a0     : number of arguments
570  //  -- a1     : constructor function
571  //  -- a3     : new target
572  //  -- cp     : context
573  //  -- ra     : return address
574  //  -- sp[...]: constructor arguments
575  // -----------------------------------
576
577  Isolate* isolate = masm->isolate();
578
579  // Enter a construct frame.
580  {
581    FrameScope scope(masm, StackFrame::CONSTRUCT);
582
583    // Preserve the incoming parameters on the stack.
584    __ SmiTag(a0);
585    __ Push(cp, a0);
586
587    if (create_implicit_receiver) {
588      // Allocate the new receiver object.
589      __ Push(a1, a3);
590      __ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
591              RelocInfo::CODE_TARGET);
592      __ mov(t4, v0);
593      __ Pop(a1, a3);
594
595      // ----------- S t a t e -------------
596      //  -- a1: constructor function
597      //  -- a3: new target
598      //  -- t0: newly allocated object
599      // -----------------------------------
600
601      // Retrieve smi-tagged arguments count from the stack.
602      __ lw(a0, MemOperand(sp));
603    }
604
605    __ SmiUntag(a0);
606
607    if (create_implicit_receiver) {
608      // Push the allocated receiver to the stack. We need two copies
609      // because we may have to return the original one and the calling
610      // conventions dictate that the called function pops the receiver.
611      __ Push(t4, t4);
612    } else {
613      __ PushRoot(Heap::kTheHoleValueRootIndex);
614    }
615
616    // Deoptimizer re-enters stub code here.
617    __ bind(&post_instantiation_deopt_entry);
618
619    // Set up pointer to last argument.
620    __ Addu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
621
622    // Copy arguments and receiver to the expression stack.
623    // a0: number of arguments
624    // a1: constructor function
625    // a2: address of last argument (caller sp)
626    // a3: new target
627    // t4: number of arguments (smi-tagged)
628    // sp[0]: receiver
629    // sp[1]: receiver
630    // sp[2]: number of arguments (smi-tagged)
631    Label loop, entry;
632    __ SmiTag(t4, a0);
633    __ jmp(&entry);
634    __ bind(&loop);
635    __ Lsa(t0, a2, t4, kPointerSizeLog2 - kSmiTagSize);
636    __ lw(t1, MemOperand(t0));
637    __ push(t1);
638    __ bind(&entry);
639    __ Addu(t4, t4, Operand(-2));
640    __ Branch(&loop, greater_equal, t4, Operand(zero_reg));
641
642    // Call the function.
643    // a0: number of arguments
644    // a1: constructor function
645    // a3: new target
646    ParameterCount actual(a0);
647    __ InvokeFunction(a1, a3, actual, CALL_FUNCTION,
648                      CheckDebugStepCallWrapper());
649
650    // Store offset of return address for deoptimizer.
651    if (create_implicit_receiver && !is_api_function) {
652      masm->isolate()->heap()->SetConstructStubInvokeDeoptPCOffset(
653          masm->pc_offset());
654    }
655
656    // Restore context from the frame.
657    __ lw(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
658
659    if (create_implicit_receiver) {
660      // If the result is an object (in the ECMA sense), we should get rid
661      // of the receiver and use the result; see ECMA-262 section 13.2.2-7
662      // on page 74.
663      Label use_receiver, exit;
664
665      // If the result is a smi, it is *not* an object in the ECMA sense.
666      // v0: result
667      // sp[0]: receiver (newly allocated object)
668      // sp[1]: number of arguments (smi-tagged)
669      __ JumpIfSmi(v0, &use_receiver);
670
671      // If the type of the result (stored in its map) is less than
672      // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
673      __ GetObjectType(v0, a1, a3);
674      __ Branch(&exit, greater_equal, a3, Operand(FIRST_JS_RECEIVER_TYPE));
675
676      // Throw away the result of the constructor invocation and use the
677      // on-stack receiver as the result.
678      __ bind(&use_receiver);
679      __ lw(v0, MemOperand(sp));
680
681      // Remove receiver from the stack, remove caller arguments, and
682      // return.
683      __ bind(&exit);
684      // v0: result
685      // sp[0]: receiver (newly allocated object)
686      // sp[1]: number of arguments (smi-tagged)
687      __ lw(a1, MemOperand(sp, 1 * kPointerSize));
688    } else {
689      __ lw(a1, MemOperand(sp));
690    }
691
692    // Leave construct frame.
693  }
694
695  // ES6 9.2.2. Step 13+
696  // Check that the result is not a Smi, indicating that the constructor result
697  // from a derived class is neither undefined nor an Object.
698  if (check_derived_construct) {
699    Label dont_throw;
700    __ JumpIfNotSmi(v0, &dont_throw);
701    {
702      FrameScope scope(masm, StackFrame::INTERNAL);
703      __ CallRuntime(Runtime::kThrowDerivedConstructorReturnedNonObject);
704    }
705    __ bind(&dont_throw);
706  }
707
708  __ Lsa(sp, sp, a1, kPointerSizeLog2 - 1);
709  __ Addu(sp, sp, kPointerSize);
710  if (create_implicit_receiver) {
711    __ IncrementCounter(isolate->counters()->constructed_objects(), 1, a1, a2);
712  }
713  __ Ret();
714
715  // Store offset of trampoline address for deoptimizer. This is the bailout
716  // point after the receiver instantiation but before the function invocation.
717  // We need to restore some registers in order to continue the above code.
718  if (create_implicit_receiver && !is_api_function) {
719    masm->isolate()->heap()->SetConstructStubCreateDeoptPCOffset(
720        masm->pc_offset());
721
722    // ----------- S t a t e -------------
723    //  -- a0    : newly allocated object
724    //  -- sp[0] : constructor function
725    // -----------------------------------
726
727    __ Pop(a1);
728    __ Push(a0, a0);
729
730    // Retrieve smi-tagged arguments count from the stack.
731    __ lw(a0, MemOperand(fp, ConstructFrameConstants::kLengthOffset));
732    __ SmiUntag(a0);
733
734    // Retrieve the new target value from the stack. This was placed into the
735    // frame description in place of the receiver by the optimizing compiler.
736    __ Addu(a3, fp, Operand(StandardFrameConstants::kCallerSPOffset));
737    __ Lsa(a3, a3, a0, kPointerSizeLog2);
738    __ lw(a3, MemOperand(a3));
739
740    // Continue with constructor function invocation.
741    __ jmp(&post_instantiation_deopt_entry);
742  }
743}
744
745}  // namespace
746
747void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
748  Generate_JSConstructStubHelper(masm, false, true, false);
749}
750
751void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
752  Generate_JSConstructStubHelper(masm, true, false, false);
753}
754
755void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
756  Generate_JSConstructStubHelper(masm, false, false, false);
757}
758
759void Builtins::Generate_JSBuiltinsConstructStubForDerived(
760    MacroAssembler* masm) {
761  Generate_JSConstructStubHelper(masm, false, false, true);
762}
763
764void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
765  FrameScope scope(masm, StackFrame::INTERNAL);
766  __ Push(a1);
767  __ CallRuntime(Runtime::kThrowConstructedNonConstructable);
768}
769
770enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt };
771
772// Clobbers a2; preserves all other registers.
773static void Generate_CheckStackOverflow(MacroAssembler* masm, Register argc,
774                                        IsTagged argc_is_tagged) {
775  // Check the stack for overflow. We are not trying to catch
776  // interruptions (e.g. debug break and preemption) here, so the "real stack
777  // limit" is checked.
778  Label okay;
779  __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
780  // Make a2 the space we have left. The stack might already be overflowed
781  // here which will cause a2 to become negative.
782  __ Subu(a2, sp, a2);
783  // Check if the arguments will overflow the stack.
784  if (argc_is_tagged == kArgcIsSmiTagged) {
785    __ sll(t3, argc, kPointerSizeLog2 - kSmiTagSize);
786  } else {
787    DCHECK(argc_is_tagged == kArgcIsUntaggedInt);
788    __ sll(t3, argc, kPointerSizeLog2);
789  }
790  // Signed comparison.
791  __ Branch(&okay, gt, a2, Operand(t3));
792
793  // Out of stack space.
794  __ CallRuntime(Runtime::kThrowStackOverflow);
795
796  __ bind(&okay);
797}
798
799static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
800                                             bool is_construct) {
801  // Called from JSEntryStub::GenerateBody
802
803  // ----------- S t a t e -------------
804  //  -- a0: new.target
805  //  -- a1: function
806  //  -- a2: receiver_pointer
807  //  -- a3: argc
808  //  -- s0: argv
809  // -----------------------------------
810  ProfileEntryHookStub::MaybeCallEntryHook(masm);
811
812  // Enter an internal frame.
813  {
814    FrameScope scope(masm, StackFrame::INTERNAL);
815
816    // Setup the context (we need to use the caller context from the isolate).
817    ExternalReference context_address(Isolate::kContextAddress,
818                                      masm->isolate());
819    __ li(cp, Operand(context_address));
820    __ lw(cp, MemOperand(cp));
821
822    // Push the function and the receiver onto the stack.
823    __ Push(a1, a2);
824
825    // Check if we have enough stack space to push all arguments.
826    // Clobbers a2.
827    Generate_CheckStackOverflow(masm, a3, kArgcIsUntaggedInt);
828
829    // Remember new.target.
830    __ mov(t1, a0);
831
832    // Copy arguments to the stack in a loop.
833    // a3: argc
834    // s0: argv, i.e. points to first arg
835    Label loop, entry;
836    __ Lsa(t2, s0, a3, kPointerSizeLog2);
837    __ b(&entry);
838    __ nop();  // Branch delay slot nop.
839    // t2 points past last arg.
840    __ bind(&loop);
841    __ lw(t0, MemOperand(s0));  // Read next parameter.
842    __ addiu(s0, s0, kPointerSize);
843    __ lw(t0, MemOperand(t0));  // Dereference handle.
844    __ push(t0);                // Push parameter.
845    __ bind(&entry);
846    __ Branch(&loop, ne, s0, Operand(t2));
847
848    // Setup new.target and argc.
849    __ mov(a0, a3);
850    __ mov(a3, t1);
851
852    // Initialize all JavaScript callee-saved registers, since they will be seen
853    // by the garbage collector as part of handlers.
854    __ LoadRoot(t0, Heap::kUndefinedValueRootIndex);
855    __ mov(s1, t0);
856    __ mov(s2, t0);
857    __ mov(s3, t0);
858    __ mov(s4, t0);
859    __ mov(s5, t0);
860    // s6 holds the root address. Do not clobber.
861    // s7 is cp. Do not init.
862
863    // Invoke the code.
864    Handle<Code> builtin = is_construct
865                               ? masm->isolate()->builtins()->Construct()
866                               : masm->isolate()->builtins()->Call();
867    __ Call(builtin, RelocInfo::CODE_TARGET);
868
869    // Leave internal frame.
870  }
871
872  __ Jump(ra);
873}
874
875void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
876  Generate_JSEntryTrampolineHelper(masm, false);
877}
878
879void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
880  Generate_JSEntryTrampolineHelper(masm, true);
881}
882
883// static
884void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
885  // ----------- S t a t e -------------
886  //  -- v0 : the value to pass to the generator
887  //  -- a1 : the JSGeneratorObject to resume
888  //  -- a2 : the resume mode (tagged)
889  //  -- ra : return address
890  // -----------------------------------
891  __ AssertGeneratorObject(a1);
892
893  // Store input value into generator object.
894  __ sw(v0, FieldMemOperand(a1, JSGeneratorObject::kInputOrDebugPosOffset));
895  __ RecordWriteField(a1, JSGeneratorObject::kInputOrDebugPosOffset, v0, a3,
896                      kRAHasNotBeenSaved, kDontSaveFPRegs);
897
898  // Store resume mode into generator object.
899  __ sw(a2, FieldMemOperand(a1, JSGeneratorObject::kResumeModeOffset));
900
901  // Load suspended function and context.
902  __ lw(t0, FieldMemOperand(a1, JSGeneratorObject::kFunctionOffset));
903  __ lw(cp, FieldMemOperand(t0, JSFunction::kContextOffset));
904
905  // Flood function if we are stepping.
906  Label prepare_step_in_if_stepping, prepare_step_in_suspended_generator;
907  Label stepping_prepared;
908  ExternalReference debug_hook =
909      ExternalReference::debug_hook_on_function_call_address(masm->isolate());
910  __ li(t1, Operand(debug_hook));
911  __ lb(t1, MemOperand(t1));
912  __ Branch(&prepare_step_in_if_stepping, ne, t1, Operand(zero_reg));
913
914  // Flood function if we need to continue stepping in the suspended generator.
915  ExternalReference debug_suspended_generator =
916      ExternalReference::debug_suspended_generator_address(masm->isolate());
917  __ li(t1, Operand(debug_suspended_generator));
918  __ lw(t1, MemOperand(t1));
919  __ Branch(&prepare_step_in_suspended_generator, eq, a1, Operand(t1));
920  __ bind(&stepping_prepared);
921
922  // Push receiver.
923  __ lw(t1, FieldMemOperand(a1, JSGeneratorObject::kReceiverOffset));
924  __ Push(t1);
925
926  // ----------- S t a t e -------------
927  //  -- a1    : the JSGeneratorObject to resume
928  //  -- a2    : the resume mode (tagged)
929  //  -- t0    : generator function
930  //  -- cp    : generator context
931  //  -- ra    : return address
932  //  -- sp[0] : generator receiver
933  // -----------------------------------
934
935  // Push holes for arguments to generator function. Since the parser forced
936  // context allocation for any variables in generators, the actual argument
937  // values have already been copied into the context and these dummy values
938  // will never be used.
939  __ lw(a3, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset));
940  __ lw(a3,
941        FieldMemOperand(a3, SharedFunctionInfo::kFormalParameterCountOffset));
942  {
943    Label done_loop, loop;
944    __ bind(&loop);
945    __ Subu(a3, a3, Operand(Smi::FromInt(1)));
946    __ Branch(&done_loop, lt, a3, Operand(zero_reg));
947    __ PushRoot(Heap::kTheHoleValueRootIndex);
948    __ Branch(&loop);
949    __ bind(&done_loop);
950  }
951
952  // Underlying function needs to have bytecode available.
953  if (FLAG_debug_code) {
954    __ lw(a3, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset));
955    __ lw(a3, FieldMemOperand(a3, SharedFunctionInfo::kFunctionDataOffset));
956    __ GetObjectType(a3, a3, a3);
957    __ Assert(eq, kMissingBytecodeArray, a3, Operand(BYTECODE_ARRAY_TYPE));
958  }
959
960  // Resume (Ignition/TurboFan) generator object.
961  {
962    __ lw(a0, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset));
963    __ lw(a0,
964          FieldMemOperand(a0, SharedFunctionInfo::kFormalParameterCountOffset));
965    __ SmiUntag(a0);
966    // We abuse new.target both to indicate that this is a resume call and to
967    // pass in the generator object.  In ordinary calls, new.target is always
968    // undefined because generator functions are non-constructable.
969    __ Move(a3, a1);
970    __ Move(a1, t0);
971    __ lw(a2, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
972    __ Jump(a2);
973  }
974
975  __ bind(&prepare_step_in_if_stepping);
976  {
977    FrameScope scope(masm, StackFrame::INTERNAL);
978    __ Push(a1, a2, t0);
979    __ CallRuntime(Runtime::kDebugOnFunctionCall);
980    __ Pop(a1, a2);
981  }
982  __ Branch(USE_DELAY_SLOT, &stepping_prepared);
983  __ lw(t0, FieldMemOperand(a1, JSGeneratorObject::kFunctionOffset));
984
985  __ bind(&prepare_step_in_suspended_generator);
986  {
987    FrameScope scope(masm, StackFrame::INTERNAL);
988    __ Push(a1, a2);
989    __ CallRuntime(Runtime::kDebugPrepareStepInSuspendedGenerator);
990    __ Pop(a1, a2);
991  }
992  __ Branch(USE_DELAY_SLOT, &stepping_prepared);
993  __ lw(t0, FieldMemOperand(a1, JSGeneratorObject::kFunctionOffset));
994}
995
996static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch) {
997  Register args_count = scratch;
998
999  // Get the arguments + receiver count.
1000  __ lw(args_count,
1001        MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
1002  __ lw(args_count,
1003        FieldMemOperand(args_count, BytecodeArray::kParameterSizeOffset));
1004
1005  // Leave the frame (also dropping the register file).
1006  __ LeaveFrame(StackFrame::JAVA_SCRIPT);
1007
1008  // Drop receiver + arguments.
1009  __ Addu(sp, sp, args_count);
1010}
1011
1012// Generate code for entering a JS function with the interpreter.
1013// On entry to the function the receiver and arguments have been pushed on the
1014// stack left to right.  The actual argument count matches the formal parameter
1015// count expected by the function.
1016//
1017// The live registers are:
1018//   o a1: the JS function object being called.
1019//   o a3: the new target
1020//   o cp: our context
1021//   o fp: the caller's frame pointer
1022//   o sp: stack pointer
1023//   o ra: return address
1024//
1025// The function builds an interpreter frame.  See InterpreterFrameConstants in
1026// frames.h for its layout.
1027void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
1028  ProfileEntryHookStub::MaybeCallEntryHook(masm);
1029
1030  // Open a frame scope to indicate that there is a frame on the stack.  The
1031  // MANUAL indicates that the scope shouldn't actually generate code to set up
1032  // the frame (that is done below).
1033  FrameScope frame_scope(masm, StackFrame::MANUAL);
1034  __ PushStandardFrame(a1);
1035
1036  // Get the bytecode array from the function object (or from the DebugInfo if
1037  // it is present) and load it into kInterpreterBytecodeArrayRegister.
1038  __ lw(a0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1039  Label load_debug_bytecode_array, bytecode_array_loaded;
1040  Register debug_info = kInterpreterBytecodeArrayRegister;
1041  DCHECK(!debug_info.is(a0));
1042  __ lw(debug_info, FieldMemOperand(a0, SharedFunctionInfo::kDebugInfoOffset));
1043  __ JumpIfNotSmi(debug_info, &load_debug_bytecode_array);
1044  __ lw(kInterpreterBytecodeArrayRegister,
1045        FieldMemOperand(a0, SharedFunctionInfo::kFunctionDataOffset));
1046  __ bind(&bytecode_array_loaded);
1047
1048  // Check whether we should continue to use the interpreter.
1049  Label switch_to_different_code_kind;
1050  __ lw(a0, FieldMemOperand(a0, SharedFunctionInfo::kCodeOffset));
1051  __ Branch(&switch_to_different_code_kind, ne, a0,
1052            Operand(masm->CodeObject()));  // Self-reference to this code.
1053
1054  // Increment invocation count for the function.
1055  __ lw(a0, FieldMemOperand(a1, JSFunction::kFeedbackVectorOffset));
1056  __ lw(a0, FieldMemOperand(a0, Cell::kValueOffset));
1057  __ lw(t0, FieldMemOperand(
1058                a0, FeedbackVector::kInvocationCountIndex * kPointerSize +
1059                        FeedbackVector::kHeaderSize));
1060  __ Addu(t0, t0, Operand(Smi::FromInt(1)));
1061  __ sw(t0, FieldMemOperand(
1062                a0, FeedbackVector::kInvocationCountIndex * kPointerSize +
1063                        FeedbackVector::kHeaderSize));
1064
1065  // Check function data field is actually a BytecodeArray object.
1066  if (FLAG_debug_code) {
1067    __ SmiTst(kInterpreterBytecodeArrayRegister, t0);
1068    __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry, t0,
1069              Operand(zero_reg));
1070    __ GetObjectType(kInterpreterBytecodeArrayRegister, t0, t0);
1071    __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry, t0,
1072              Operand(BYTECODE_ARRAY_TYPE));
1073  }
1074
1075  // Reset code age.
1076  DCHECK_EQ(0, BytecodeArray::kNoAgeBytecodeAge);
1077  __ sb(zero_reg, FieldMemOperand(kInterpreterBytecodeArrayRegister,
1078                                  BytecodeArray::kBytecodeAgeOffset));
1079
1080  // Load initial bytecode offset.
1081  __ li(kInterpreterBytecodeOffsetRegister,
1082        Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
1083
1084  // Push new.target, bytecode array and Smi tagged bytecode array offset.
1085  __ SmiTag(t0, kInterpreterBytecodeOffsetRegister);
1086  __ Push(a3, kInterpreterBytecodeArrayRegister, t0);
1087
1088  // Allocate the local and temporary register file on the stack.
1089  {
1090    // Load frame size from the BytecodeArray object.
1091    __ lw(t0, FieldMemOperand(kInterpreterBytecodeArrayRegister,
1092                              BytecodeArray::kFrameSizeOffset));
1093
1094    // Do a stack check to ensure we don't go over the limit.
1095    Label ok;
1096    __ Subu(t1, sp, Operand(t0));
1097    __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
1098    __ Branch(&ok, hs, t1, Operand(a2));
1099    __ CallRuntime(Runtime::kThrowStackOverflow);
1100    __ bind(&ok);
1101
1102    // If ok, push undefined as the initial value for all register file entries.
1103    Label loop_header;
1104    Label loop_check;
1105    __ LoadRoot(t1, Heap::kUndefinedValueRootIndex);
1106    __ Branch(&loop_check);
1107    __ bind(&loop_header);
1108    // TODO(rmcilroy): Consider doing more than one push per loop iteration.
1109    __ push(t1);
1110    // Continue loop if not done.
1111    __ bind(&loop_check);
1112    __ Subu(t0, t0, Operand(kPointerSize));
1113    __ Branch(&loop_header, ge, t0, Operand(zero_reg));
1114  }
1115
1116  // Load accumulator and dispatch table into registers.
1117  __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
1118  __ li(kInterpreterDispatchTableRegister,
1119        Operand(ExternalReference::interpreter_dispatch_table_address(
1120            masm->isolate())));
1121
1122  // Dispatch to the first bytecode handler for the function.
1123  __ Addu(a0, kInterpreterBytecodeArrayRegister,
1124          kInterpreterBytecodeOffsetRegister);
1125  __ lbu(a0, MemOperand(a0));
1126  __ Lsa(at, kInterpreterDispatchTableRegister, a0, kPointerSizeLog2);
1127  __ lw(at, MemOperand(at));
1128  __ Call(at);
1129  masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
1130
1131  // The return value is in v0.
1132  LeaveInterpreterFrame(masm, t0);
1133  __ Jump(ra);
1134
1135  // Load debug copy of the bytecode array.
1136  __ bind(&load_debug_bytecode_array);
1137  __ lw(kInterpreterBytecodeArrayRegister,
1138        FieldMemOperand(debug_info, DebugInfo::kDebugBytecodeArrayIndex));
1139  __ Branch(&bytecode_array_loaded);
1140
1141  // If the shared code is no longer this entry trampoline, then the underlying
1142  // function has been switched to a different kind of code and we heal the
1143  // closure by switching the code entry field over to the new code as well.
1144  __ bind(&switch_to_different_code_kind);
1145  __ LeaveFrame(StackFrame::JAVA_SCRIPT);
1146  __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1147  __ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kCodeOffset));
1148  __ Addu(t0, t0, Operand(Code::kHeaderSize - kHeapObjectTag));
1149  __ sw(t0, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
1150  __ RecordWriteCodeEntryField(a1, t0, t1);
1151  __ Jump(t0);
1152}
1153
1154static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
1155                                        Register scratch1, Register scratch2,
1156                                        Label* stack_overflow) {
1157  // Check the stack for overflow. We are not trying to catch
1158  // interruptions (e.g. debug break and preemption) here, so the "real stack
1159  // limit" is checked.
1160  __ LoadRoot(scratch1, Heap::kRealStackLimitRootIndex);
1161  // Make scratch1 the space we have left. The stack might already be overflowed
1162  // here which will cause scratch1 to become negative.
1163  __ subu(scratch1, sp, scratch1);
1164  // Check if the arguments will overflow the stack.
1165  __ sll(scratch2, num_args, kPointerSizeLog2);
1166  // Signed comparison.
1167  __ Branch(stack_overflow, le, scratch1, Operand(scratch2));
1168}
1169
1170static void Generate_InterpreterPushArgs(MacroAssembler* masm,
1171                                         Register num_args, Register index,
1172                                         Register scratch, Register scratch2,
1173                                         Label* stack_overflow) {
1174  Generate_StackOverflowCheck(masm, num_args, scratch, scratch2,
1175                              stack_overflow);
1176
1177  // Find the address of the last argument.
1178  __ mov(scratch2, num_args);
1179  __ sll(scratch2, scratch2, kPointerSizeLog2);
1180  __ Subu(scratch2, index, Operand(scratch2));
1181
1182  // Push the arguments.
1183  Label loop_header, loop_check;
1184  __ Branch(&loop_check);
1185  __ bind(&loop_header);
1186  __ lw(scratch, MemOperand(index));
1187  __ Addu(index, index, Operand(-kPointerSize));
1188  __ push(scratch);
1189  __ bind(&loop_check);
1190  __ Branch(&loop_header, gt, index, Operand(scratch2));
1191}
1192
1193// static
1194void Builtins::Generate_InterpreterPushArgsAndCallImpl(
1195    MacroAssembler* masm, TailCallMode tail_call_mode,
1196    InterpreterPushArgsMode mode) {
1197  // ----------- S t a t e -------------
1198  //  -- a0 : the number of arguments (not including the receiver)
1199  //  -- a2 : the address of the first argument to be pushed. Subsequent
1200  //          arguments should be consecutive above this, in the same order as
1201  //          they are to be pushed onto the stack.
1202  //  -- a1 : the target to call (can be any Object).
1203  // -----------------------------------
1204  Label stack_overflow;
1205
1206  __ Addu(t0, a0, Operand(1));  // Add one for receiver.
1207
1208  // This function modifies a2, t4 and t1.
1209  Generate_InterpreterPushArgs(masm, t0, a2, t4, t1, &stack_overflow);
1210
1211  // Call the target.
1212  if (mode == InterpreterPushArgsMode::kJSFunction) {
1213    __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny,
1214                                                      tail_call_mode),
1215            RelocInfo::CODE_TARGET);
1216  } else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
1217    __ Jump(masm->isolate()->builtins()->CallWithSpread(),
1218            RelocInfo::CODE_TARGET);
1219  } else {
1220    __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
1221                                              tail_call_mode),
1222            RelocInfo::CODE_TARGET);
1223  }
1224
1225  __ bind(&stack_overflow);
1226  {
1227    __ TailCallRuntime(Runtime::kThrowStackOverflow);
1228    // Unreachable code.
1229    __ break_(0xCC);
1230  }
1231}
1232
1233// static
1234void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
1235    MacroAssembler* masm, InterpreterPushArgsMode mode) {
1236  // ----------- S t a t e -------------
1237  // -- a0 : argument count (not including receiver)
1238  // -- a3 : new target
1239  // -- a1 : constructor to call
1240  // -- a2 : allocation site feedback if available, undefined otherwise.
1241  // -- t4 : address of the first argument
1242  // -----------------------------------
1243  Label stack_overflow;
1244
1245  // Push a slot for the receiver.
1246  __ push(zero_reg);
1247
1248  // This function modified t4, t1 and t0.
1249  Generate_InterpreterPushArgs(masm, a0, t4, t1, t0, &stack_overflow);
1250
1251  __ AssertUndefinedOrAllocationSite(a2, t0);
1252  if (mode == InterpreterPushArgsMode::kJSFunction) {
1253    __ AssertFunction(a1);
1254
1255    // Tail call to the function-specific construct stub (still in the caller
1256    // context at this point).
1257    __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1258    __ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kConstructStubOffset));
1259    __ Addu(at, t0, Operand(Code::kHeaderSize - kHeapObjectTag));
1260    __ Jump(at);
1261  } else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
1262    // Call the constructor with a0, a1, and a3 unmodified.
1263    __ Jump(masm->isolate()->builtins()->ConstructWithSpread(),
1264            RelocInfo::CODE_TARGET);
1265  } else {
1266    DCHECK_EQ(InterpreterPushArgsMode::kOther, mode);
1267    // Call the constructor with a0, a1, and a3 unmodified.
1268    __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1269  }
1270
1271  __ bind(&stack_overflow);
1272  {
1273    __ TailCallRuntime(Runtime::kThrowStackOverflow);
1274    // Unreachable code.
1275    __ break_(0xCC);
1276  }
1277}
1278
1279// static
1280void Builtins::Generate_InterpreterPushArgsAndConstructArray(
1281    MacroAssembler* masm) {
1282  // ----------- S t a t e -------------
1283  //  -- a0 : the number of arguments (not including the receiver)
1284  //  -- a1 : the target to call checked to be Array function.
1285  //  -- a2 : allocation site feedback.
1286  //  -- a3 : the address of the first argument to be pushed. Subsequent
1287  //          arguments should be consecutive above this, in the same order as
1288  //          they are to be pushed onto the stack.
1289  // -----------------------------------
1290  Label stack_overflow;
1291
1292  __ Addu(t0, a0, Operand(1));  // Add one for receiver.
1293
1294  // This function modifies a3, t4, and t1.
1295  Generate_InterpreterPushArgs(masm, t0, a3, t1, t4, &stack_overflow);
1296
1297  // ArrayConstructor stub expects constructor in a3. Set it here.
1298  __ mov(a3, a1);
1299
1300  ArrayConstructorStub stub(masm->isolate());
1301  __ TailCallStub(&stub);
1302
1303  __ bind(&stack_overflow);
1304  {
1305    __ TailCallRuntime(Runtime::kThrowStackOverflow);
1306    // Unreachable code.
1307    __ break_(0xCC);
1308  }
1309}
1310
1311static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
1312  // Set the return address to the correct point in the interpreter entry
1313  // trampoline.
1314  Smi* interpreter_entry_return_pc_offset(
1315      masm->isolate()->heap()->interpreter_entry_return_pc_offset());
1316  DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero);
1317  __ li(t0, Operand(masm->isolate()->builtins()->InterpreterEntryTrampoline()));
1318  __ Addu(ra, t0, Operand(interpreter_entry_return_pc_offset->value() +
1319                          Code::kHeaderSize - kHeapObjectTag));
1320
1321  // Initialize the dispatch table register.
1322  __ li(kInterpreterDispatchTableRegister,
1323        Operand(ExternalReference::interpreter_dispatch_table_address(
1324            masm->isolate())));
1325
1326  // Get the bytecode array pointer from the frame.
1327  __ lw(kInterpreterBytecodeArrayRegister,
1328        MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
1329
1330  if (FLAG_debug_code) {
1331    // Check function data field is actually a BytecodeArray object.
1332    __ SmiTst(kInterpreterBytecodeArrayRegister, at);
1333    __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry, at,
1334              Operand(zero_reg));
1335    __ GetObjectType(kInterpreterBytecodeArrayRegister, a1, a1);
1336    __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry, a1,
1337              Operand(BYTECODE_ARRAY_TYPE));
1338  }
1339
1340  // Get the target bytecode offset from the frame.
1341  __ lw(kInterpreterBytecodeOffsetRegister,
1342        MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
1343  __ SmiUntag(kInterpreterBytecodeOffsetRegister);
1344
1345  // Dispatch to the target bytecode.
1346  __ Addu(a1, kInterpreterBytecodeArrayRegister,
1347          kInterpreterBytecodeOffsetRegister);
1348  __ lbu(a1, MemOperand(a1));
1349  __ Lsa(a1, kInterpreterDispatchTableRegister, a1, kPointerSizeLog2);
1350  __ lw(a1, MemOperand(a1));
1351  __ Jump(a1);
1352}
1353
1354void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) {
1355  // Advance the current bytecode offset stored within the given interpreter
1356  // stack frame. This simulates what all bytecode handlers do upon completion
1357  // of the underlying operation.
1358  __ lw(a1, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
1359  __ lw(a2, MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
1360  __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1361  {
1362    FrameScope scope(masm, StackFrame::INTERNAL);
1363    __ Push(kInterpreterAccumulatorRegister, a1, a2);
1364    __ CallRuntime(Runtime::kInterpreterAdvanceBytecodeOffset);
1365    __ mov(a2, v0);  // Result is the new bytecode offset.
1366    __ Pop(kInterpreterAccumulatorRegister);
1367  }
1368  __ sw(a2, MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
1369
1370  Generate_InterpreterEnterBytecode(masm);
1371}
1372
1373void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
1374  Generate_InterpreterEnterBytecode(masm);
1375}
1376
1377void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
1378  // ----------- S t a t e -------------
1379  //  -- a0 : argument count (preserved for callee)
1380  //  -- a3 : new target (preserved for callee)
1381  //  -- a1 : target function (preserved for callee)
1382  // -----------------------------------
1383  // First lookup code, maybe we don't need to compile!
1384  Label gotta_call_runtime, gotta_call_runtime_no_stack;
1385  Label try_shared;
1386  Label loop_top, loop_bottom;
1387
1388  Register argument_count = a0;
1389  Register closure = a1;
1390  Register new_target = a3;
1391  Register map = a0;
1392  Register index = a2;
1393
1394  // Do we have a valid feedback vector?
1395  __ lw(index, FieldMemOperand(closure, JSFunction::kFeedbackVectorOffset));
1396  __ lw(index, FieldMemOperand(index, Cell::kValueOffset));
1397  __ JumpIfRoot(index, Heap::kUndefinedValueRootIndex,
1398                &gotta_call_runtime_no_stack);
1399
1400  __ push(argument_count);
1401  __ push(new_target);
1402  __ push(closure);
1403
1404  __ lw(map, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
1405  __ lw(map, FieldMemOperand(map, SharedFunctionInfo::kOptimizedCodeMapOffset));
1406  __ lw(index, FieldMemOperand(map, FixedArray::kLengthOffset));
1407  __ Branch(&try_shared, lt, index, Operand(Smi::FromInt(2)));
1408
1409  // a3  : native context
1410  // a2  : length / index
1411  // a0  : optimized code map
1412  // stack[0] : new target
1413  // stack[4] : closure
1414  Register native_context = a3;
1415  __ lw(native_context, NativeContextMemOperand());
1416
1417  __ bind(&loop_top);
1418  Register temp = a1;
1419  Register array_pointer = t1;
1420
1421  // Does the native context match?
1422  __ sll(at, index, kPointerSizeLog2 - kSmiTagSize);
1423  __ Addu(array_pointer, map, Operand(at));
1424  __ lw(temp, FieldMemOperand(array_pointer,
1425                              SharedFunctionInfo::kOffsetToPreviousContext));
1426  __ lw(temp, FieldMemOperand(temp, WeakCell::kValueOffset));
1427  __ Branch(&loop_bottom, ne, temp, Operand(native_context));
1428
1429  // Code available?
1430  Register entry = t0;
1431  __ lw(entry,
1432        FieldMemOperand(array_pointer,
1433                        SharedFunctionInfo::kOffsetToPreviousCachedCode));
1434  __ lw(entry, FieldMemOperand(entry, WeakCell::kValueOffset));
1435  __ JumpIfSmi(entry, &try_shared);
1436
1437  // Found code. Get it into the closure and return.
1438  __ pop(closure);
1439  // Store code entry in the closure.
1440  __ Addu(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
1441  __ sw(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
1442  __ RecordWriteCodeEntryField(closure, entry, t1);
1443
1444  // Link the closure into the optimized function list.
1445  // t0 : code entry
1446  // a3 : native context
1447  // a1 : closure
1448  __ lw(t1,
1449        ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
1450  __ sw(t1, FieldMemOperand(closure, JSFunction::kNextFunctionLinkOffset));
1451  __ RecordWriteField(closure, JSFunction::kNextFunctionLinkOffset, t1, a0,
1452                      kRAHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
1453                      OMIT_SMI_CHECK);
1454  const int function_list_offset =
1455      Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST);
1456  __ sw(closure,
1457        ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
1458  // Save closure before the write barrier.
1459  __ mov(t1, closure);
1460  __ RecordWriteContextSlot(native_context, function_list_offset, closure, a0,
1461                            kRAHasNotBeenSaved, kDontSaveFPRegs);
1462  __ mov(closure, t1);
1463  __ pop(new_target);
1464  __ pop(argument_count);
1465  __ Jump(entry);
1466
1467  __ bind(&loop_bottom);
1468  __ Subu(index, index,
1469          Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
1470  __ Branch(&loop_top, gt, index, Operand(Smi::FromInt(1)));
1471
1472  // We found no code.
1473  __ bind(&try_shared);
1474  __ pop(closure);
1475  __ pop(new_target);
1476  __ pop(argument_count);
1477  __ lw(entry, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
1478  // Is the shared function marked for tier up?
1479  __ lbu(t1, FieldMemOperand(entry,
1480                             SharedFunctionInfo::kMarkedForTierUpByteOffset));
1481  __ And(t1, t1,
1482         Operand(1 << SharedFunctionInfo::kMarkedForTierUpBitWithinByte));
1483  __ Branch(&gotta_call_runtime_no_stack, ne, t1, Operand(zero_reg));
1484
1485  // If SFI points to anything other than CompileLazy, install that.
1486  __ lw(entry, FieldMemOperand(entry, SharedFunctionInfo::kCodeOffset));
1487  __ Move(t1, masm->CodeObject());
1488  __ Branch(&gotta_call_runtime_no_stack, eq, entry, Operand(t1));
1489
1490  // Install the SFI's code entry.
1491  __ Addu(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
1492  __ sw(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
1493  __ RecordWriteCodeEntryField(closure, entry, t1);
1494  __ Jump(entry);
1495
1496  __ bind(&gotta_call_runtime);
1497  __ pop(closure);
1498  __ pop(new_target);
1499  __ pop(argument_count);
1500  __ bind(&gotta_call_runtime_no_stack);
1501  GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
1502}
1503
1504void Builtins::Generate_CompileBaseline(MacroAssembler* masm) {
1505  GenerateTailCallToReturnedCode(masm, Runtime::kCompileBaseline);
1506}
1507
1508void Builtins::Generate_CompileOptimized(MacroAssembler* masm) {
1509  GenerateTailCallToReturnedCode(masm,
1510                                 Runtime::kCompileOptimized_NotConcurrent);
1511}
1512
1513void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
1514  GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
1515}
1516
1517void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
1518  // ----------- S t a t e -------------
1519  //  -- a0 : argument count (preserved for callee)
1520  //  -- a1 : new target (preserved for callee)
1521  //  -- a3 : target function (preserved for callee)
1522  // -----------------------------------
1523  Label failed;
1524  {
1525    FrameScope scope(masm, StackFrame::INTERNAL);
1526    // Preserve argument count for later compare.
1527    __ Move(t4, a0);
1528    // Push a copy of the target function and the new target.
1529    // Push function as parameter to the runtime call.
1530    __ SmiTag(a0);
1531    __ Push(a0, a1, a3, a1);
1532
1533    // Copy arguments from caller (stdlib, foreign, heap).
1534    Label args_done;
1535    for (int j = 0; j < 4; ++j) {
1536      Label over;
1537      if (j < 3) {
1538        __ Branch(&over, ne, t4, Operand(j));
1539      }
1540      for (int i = j - 1; i >= 0; --i) {
1541        __ lw(t4, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
1542                                     i * kPointerSize));
1543        __ push(t4);
1544      }
1545      for (int i = 0; i < 3 - j; ++i) {
1546        __ PushRoot(Heap::kUndefinedValueRootIndex);
1547      }
1548      if (j < 3) {
1549        __ jmp(&args_done);
1550        __ bind(&over);
1551      }
1552    }
1553    __ bind(&args_done);
1554
1555    // Call runtime, on success unwind frame, and parent frame.
1556    __ CallRuntime(Runtime::kInstantiateAsmJs, 4);
1557    // A smi 0 is returned on failure, an object on success.
1558    __ JumpIfSmi(v0, &failed);
1559
1560    __ Drop(2);
1561    __ pop(t4);
1562    __ SmiUntag(t4);
1563    scope.GenerateLeaveFrame();
1564
1565    __ Addu(t4, t4, Operand(1));
1566    __ Lsa(sp, sp, t4, kPointerSizeLog2);
1567    __ Ret();
1568
1569    __ bind(&failed);
1570    // Restore target function and new target.
1571    __ Pop(a0, a1, a3);
1572    __ SmiUntag(a0);
1573  }
1574  // On failure, tail call back to regular js.
1575  GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
1576}
1577
1578static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
1579  // For now, we are relying on the fact that make_code_young doesn't do any
1580  // garbage collection which allows us to save/restore the registers without
1581  // worrying about which of them contain pointers. We also don't build an
1582  // internal frame to make the code faster, since we shouldn't have to do stack
1583  // crawls in MakeCodeYoung. This seems a bit fragile.
1584
1585  // Set a0 to point to the head of the PlatformCodeAge sequence.
1586  __ Subu(a0, a0, Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize));
1587
1588  // The following registers must be saved and restored when calling through to
1589  // the runtime:
1590  //   a0 - contains return address (beginning of patch sequence)
1591  //   a1 - isolate
1592  //   a3 - new target
1593  RegList saved_regs =
1594      (a0.bit() | a1.bit() | a3.bit() | ra.bit() | fp.bit()) & ~sp.bit();
1595  FrameScope scope(masm, StackFrame::MANUAL);
1596  __ MultiPush(saved_regs);
1597  __ PrepareCallCFunction(2, 0, a2);
1598  __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate())));
1599  __ CallCFunction(
1600      ExternalReference::get_make_code_young_function(masm->isolate()), 2);
1601  __ MultiPop(saved_regs);
1602  __ Jump(a0);
1603}
1604
1605#define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C)                              \
1606  void Builtins::Generate_Make##C##CodeYoungAgain(MacroAssembler* masm) { \
1607    GenerateMakeCodeYoungAgainCommon(masm);                               \
1608  }
1609CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR)
1610#undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
1611
1612void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
1613  // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact
1614  // that make_code_young doesn't do any garbage collection which allows us to
1615  // save/restore the registers without worrying about which of them contain
1616  // pointers.
1617
1618  // Set a0 to point to the head of the PlatformCodeAge sequence.
1619  __ Subu(a0, a0, Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize));
1620
1621  // The following registers must be saved and restored when calling through to
1622  // the runtime:
1623  //   a0 - contains return address (beginning of patch sequence)
1624  //   a1 - isolate
1625  //   a3 - new target
1626  RegList saved_regs =
1627      (a0.bit() | a1.bit() | a3.bit() | ra.bit() | fp.bit()) & ~sp.bit();
1628  FrameScope scope(masm, StackFrame::MANUAL);
1629  __ MultiPush(saved_regs);
1630  __ PrepareCallCFunction(2, 0, a2);
1631  __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate())));
1632  __ CallCFunction(
1633      ExternalReference::get_mark_code_as_executed_function(masm->isolate()),
1634      2);
1635  __ MultiPop(saved_regs);
1636
1637  // Perform prologue operations usually performed by the young code stub.
1638  __ PushStandardFrame(a1);
1639
1640  // Jump to point after the code-age stub.
1641  __ Addu(a0, a0, Operand(kNoCodeAgeSequenceLength));
1642  __ Jump(a0);
1643}
1644
1645void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
1646  GenerateMakeCodeYoungAgainCommon(masm);
1647}
1648
1649void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
1650  Generate_MarkCodeAsExecutedOnce(masm);
1651}
1652
1653static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
1654                                             SaveFPRegsMode save_doubles) {
1655  {
1656    FrameScope scope(masm, StackFrame::INTERNAL);
1657
1658    // Preserve registers across notification, this is important for compiled
1659    // stubs that tail call the runtime on deopts passing their parameters in
1660    // registers.
1661    __ MultiPush(kJSCallerSaved | kCalleeSaved);
1662    // Pass the function and deoptimization type to the runtime system.
1663    __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles);
1664    __ MultiPop(kJSCallerSaved | kCalleeSaved);
1665  }
1666
1667  __ Addu(sp, sp, Operand(kPointerSize));  // Ignore state
1668  __ Jump(ra);                             // Jump to miss handler
1669}
1670
1671void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
1672  Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs);
1673}
1674
1675void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
1676  Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
1677}
1678
1679static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
1680                                             Deoptimizer::BailoutType type) {
1681  {
1682    FrameScope scope(masm, StackFrame::INTERNAL);
1683    // Pass the function and deoptimization type to the runtime system.
1684    __ li(a0, Operand(Smi::FromInt(static_cast<int>(type))));
1685    __ push(a0);
1686    __ CallRuntime(Runtime::kNotifyDeoptimized);
1687  }
1688
1689  // Get the full codegen state from the stack and untag it -> t2.
1690  __ lw(t2, MemOperand(sp, 0 * kPointerSize));
1691  __ SmiUntag(t2);
1692  // Switch on the state.
1693  Label with_tos_register, unknown_state;
1694  __ Branch(&with_tos_register, ne, t2,
1695            Operand(static_cast<int>(Deoptimizer::BailoutState::NO_REGISTERS)));
1696  __ Ret(USE_DELAY_SLOT);
1697  // Safe to fill delay slot Addu will emit one instruction.
1698  __ Addu(sp, sp, Operand(1 * kPointerSize));  // Remove state.
1699
1700  __ bind(&with_tos_register);
1701  DCHECK_EQ(kInterpreterAccumulatorRegister.code(), v0.code());
1702  __ lw(v0, MemOperand(sp, 1 * kPointerSize));
1703  __ Branch(&unknown_state, ne, t2,
1704            Operand(static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)));
1705
1706  __ Ret(USE_DELAY_SLOT);
1707  // Safe to fill delay slot Addu will emit one instruction.
1708  __ Addu(sp, sp, Operand(2 * kPointerSize));  // Remove state.
1709
1710  __ bind(&unknown_state);
1711  __ stop("no cases left");
1712}
1713
1714void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
1715  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
1716}
1717
1718void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) {
1719  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
1720}
1721
1722void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
1723  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
1724}
1725
1726// Clobbers {t2, t3, t4, t5}.
1727static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver,
1728                                    Register function_template_info,
1729                                    Label* receiver_check_failed) {
1730  Register signature = t2;
1731  Register map = t3;
1732  Register constructor = t4;
1733  Register scratch = t5;
1734
1735  // If there is no signature, return the holder.
1736  __ lw(signature, FieldMemOperand(function_template_info,
1737                                   FunctionTemplateInfo::kSignatureOffset));
1738  Label receiver_check_passed;
1739  __ JumpIfRoot(signature, Heap::kUndefinedValueRootIndex,
1740                &receiver_check_passed);
1741
1742  // Walk the prototype chain.
1743  __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
1744  Label prototype_loop_start;
1745  __ bind(&prototype_loop_start);
1746
1747  // Get the constructor, if any.
1748  __ GetMapConstructor(constructor, map, scratch, scratch);
1749  Label next_prototype;
1750  __ Branch(&next_prototype, ne, scratch, Operand(JS_FUNCTION_TYPE));
1751  Register type = constructor;
1752  __ lw(type,
1753        FieldMemOperand(constructor, JSFunction::kSharedFunctionInfoOffset));
1754  __ lw(type, FieldMemOperand(type, SharedFunctionInfo::kFunctionDataOffset));
1755
1756  // Loop through the chain of inheriting function templates.
1757  Label function_template_loop;
1758  __ bind(&function_template_loop);
1759
1760  // If the signatures match, we have a compatible receiver.
1761  __ Branch(&receiver_check_passed, eq, signature, Operand(type),
1762            USE_DELAY_SLOT);
1763
1764  // If the current type is not a FunctionTemplateInfo, load the next prototype
1765  // in the chain.
1766  __ JumpIfSmi(type, &next_prototype);
1767  __ GetObjectType(type, scratch, scratch);
1768  __ Branch(&next_prototype, ne, scratch, Operand(FUNCTION_TEMPLATE_INFO_TYPE));
1769
1770  // Otherwise load the parent function template and iterate.
1771  __ lw(type,
1772        FieldMemOperand(type, FunctionTemplateInfo::kParentTemplateOffset));
1773  __ Branch(&function_template_loop);
1774
1775  // Load the next prototype and iterate.
1776  __ bind(&next_prototype);
1777  __ lw(scratch, FieldMemOperand(map, Map::kBitField3Offset));
1778  __ DecodeField<Map::HasHiddenPrototype>(scratch);
1779  __ Branch(receiver_check_failed, eq, scratch, Operand(zero_reg));
1780  __ lw(receiver, FieldMemOperand(map, Map::kPrototypeOffset));
1781  __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
1782
1783  __ Branch(&prototype_loop_start);
1784
1785  __ bind(&receiver_check_passed);
1786}
1787
1788void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) {
1789  // ----------- S t a t e -------------
1790  //  -- a0                 : number of arguments excluding receiver
1791  //  -- a1                 : callee
1792  //  -- ra                 : return address
1793  //  -- sp[0]              : last argument
1794  //  -- ...
1795  //  -- sp[4 * (argc - 1)] : first argument
1796  //  -- sp[4 * argc]       : receiver
1797  // -----------------------------------
1798
1799  // Load the FunctionTemplateInfo.
1800  __ lw(t1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1801  __ lw(t1, FieldMemOperand(t1, SharedFunctionInfo::kFunctionDataOffset));
1802
1803  // Do the compatible receiver check.
1804  Label receiver_check_failed;
1805  __ Lsa(t8, sp, a0, kPointerSizeLog2);
1806  __ lw(t0, MemOperand(t8));
1807  CompatibleReceiverCheck(masm, t0, t1, &receiver_check_failed);
1808
1809  // Get the callback offset from the FunctionTemplateInfo, and jump to the
1810  // beginning of the code.
1811  __ lw(t2, FieldMemOperand(t1, FunctionTemplateInfo::kCallCodeOffset));
1812  __ lw(t2, FieldMemOperand(t2, CallHandlerInfo::kFastHandlerOffset));
1813  __ Addu(t2, t2, Operand(Code::kHeaderSize - kHeapObjectTag));
1814  __ Jump(t2);
1815
1816  // Compatible receiver check failed: throw an Illegal Invocation exception.
1817  __ bind(&receiver_check_failed);
1818  // Drop the arguments (including the receiver);
1819  __ Addu(t8, t8, Operand(kPointerSize));
1820  __ addu(sp, t8, zero_reg);
1821  __ TailCallRuntime(Runtime::kThrowIllegalInvocation);
1822}
1823
1824static void Generate_OnStackReplacementHelper(MacroAssembler* masm,
1825                                              bool has_handler_frame) {
1826  // Lookup the function in the JavaScript frame.
1827  if (has_handler_frame) {
1828    __ lw(a0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
1829    __ lw(a0, MemOperand(a0, JavaScriptFrameConstants::kFunctionOffset));
1830  } else {
1831    __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1832  }
1833
1834  {
1835    FrameScope scope(masm, StackFrame::INTERNAL);
1836    // Pass function as argument.
1837    __ push(a0);
1838    __ CallRuntime(Runtime::kCompileForOnStackReplacement);
1839  }
1840
1841  // If the code object is null, just return to the caller.
1842  __ Ret(eq, v0, Operand(Smi::kZero));
1843
1844  // Drop any potential handler frame that is be sitting on top of the actual
1845  // JavaScript frame. This is the case then OSR is triggered from bytecode.
1846  if (has_handler_frame) {
1847    __ LeaveFrame(StackFrame::STUB);
1848  }
1849
1850  // Load deoptimization data from the code object.
1851  // <deopt_data> = <code>[#deoptimization_data_offset]
1852  __ lw(a1, MemOperand(v0, Code::kDeoptimizationDataOffset - kHeapObjectTag));
1853
1854  // Load the OSR entrypoint offset from the deoptimization data.
1855  // <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset]
1856  __ lw(a1, MemOperand(a1, FixedArray::OffsetOfElementAt(
1857                               DeoptimizationInputData::kOsrPcOffsetIndex) -
1858                               kHeapObjectTag));
1859  __ SmiUntag(a1);
1860
1861  // Compute the target address = code_obj + header_size + osr_offset
1862  // <entry_addr> = <code_obj> + #header_size + <osr_offset>
1863  __ addu(v0, v0, a1);
1864  __ addiu(ra, v0, Code::kHeaderSize - kHeapObjectTag);
1865
1866  // And "return" to the OSR entry point of the function.
1867  __ Ret();
1868}
1869
1870void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
1871  Generate_OnStackReplacementHelper(masm, false);
1872}
1873
1874void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
1875  Generate_OnStackReplacementHelper(masm, true);
1876}
1877
1878// static
1879void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
1880  // ----------- S t a t e -------------
1881  //  -- a0    : argc
1882  //  -- sp[0] : argArray
1883  //  -- sp[4] : thisArg
1884  //  -- sp[8] : receiver
1885  // -----------------------------------
1886
1887  // 1. Load receiver into a1, argArray into a0 (if present), remove all
1888  // arguments from the stack (including the receiver), and push thisArg (if
1889  // present) instead.
1890  {
1891    Label no_arg;
1892    Register scratch = t0;
1893    __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
1894    __ mov(a3, a2);
1895    // Lsa() cannot be used hare as scratch value used later.
1896    __ sll(scratch, a0, kPointerSizeLog2);
1897    __ Addu(a0, sp, Operand(scratch));
1898    __ lw(a1, MemOperand(a0));  // receiver
1899    __ Subu(a0, a0, Operand(kPointerSize));
1900    __ Branch(&no_arg, lt, a0, Operand(sp));
1901    __ lw(a2, MemOperand(a0));  // thisArg
1902    __ Subu(a0, a0, Operand(kPointerSize));
1903    __ Branch(&no_arg, lt, a0, Operand(sp));
1904    __ lw(a3, MemOperand(a0));  // argArray
1905    __ bind(&no_arg);
1906    __ Addu(sp, sp, Operand(scratch));
1907    __ sw(a2, MemOperand(sp));
1908    __ mov(a0, a3);
1909  }
1910
1911  // ----------- S t a t e -------------
1912  //  -- a0    : argArray
1913  //  -- a1    : receiver
1914  //  -- sp[0] : thisArg
1915  // -----------------------------------
1916
1917  // 2. Make sure the receiver is actually callable.
1918  Label receiver_not_callable;
1919  __ JumpIfSmi(a1, &receiver_not_callable);
1920  __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset));
1921  __ lbu(t0, FieldMemOperand(t0, Map::kBitFieldOffset));
1922  __ And(t0, t0, Operand(1 << Map::kIsCallable));
1923  __ Branch(&receiver_not_callable, eq, t0, Operand(zero_reg));
1924
1925  // 3. Tail call with no arguments if argArray is null or undefined.
1926  Label no_arguments;
1927  __ JumpIfRoot(a0, Heap::kNullValueRootIndex, &no_arguments);
1928  __ JumpIfRoot(a0, Heap::kUndefinedValueRootIndex, &no_arguments);
1929
1930  // 4a. Apply the receiver to the given argArray (passing undefined for
1931  // new.target).
1932  __ LoadRoot(a3, Heap::kUndefinedValueRootIndex);
1933  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1934
1935  // 4b. The argArray is either null or undefined, so we tail call without any
1936  // arguments to the receiver.
1937  __ bind(&no_arguments);
1938  {
1939    __ mov(a0, zero_reg);
1940    __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1941  }
1942
1943  // 4c. The receiver is not callable, throw an appropriate TypeError.
1944  __ bind(&receiver_not_callable);
1945  {
1946    __ sw(a1, MemOperand(sp));
1947    __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
1948  }
1949}
1950
1951// static
1952void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) {
1953  // 1. Make sure we have at least one argument.
1954  // a0: actual number of arguments
1955  {
1956    Label done;
1957    __ Branch(&done, ne, a0, Operand(zero_reg));
1958    __ PushRoot(Heap::kUndefinedValueRootIndex);
1959    __ Addu(a0, a0, Operand(1));
1960    __ bind(&done);
1961  }
1962
1963  // 2. Get the function to call (passed as receiver) from the stack.
1964  // a0: actual number of arguments
1965  __ Lsa(at, sp, a0, kPointerSizeLog2);
1966  __ lw(a1, MemOperand(at));
1967
1968  // 3. Shift arguments and return address one slot down on the stack
1969  //    (overwriting the original receiver).  Adjust argument count to make
1970  //    the original first argument the new receiver.
1971  // a0: actual number of arguments
1972  // a1: function
1973  {
1974    Label loop;
1975    // Calculate the copy start address (destination). Copy end address is sp.
1976    __ Lsa(a2, sp, a0, kPointerSizeLog2);
1977
1978    __ bind(&loop);
1979    __ lw(at, MemOperand(a2, -kPointerSize));
1980    __ sw(at, MemOperand(a2));
1981    __ Subu(a2, a2, Operand(kPointerSize));
1982    __ Branch(&loop, ne, a2, Operand(sp));
1983    // Adjust the actual number of arguments and remove the top element
1984    // (which is a copy of the last argument).
1985    __ Subu(a0, a0, Operand(1));
1986    __ Pop();
1987  }
1988
1989  // 4. Call the callable.
1990  __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1991}
1992
1993void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1994  // ----------- S t a t e -------------
1995  //  -- a0     : argc
1996  //  -- sp[0]  : argumentsList
1997  //  -- sp[4]  : thisArgument
1998  //  -- sp[8]  : target
1999  //  -- sp[12] : receiver
2000  // -----------------------------------
2001
2002  // 1. Load target into a1 (if present), argumentsList into a0 (if present),
2003  // remove all arguments from the stack (including the receiver), and push
2004  // thisArgument (if present) instead.
2005  {
2006    Label no_arg;
2007    Register scratch = t0;
2008    __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
2009    __ mov(a2, a1);
2010    __ mov(a3, a1);
2011    __ sll(scratch, a0, kPointerSizeLog2);
2012    __ mov(a0, scratch);
2013    __ Subu(a0, a0, Operand(kPointerSize));
2014    __ Branch(&no_arg, lt, a0, Operand(zero_reg));
2015    __ Addu(a0, sp, Operand(a0));
2016    __ lw(a1, MemOperand(a0));  // target
2017    __ Subu(a0, a0, Operand(kPointerSize));
2018    __ Branch(&no_arg, lt, a0, Operand(sp));
2019    __ lw(a2, MemOperand(a0));  // thisArgument
2020    __ Subu(a0, a0, Operand(kPointerSize));
2021    __ Branch(&no_arg, lt, a0, Operand(sp));
2022    __ lw(a3, MemOperand(a0));  // argumentsList
2023    __ bind(&no_arg);
2024    __ Addu(sp, sp, Operand(scratch));
2025    __ sw(a2, MemOperand(sp));
2026    __ mov(a0, a3);
2027  }
2028
2029  // ----------- S t a t e -------------
2030  //  -- a0    : argumentsList
2031  //  -- a1    : target
2032  //  -- sp[0] : thisArgument
2033  // -----------------------------------
2034
2035  // 2. Make sure the target is actually callable.
2036  Label target_not_callable;
2037  __ JumpIfSmi(a1, &target_not_callable);
2038  __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset));
2039  __ lbu(t0, FieldMemOperand(t0, Map::kBitFieldOffset));
2040  __ And(t0, t0, Operand(1 << Map::kIsCallable));
2041  __ Branch(&target_not_callable, eq, t0, Operand(zero_reg));
2042
2043  // 3a. Apply the target to the given argumentsList (passing undefined for
2044  // new.target).
2045  __ LoadRoot(a3, Heap::kUndefinedValueRootIndex);
2046  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
2047
2048  // 3b. The target is not callable, throw an appropriate TypeError.
2049  __ bind(&target_not_callable);
2050  {
2051    __ sw(a1, MemOperand(sp));
2052    __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
2053  }
2054}
2055
2056void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
2057  // ----------- S t a t e -------------
2058  //  -- a0     : argc
2059  //  -- sp[0]  : new.target (optional)
2060  //  -- sp[4]  : argumentsList
2061  //  -- sp[8]  : target
2062  //  -- sp[12] : receiver
2063  // -----------------------------------
2064
2065  // 1. Load target into a1 (if present), argumentsList into a0 (if present),
2066  // new.target into a3 (if present, otherwise use target), remove all
2067  // arguments from the stack (including the receiver), and push thisArgument
2068  // (if present) instead.
2069  {
2070    Label no_arg;
2071    Register scratch = t0;
2072    __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
2073    __ mov(a2, a1);
2074    // Lsa() cannot be used hare as scratch value used later.
2075    __ sll(scratch, a0, kPointerSizeLog2);
2076    __ Addu(a0, sp, Operand(scratch));
2077    __ sw(a2, MemOperand(a0));  // receiver
2078    __ Subu(a0, a0, Operand(kPointerSize));
2079    __ Branch(&no_arg, lt, a0, Operand(sp));
2080    __ lw(a1, MemOperand(a0));  // target
2081    __ mov(a3, a1);             // new.target defaults to target
2082    __ Subu(a0, a0, Operand(kPointerSize));
2083    __ Branch(&no_arg, lt, a0, Operand(sp));
2084    __ lw(a2, MemOperand(a0));  // argumentsList
2085    __ Subu(a0, a0, Operand(kPointerSize));
2086    __ Branch(&no_arg, lt, a0, Operand(sp));
2087    __ lw(a3, MemOperand(a0));  // new.target
2088    __ bind(&no_arg);
2089    __ Addu(sp, sp, Operand(scratch));
2090    __ mov(a0, a2);
2091  }
2092
2093  // ----------- S t a t e -------------
2094  //  -- a0    : argumentsList
2095  //  -- a3    : new.target
2096  //  -- a1    : target
2097  //  -- sp[0] : receiver (undefined)
2098  // -----------------------------------
2099
2100  // 2. Make sure the target is actually a constructor.
2101  Label target_not_constructor;
2102  __ JumpIfSmi(a1, &target_not_constructor);
2103  __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset));
2104  __ lbu(t0, FieldMemOperand(t0, Map::kBitFieldOffset));
2105  __ And(t0, t0, Operand(1 << Map::kIsConstructor));
2106  __ Branch(&target_not_constructor, eq, t0, Operand(zero_reg));
2107
2108  // 3. Make sure the target is actually a constructor.
2109  Label new_target_not_constructor;
2110  __ JumpIfSmi(a3, &new_target_not_constructor);
2111  __ lw(t0, FieldMemOperand(a3, HeapObject::kMapOffset));
2112  __ lbu(t0, FieldMemOperand(t0, Map::kBitFieldOffset));
2113  __ And(t0, t0, Operand(1 << Map::kIsConstructor));
2114  __ Branch(&new_target_not_constructor, eq, t0, Operand(zero_reg));
2115
2116  // 4a. Construct the target with the given new.target and argumentsList.
2117  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
2118
2119  // 4b. The target is not a constructor, throw an appropriate TypeError.
2120  __ bind(&target_not_constructor);
2121  {
2122    __ sw(a1, MemOperand(sp));
2123    __ TailCallRuntime(Runtime::kThrowNotConstructor);
2124  }
2125
2126  // 4c. The new.target is not a constructor, throw an appropriate TypeError.
2127  __ bind(&new_target_not_constructor);
2128  {
2129    __ sw(a3, MemOperand(sp));
2130    __ TailCallRuntime(Runtime::kThrowNotConstructor);
2131  }
2132}
2133
2134static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
2135  __ sll(a0, a0, kSmiTagSize);
2136  __ li(t0, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
2137  __ MultiPush(a0.bit() | a1.bit() | t0.bit() | fp.bit() | ra.bit());
2138  __ Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp +
2139                          kPointerSize));
2140}
2141
2142static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
2143  // ----------- S t a t e -------------
2144  //  -- v0 : result being passed through
2145  // -----------------------------------
2146  // Get the number of arguments passed (as a smi), tear down the frame and
2147  // then tear down the parameters.
2148  __ lw(a1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
2149                             kPointerSize)));
2150  __ mov(sp, fp);
2151  __ MultiPop(fp.bit() | ra.bit());
2152  __ Lsa(sp, sp, a1, kPointerSizeLog2 - kSmiTagSize);
2153  // Adjust for the receiver.
2154  __ Addu(sp, sp, Operand(kPointerSize));
2155}
2156
2157// static
2158void Builtins::Generate_Apply(MacroAssembler* masm) {
2159  // ----------- S t a t e -------------
2160  //  -- a0    : argumentsList
2161  //  -- a1    : target
2162  //  -- a3    : new.target (checked to be constructor or undefined)
2163  //  -- sp[0] : thisArgument
2164  // -----------------------------------
2165
2166  // Create the list of arguments from the array-like argumentsList.
2167  {
2168    Label create_arguments, create_array, create_holey_array, create_runtime,
2169        done_create;
2170    __ JumpIfSmi(a0, &create_runtime);
2171
2172    // Load the map of argumentsList into a2.
2173    __ lw(a2, FieldMemOperand(a0, HeapObject::kMapOffset));
2174
2175    // Load native context into t0.
2176    __ lw(t0, NativeContextMemOperand());
2177
2178    // Check if argumentsList is an (unmodified) arguments object.
2179    __ lw(at, ContextMemOperand(t0, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
2180    __ Branch(&create_arguments, eq, a2, Operand(at));
2181    __ lw(at, ContextMemOperand(t0, Context::STRICT_ARGUMENTS_MAP_INDEX));
2182    __ Branch(&create_arguments, eq, a2, Operand(at));
2183
2184    // Check if argumentsList is a fast JSArray.
2185    __ lbu(v0, FieldMemOperand(a2, Map::kInstanceTypeOffset));
2186    __ Branch(&create_array, eq, v0, Operand(JS_ARRAY_TYPE));
2187
2188    // Ask the runtime to create the list (actually a FixedArray).
2189    __ bind(&create_runtime);
2190    {
2191      FrameScope scope(masm, StackFrame::INTERNAL);
2192      __ Push(a1, a3, a0);
2193      __ CallRuntime(Runtime::kCreateListFromArrayLike);
2194      __ mov(a0, v0);
2195      __ Pop(a1, a3);
2196      __ lw(a2, FieldMemOperand(v0, FixedArray::kLengthOffset));
2197      __ SmiUntag(a2);
2198    }
2199    __ Branch(&done_create);
2200
2201    // Try to create the list from an arguments object.
2202    __ bind(&create_arguments);
2203    __ lw(a2, FieldMemOperand(a0, JSArgumentsObject::kLengthOffset));
2204    __ lw(t0, FieldMemOperand(a0, JSObject::kElementsOffset));
2205    __ lw(at, FieldMemOperand(t0, FixedArray::kLengthOffset));
2206    __ Branch(&create_runtime, ne, a2, Operand(at));
2207    __ SmiUntag(a2);
2208    __ mov(a0, t0);
2209    __ Branch(&done_create);
2210
2211    // For holey JSArrays we need to check that the array prototype chain
2212    // protector is intact and our prototype is the Array.prototype actually.
2213    __ bind(&create_holey_array);
2214    __ lw(a2, FieldMemOperand(a2, Map::kPrototypeOffset));
2215    __ lw(at, ContextMemOperand(t0, Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
2216    __ Branch(&create_runtime, ne, a2, Operand(at));
2217    __ LoadRoot(at, Heap::kArrayProtectorRootIndex);
2218    __ lw(a2, FieldMemOperand(at, PropertyCell::kValueOffset));
2219    __ Branch(&create_runtime, ne, a2,
2220              Operand(Smi::FromInt(Isolate::kProtectorValid)));
2221    __ lw(a2, FieldMemOperand(a0, JSArray::kLengthOffset));
2222    __ lw(a0, FieldMemOperand(a0, JSArray::kElementsOffset));
2223    __ SmiUntag(a2);
2224    __ Branch(&done_create);
2225
2226    // Try to create the list from a JSArray object.
2227    __ bind(&create_array);
2228    __ lbu(t1, FieldMemOperand(a2, Map::kBitField2Offset));
2229    __ DecodeField<Map::ElementsKindBits>(t1);
2230    STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
2231    STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
2232    STATIC_ASSERT(FAST_ELEMENTS == 2);
2233    STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
2234    __ Branch(&create_holey_array, eq, t1, Operand(FAST_HOLEY_SMI_ELEMENTS));
2235    __ Branch(&create_holey_array, eq, t1, Operand(FAST_HOLEY_ELEMENTS));
2236    __ Branch(&create_runtime, hi, t1, Operand(FAST_ELEMENTS));
2237    __ lw(a2, FieldMemOperand(a0, JSArray::kLengthOffset));
2238    __ lw(a0, FieldMemOperand(a0, JSArray::kElementsOffset));
2239    __ SmiUntag(a2);
2240
2241    __ bind(&done_create);
2242  }
2243
2244  // Check for stack overflow.
2245  {
2246    // Check the stack for overflow. We are not trying to catch interruptions
2247    // (i.e. debug break and preemption) here, so check the "real stack limit".
2248    Label done;
2249    __ LoadRoot(t0, Heap::kRealStackLimitRootIndex);
2250    // Make ip the space we have left. The stack might already be overflowed
2251    // here which will cause ip to become negative.
2252    __ Subu(t0, sp, t0);
2253    // Check if the arguments will overflow the stack.
2254    __ sll(at, a2, kPointerSizeLog2);
2255    __ Branch(&done, gt, t0, Operand(at));  // Signed comparison.
2256    __ TailCallRuntime(Runtime::kThrowStackOverflow);
2257    __ bind(&done);
2258  }
2259
2260  // ----------- S t a t e -------------
2261  //  -- a1    : target
2262  //  -- a0    : args (a FixedArray built from argumentsList)
2263  //  -- a2    : len (number of elements to push from args)
2264  //  -- a3    : new.target (checked to be constructor or undefined)
2265  //  -- sp[0] : thisArgument
2266  // -----------------------------------
2267
2268  // Push arguments onto the stack (thisArgument is already on the stack).
2269  {
2270    __ mov(t0, zero_reg);
2271    Label done, push, loop;
2272    __ LoadRoot(t1, Heap::kTheHoleValueRootIndex);
2273    __ bind(&loop);
2274    __ Branch(&done, eq, t0, Operand(a2));
2275    __ Lsa(at, a0, t0, kPointerSizeLog2);
2276    __ lw(at, FieldMemOperand(at, FixedArray::kHeaderSize));
2277    __ Branch(&push, ne, t1, Operand(at));
2278    __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
2279    __ bind(&push);
2280    __ Push(at);
2281    __ Addu(t0, t0, Operand(1));
2282    __ Branch(&loop);
2283    __ bind(&done);
2284    __ Move(a0, t0);
2285  }
2286
2287  // Dispatch to Call or Construct depending on whether new.target is undefined.
2288  {
2289    Label construct;
2290    __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
2291    __ Branch(&construct, ne, a3, Operand(at));
2292    __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2293    __ bind(&construct);
2294    __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2295  }
2296}
2297
2298// static
2299void Builtins::Generate_CallForwardVarargs(MacroAssembler* masm,
2300                                           Handle<Code> code) {
2301  // ----------- S t a t e -------------
2302  //  -- a1    : the target to call (can be any Object)
2303  //  -- a2    : start index (to support rest parameters)
2304  //  -- ra    : return address.
2305  //  -- sp[0] : thisArgument
2306  // -----------------------------------
2307
2308  // Check if we have an arguments adaptor frame below the function frame.
2309  Label arguments_adaptor, arguments_done;
2310  __ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2311  __ lw(a0, MemOperand(a3, CommonFrameConstants::kContextOrFrameTypeOffset));
2312  __ Branch(&arguments_adaptor, eq, a0,
2313            Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
2314  {
2315    __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
2316    __ lw(a0, FieldMemOperand(a0, JSFunction::kSharedFunctionInfoOffset));
2317    __ lw(a0,
2318          FieldMemOperand(a0, SharedFunctionInfo::kFormalParameterCountOffset));
2319    __ mov(a3, fp);
2320  }
2321  __ Branch(&arguments_done);
2322  __ bind(&arguments_adaptor);
2323  {
2324    // Just get the length from the ArgumentsAdaptorFrame.
2325    __ lw(a0, MemOperand(a3, ArgumentsAdaptorFrameConstants::kLengthOffset));
2326  }
2327  __ bind(&arguments_done);
2328
2329  Label stack_empty, stack_done, stack_overflow;
2330  __ SmiUntag(a0);
2331  __ Subu(a0, a0, a2);
2332  __ Branch(&stack_empty, le, a0, Operand(zero_reg));
2333  {
2334    // Check for stack overflow.
2335    Generate_StackOverflowCheck(masm, a0, t0, t1, &stack_overflow);
2336
2337    // Forward the arguments from the caller frame.
2338    {
2339      Label loop;
2340      __ mov(a2, a0);
2341      __ bind(&loop);
2342      {
2343        __ Lsa(at, a3, a2, kPointerSizeLog2);
2344        __ lw(at, MemOperand(at, 1 * kPointerSize));
2345        __ push(at);
2346        __ Subu(a2, a2, Operand(1));
2347        __ Branch(&loop, ne, a2, Operand(zero_reg));
2348      }
2349    }
2350  }
2351  __ Branch(&stack_done);
2352  __ bind(&stack_overflow);
2353  __ TailCallRuntime(Runtime::kThrowStackOverflow);
2354  __ bind(&stack_empty);
2355  {
2356    // We just pass the receiver, which is already on the stack.
2357    __ li(a0, Operand(0));
2358  }
2359  __ bind(&stack_done);
2360
2361  __ Jump(code, RelocInfo::CODE_TARGET);
2362}
2363
2364namespace {
2365
2366// Drops top JavaScript frame and an arguments adaptor frame below it (if
2367// present) preserving all the arguments prepared for current call.
2368// Does nothing if debugger is currently active.
2369// ES6 14.6.3. PrepareForTailCall
2370//
2371// Stack structure for the function g() tail calling f():
2372//
2373// ------- Caller frame: -------
2374// |  ...
2375// |  g()'s arg M
2376// |  ...
2377// |  g()'s arg 1
2378// |  g()'s receiver arg
2379// |  g()'s caller pc
2380// ------- g()'s frame: -------
2381// |  g()'s caller fp      <- fp
2382// |  g()'s context
2383// |  function pointer: g
2384// |  -------------------------
2385// |  ...
2386// |  ...
2387// |  f()'s arg N
2388// |  ...
2389// |  f()'s arg 1
2390// |  f()'s receiver arg   <- sp (f()'s caller pc is not on the stack yet!)
2391// ----------------------
2392//
2393void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
2394                        Register scratch1, Register scratch2,
2395                        Register scratch3) {
2396  DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
2397  Comment cmnt(masm, "[ PrepareForTailCall");
2398
2399  // Prepare for tail call only if ES2015 tail call elimination is enabled.
2400  Label done;
2401  ExternalReference is_tail_call_elimination_enabled =
2402      ExternalReference::is_tail_call_elimination_enabled_address(
2403          masm->isolate());
2404  __ li(at, Operand(is_tail_call_elimination_enabled));
2405  __ lb(scratch1, MemOperand(at));
2406  __ Branch(&done, eq, scratch1, Operand(zero_reg));
2407
2408  // Drop possible interpreter handler/stub frame.
2409  {
2410    Label no_interpreter_frame;
2411    __ lw(scratch3,
2412          MemOperand(fp, CommonFrameConstants::kContextOrFrameTypeOffset));
2413    __ Branch(&no_interpreter_frame, ne, scratch3,
2414              Operand(StackFrame::TypeToMarker(StackFrame::STUB)));
2415    __ lw(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2416    __ bind(&no_interpreter_frame);
2417  }
2418
2419  // Check if next frame is an arguments adaptor frame.
2420  Register caller_args_count_reg = scratch1;
2421  Label no_arguments_adaptor, formal_parameter_count_loaded;
2422  __ lw(scratch2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2423  __ lw(scratch3,
2424        MemOperand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset));
2425  __ Branch(&no_arguments_adaptor, ne, scratch3,
2426            Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
2427
2428  // Drop current frame and load arguments count from arguments adaptor frame.
2429  __ mov(fp, scratch2);
2430  __ lw(caller_args_count_reg,
2431        MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
2432  __ SmiUntag(caller_args_count_reg);
2433  __ Branch(&formal_parameter_count_loaded);
2434
2435  __ bind(&no_arguments_adaptor);
2436  // Load caller's formal parameter count
2437  __ lw(scratch1,
2438        MemOperand(fp, ArgumentsAdaptorFrameConstants::kFunctionOffset));
2439  __ lw(scratch1,
2440        FieldMemOperand(scratch1, JSFunction::kSharedFunctionInfoOffset));
2441  __ lw(caller_args_count_reg,
2442        FieldMemOperand(scratch1,
2443                        SharedFunctionInfo::kFormalParameterCountOffset));
2444  __ SmiUntag(caller_args_count_reg);
2445
2446  __ bind(&formal_parameter_count_loaded);
2447
2448  ParameterCount callee_args_count(args_reg);
2449  __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
2450                        scratch3);
2451  __ bind(&done);
2452}
2453}  // namespace
2454
2455// static
2456void Builtins::Generate_CallFunction(MacroAssembler* masm,
2457                                     ConvertReceiverMode mode,
2458                                     TailCallMode tail_call_mode) {
2459  // ----------- S t a t e -------------
2460  //  -- a0 : the number of arguments (not including the receiver)
2461  //  -- a1 : the function to call (checked to be a JSFunction)
2462  // -----------------------------------
2463  __ AssertFunction(a1);
2464
2465  // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
2466  // Check that the function is not a "classConstructor".
2467  Label class_constructor;
2468  __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
2469  __ lbu(a3, FieldMemOperand(a2, SharedFunctionInfo::kFunctionKindByteOffset));
2470  __ And(at, a3, Operand(SharedFunctionInfo::kClassConstructorBitsWithinByte));
2471  __ Branch(&class_constructor, ne, at, Operand(zero_reg));
2472
2473  // Enter the context of the function; ToObject has to run in the function
2474  // context, and we also need to take the global proxy from the function
2475  // context in case of conversion.
2476  STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset ==
2477                SharedFunctionInfo::kStrictModeByteOffset);
2478  __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
2479  // We need to convert the receiver for non-native sloppy mode functions.
2480  Label done_convert;
2481  __ lbu(a3, FieldMemOperand(a2, SharedFunctionInfo::kNativeByteOffset));
2482  __ And(at, a3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) |
2483                         (1 << SharedFunctionInfo::kStrictModeBitWithinByte)));
2484  __ Branch(&done_convert, ne, at, Operand(zero_reg));
2485  {
2486    // ----------- S t a t e -------------
2487    //  -- a0 : the number of arguments (not including the receiver)
2488    //  -- a1 : the function to call (checked to be a JSFunction)
2489    //  -- a2 : the shared function info.
2490    //  -- cp : the function context.
2491    // -----------------------------------
2492
2493    if (mode == ConvertReceiverMode::kNullOrUndefined) {
2494      // Patch receiver to global proxy.
2495      __ LoadGlobalProxy(a3);
2496    } else {
2497      Label convert_to_object, convert_receiver;
2498      __ Lsa(at, sp, a0, kPointerSizeLog2);
2499      __ lw(a3, MemOperand(at));
2500      __ JumpIfSmi(a3, &convert_to_object);
2501      STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
2502      __ GetObjectType(a3, t0, t0);
2503      __ Branch(&done_convert, hs, t0, Operand(FIRST_JS_RECEIVER_TYPE));
2504      if (mode != ConvertReceiverMode::kNotNullOrUndefined) {
2505        Label convert_global_proxy;
2506        __ JumpIfRoot(a3, Heap::kUndefinedValueRootIndex,
2507                      &convert_global_proxy);
2508        __ JumpIfNotRoot(a3, Heap::kNullValueRootIndex, &convert_to_object);
2509        __ bind(&convert_global_proxy);
2510        {
2511          // Patch receiver to global proxy.
2512          __ LoadGlobalProxy(a3);
2513        }
2514        __ Branch(&convert_receiver);
2515      }
2516      __ bind(&convert_to_object);
2517      {
2518        // Convert receiver using ToObject.
2519        // TODO(bmeurer): Inline the allocation here to avoid building the frame
2520        // in the fast case? (fall back to AllocateInNewSpace?)
2521        FrameScope scope(masm, StackFrame::INTERNAL);
2522        __ sll(a0, a0, kSmiTagSize);  // Smi tagged.
2523        __ Push(a0, a1);
2524        __ mov(a0, a3);
2525        __ Push(cp);
2526        __ Call(masm->isolate()->builtins()->ToObject(),
2527                RelocInfo::CODE_TARGET);
2528        __ Pop(cp);
2529        __ mov(a3, v0);
2530        __ Pop(a0, a1);
2531        __ sra(a0, a0, kSmiTagSize);  // Un-tag.
2532      }
2533      __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
2534      __ bind(&convert_receiver);
2535    }
2536    __ Lsa(at, sp, a0, kPointerSizeLog2);
2537    __ sw(a3, MemOperand(at));
2538  }
2539  __ bind(&done_convert);
2540
2541  // ----------- S t a t e -------------
2542  //  -- a0 : the number of arguments (not including the receiver)
2543  //  -- a1 : the function to call (checked to be a JSFunction)
2544  //  -- a2 : the shared function info.
2545  //  -- cp : the function context.
2546  // -----------------------------------
2547
2548  if (tail_call_mode == TailCallMode::kAllow) {
2549    PrepareForTailCall(masm, a0, t0, t1, t2);
2550  }
2551
2552  __ lw(a2,
2553        FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset));
2554  __ sra(a2, a2, kSmiTagSize);  // Un-tag.
2555  ParameterCount actual(a0);
2556  ParameterCount expected(a2);
2557  __ InvokeFunctionCode(a1, no_reg, expected, actual, JUMP_FUNCTION,
2558                        CheckDebugStepCallWrapper());
2559
2560  // The function is a "classConstructor", need to raise an exception.
2561  __ bind(&class_constructor);
2562  {
2563    FrameScope frame(masm, StackFrame::INTERNAL);
2564    __ Push(a1);
2565    __ CallRuntime(Runtime::kThrowConstructorNonCallableError);
2566  }
2567}
2568
2569// static
2570void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm,
2571                                              TailCallMode tail_call_mode) {
2572  // ----------- S t a t e -------------
2573  //  -- a0 : the number of arguments (not including the receiver)
2574  //  -- a1 : the function to call (checked to be a JSBoundFunction)
2575  // -----------------------------------
2576  __ AssertBoundFunction(a1);
2577
2578  if (tail_call_mode == TailCallMode::kAllow) {
2579    PrepareForTailCall(masm, a0, t0, t1, t2);
2580  }
2581
2582  // Patch the receiver to [[BoundThis]].
2583  {
2584    __ lw(at, FieldMemOperand(a1, JSBoundFunction::kBoundThisOffset));
2585    __ Lsa(t0, sp, a0, kPointerSizeLog2);
2586    __ sw(at, MemOperand(t0));
2587  }
2588
2589  // Load [[BoundArguments]] into a2 and length of that into t0.
2590  __ lw(a2, FieldMemOperand(a1, JSBoundFunction::kBoundArgumentsOffset));
2591  __ lw(t0, FieldMemOperand(a2, FixedArray::kLengthOffset));
2592  __ SmiUntag(t0);
2593
2594  // ----------- S t a t e -------------
2595  //  -- a0 : the number of arguments (not including the receiver)
2596  //  -- a1 : the function to call (checked to be a JSBoundFunction)
2597  //  -- a2 : the [[BoundArguments]] (implemented as FixedArray)
2598  //  -- t0 : the number of [[BoundArguments]]
2599  // -----------------------------------
2600
2601  // Reserve stack space for the [[BoundArguments]].
2602  {
2603    Label done;
2604    __ sll(t1, t0, kPointerSizeLog2);
2605    __ Subu(sp, sp, Operand(t1));
2606    // Check the stack for overflow. We are not trying to catch interruptions
2607    // (i.e. debug break and preemption) here, so check the "real stack limit".
2608    __ LoadRoot(at, Heap::kRealStackLimitRootIndex);
2609    __ Branch(&done, gt, sp, Operand(at));  // Signed comparison.
2610    // Restore the stack pointer.
2611    __ Addu(sp, sp, Operand(t1));
2612    {
2613      FrameScope scope(masm, StackFrame::MANUAL);
2614      __ EnterFrame(StackFrame::INTERNAL);
2615      __ CallRuntime(Runtime::kThrowStackOverflow);
2616    }
2617    __ bind(&done);
2618  }
2619
2620  // Relocate arguments down the stack.
2621  {
2622    Label loop, done_loop;
2623    __ mov(t1, zero_reg);
2624    __ bind(&loop);
2625    __ Branch(&done_loop, gt, t1, Operand(a0));
2626    __ Lsa(t2, sp, t0, kPointerSizeLog2);
2627    __ lw(at, MemOperand(t2));
2628    __ Lsa(t2, sp, t1, kPointerSizeLog2);
2629    __ sw(at, MemOperand(t2));
2630    __ Addu(t0, t0, Operand(1));
2631    __ Addu(t1, t1, Operand(1));
2632    __ Branch(&loop);
2633    __ bind(&done_loop);
2634  }
2635
2636  // Copy [[BoundArguments]] to the stack (below the arguments).
2637  {
2638    Label loop, done_loop;
2639    __ lw(t0, FieldMemOperand(a2, FixedArray::kLengthOffset));
2640    __ SmiUntag(t0);
2641    __ Addu(a2, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
2642    __ bind(&loop);
2643    __ Subu(t0, t0, Operand(1));
2644    __ Branch(&done_loop, lt, t0, Operand(zero_reg));
2645    __ Lsa(t1, a2, t0, kPointerSizeLog2);
2646    __ lw(at, MemOperand(t1));
2647    __ Lsa(t1, sp, a0, kPointerSizeLog2);
2648    __ sw(at, MemOperand(t1));
2649    __ Addu(a0, a0, Operand(1));
2650    __ Branch(&loop);
2651    __ bind(&done_loop);
2652  }
2653
2654  // Call the [[BoundTargetFunction]] via the Call builtin.
2655  __ lw(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
2656  __ li(at, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny,
2657                                      masm->isolate())));
2658  __ lw(at, MemOperand(at));
2659  __ Addu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag));
2660  __ Jump(at);
2661}
2662
2663// static
2664void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
2665                             TailCallMode tail_call_mode) {
2666  // ----------- S t a t e -------------
2667  //  -- a0 : the number of arguments (not including the receiver)
2668  //  -- a1 : the target to call (can be any Object).
2669  // -----------------------------------
2670
2671  Label non_callable, non_function, non_smi;
2672  __ JumpIfSmi(a1, &non_callable);
2673  __ bind(&non_smi);
2674  __ GetObjectType(a1, t1, t2);
2675  __ Jump(masm->isolate()->builtins()->CallFunction(mode, tail_call_mode),
2676          RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE));
2677  __ Jump(masm->isolate()->builtins()->CallBoundFunction(tail_call_mode),
2678          RelocInfo::CODE_TARGET, eq, t2, Operand(JS_BOUND_FUNCTION_TYPE));
2679
2680  // Check if target has a [[Call]] internal method.
2681  __ lbu(t1, FieldMemOperand(t1, Map::kBitFieldOffset));
2682  __ And(t1, t1, Operand(1 << Map::kIsCallable));
2683  __ Branch(&non_callable, eq, t1, Operand(zero_reg));
2684
2685  __ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE));
2686
2687  // 0. Prepare for tail call if necessary.
2688  if (tail_call_mode == TailCallMode::kAllow) {
2689    PrepareForTailCall(masm, a0, t0, t1, t2);
2690  }
2691
2692  // 1. Runtime fallback for Proxy [[Call]].
2693  __ Push(a1);
2694  // Increase the arguments size to include the pushed function and the
2695  // existing receiver on the stack.
2696  __ Addu(a0, a0, 2);
2697  // Tail-call to the runtime.
2698  __ JumpToExternalReference(
2699      ExternalReference(Runtime::kJSProxyCall, masm->isolate()));
2700
2701  // 2. Call to something else, which might have a [[Call]] internal method (if
2702  // not we raise an exception).
2703  __ bind(&non_function);
2704  // Overwrite the original receiver with the (original) target.
2705  __ Lsa(at, sp, a0, kPointerSizeLog2);
2706  __ sw(a1, MemOperand(at));
2707  // Let the "call_as_function_delegate" take care of the rest.
2708  __ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, a1);
2709  __ Jump(masm->isolate()->builtins()->CallFunction(
2710              ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode),
2711          RelocInfo::CODE_TARGET);
2712
2713  // 3. Call to something that is not callable.
2714  __ bind(&non_callable);
2715  {
2716    FrameScope scope(masm, StackFrame::INTERNAL);
2717    __ Push(a1);
2718    __ CallRuntime(Runtime::kThrowCalledNonCallable);
2719  }
2720}
2721
2722static void CheckSpreadAndPushToStack(MacroAssembler* masm) {
2723  Register argc = a0;
2724  Register constructor = a1;
2725  Register new_target = a3;
2726
2727  Register scratch = t0;
2728  Register scratch2 = t1;
2729
2730  Register spread = a2;
2731  Register spread_map = t3;
2732
2733  Register spread_len = t3;
2734
2735  Register native_context = t4;
2736
2737  Label runtime_call, push_args;
2738  __ lw(spread, MemOperand(sp, 0));
2739  __ JumpIfSmi(spread, &runtime_call);
2740  __ lw(spread_map, FieldMemOperand(spread, HeapObject::kMapOffset));
2741  __ lw(native_context, NativeContextMemOperand());
2742
2743  // Check that the spread is an array.
2744  __ lbu(scratch, FieldMemOperand(spread_map, Map::kInstanceTypeOffset));
2745  __ Branch(&runtime_call, ne, scratch, Operand(JS_ARRAY_TYPE));
2746
2747  // Check that we have the original ArrayPrototype.
2748  __ lw(scratch, FieldMemOperand(spread_map, Map::kPrototypeOffset));
2749  __ lw(scratch2, ContextMemOperand(native_context,
2750                                    Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
2751  __ Branch(&runtime_call, ne, scratch, Operand(scratch2));
2752
2753  // Check that the ArrayPrototype hasn't been modified in a way that would
2754  // affect iteration.
2755  __ LoadRoot(scratch, Heap::kArrayIteratorProtectorRootIndex);
2756  __ lw(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset));
2757  __ Branch(&runtime_call, ne, scratch,
2758            Operand(Smi::FromInt(Isolate::kProtectorValid)));
2759
2760  // Check that the map of the initial array iterator hasn't changed.
2761  __ lw(scratch,
2762        ContextMemOperand(native_context,
2763                          Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX));
2764  __ lw(scratch, FieldMemOperand(scratch, HeapObject::kMapOffset));
2765  __ lw(scratch2,
2766        ContextMemOperand(native_context,
2767                          Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_MAP_INDEX));
2768  __ Branch(&runtime_call, ne, scratch, Operand(scratch2));
2769
2770  // For FastPacked kinds, iteration will have the same effect as simply
2771  // accessing each property in order.
2772  Label no_protector_check;
2773  __ lbu(scratch, FieldMemOperand(spread_map, Map::kBitField2Offset));
2774  __ DecodeField<Map::ElementsKindBits>(scratch);
2775  __ Branch(&runtime_call, hi, scratch, Operand(FAST_HOLEY_ELEMENTS));
2776  // For non-FastHoley kinds, we can skip the protector check.
2777  __ Branch(&no_protector_check, eq, scratch, Operand(FAST_SMI_ELEMENTS));
2778  __ Branch(&no_protector_check, eq, scratch, Operand(FAST_ELEMENTS));
2779  // Check the ArrayProtector cell.
2780  __ LoadRoot(scratch, Heap::kArrayProtectorRootIndex);
2781  __ lw(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset));
2782  __ Branch(&runtime_call, ne, scratch,
2783            Operand(Smi::FromInt(Isolate::kProtectorValid)));
2784
2785  __ bind(&no_protector_check);
2786  // Load the FixedArray backing store, but use the length from the array.
2787  __ lw(spread_len, FieldMemOperand(spread, JSArray::kLengthOffset));
2788  __ SmiUntag(spread_len);
2789  __ lw(spread, FieldMemOperand(spread, JSArray::kElementsOffset));
2790  __ Branch(&push_args);
2791
2792  __ bind(&runtime_call);
2793  {
2794    // Call the builtin for the result of the spread.
2795    FrameScope scope(masm, StackFrame::INTERNAL);
2796    __ SmiTag(argc);
2797    __ Push(constructor, new_target, argc, spread);
2798    __ CallRuntime(Runtime::kSpreadIterableFixed);
2799    __ mov(spread, v0);
2800    __ Pop(constructor, new_target, argc);
2801    __ SmiUntag(argc);
2802  }
2803
2804  {
2805    // Calculate the new nargs including the result of the spread.
2806    __ lw(spread_len, FieldMemOperand(spread, FixedArray::kLengthOffset));
2807    __ SmiUntag(spread_len);
2808
2809    __ bind(&push_args);
2810    // argc += spread_len - 1. Subtract 1 for the spread itself.
2811    __ Addu(argc, argc, spread_len);
2812    __ Subu(argc, argc, Operand(1));
2813
2814    // Pop the spread argument off the stack.
2815    __ Pop(scratch);
2816  }
2817
2818  // Check for stack overflow.
2819  {
2820    // Check the stack for overflow. We are not trying to catch interruptions
2821    // (i.e. debug break and preemption) here, so check the "real stack limit".
2822    Label done;
2823    __ LoadRoot(scratch, Heap::kRealStackLimitRootIndex);
2824    // Make scratch the space we have left. The stack might already be
2825    // overflowed here which will cause ip to become negative.
2826    __ Subu(scratch, sp, scratch);
2827    // Check if the arguments will overflow the stack.
2828    __ sll(at, spread_len, kPointerSizeLog2);
2829    __ Branch(&done, gt, scratch, Operand(at));  // Signed comparison.
2830    __ TailCallRuntime(Runtime::kThrowStackOverflow);
2831    __ bind(&done);
2832  }
2833
2834  // Put the evaluated spread onto the stack as additional arguments.
2835  {
2836    __ mov(scratch, zero_reg);
2837    Label done, push, loop;
2838    __ bind(&loop);
2839    __ Branch(&done, eq, scratch, Operand(spread_len));
2840    __ Lsa(scratch2, spread, scratch, kPointerSizeLog2);
2841    __ lw(scratch2, FieldMemOperand(scratch2, FixedArray::kHeaderSize));
2842    __ JumpIfNotRoot(scratch2, Heap::kTheHoleValueRootIndex, &push);
2843    __ LoadRoot(scratch2, Heap::kUndefinedValueRootIndex);
2844    __ bind(&push);
2845    __ Push(scratch2);
2846    __ Addu(scratch, scratch, Operand(1));
2847    __ Branch(&loop);
2848    __ bind(&done);
2849  }
2850}
2851
2852// static
2853void Builtins::Generate_CallWithSpread(MacroAssembler* masm) {
2854  // ----------- S t a t e -------------
2855  //  -- a0 : the number of arguments (not including the receiver)
2856  //  -- a1 : the target to call (can be any Object).
2857  // -----------------------------------
2858
2859  // CheckSpreadAndPushToStack will push a3 to save it.
2860  __ LoadRoot(a3, Heap::kUndefinedValueRootIndex);
2861  CheckSpreadAndPushToStack(masm);
2862  __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2863                                            TailCallMode::kDisallow),
2864          RelocInfo::CODE_TARGET);
2865}
2866
2867// static
2868void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
2869  // ----------- S t a t e -------------
2870  //  -- a0 : the number of arguments (not including the receiver)
2871  //  -- a1 : the constructor to call (checked to be a JSFunction)
2872  //  -- a3 : the new target (checked to be a constructor)
2873  // -----------------------------------
2874  __ AssertFunction(a1);
2875
2876  // Calling convention for function specific ConstructStubs require
2877  // a2 to contain either an AllocationSite or undefined.
2878  __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
2879
2880  // Tail call to the function-specific construct stub (still in the caller
2881  // context at this point).
2882  __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
2883  __ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kConstructStubOffset));
2884  __ Addu(at, t0, Operand(Code::kHeaderSize - kHeapObjectTag));
2885  __ Jump(at);
2886}
2887
2888// static
2889void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
2890  // ----------- S t a t e -------------
2891  //  -- a0 : the number of arguments (not including the receiver)
2892  //  -- a1 : the function to call (checked to be a JSBoundFunction)
2893  //  -- a3 : the new target (checked to be a constructor)
2894  // -----------------------------------
2895  __ AssertBoundFunction(a1);
2896
2897  // Load [[BoundArguments]] into a2 and length of that into t0.
2898  __ lw(a2, FieldMemOperand(a1, JSBoundFunction::kBoundArgumentsOffset));
2899  __ lw(t0, FieldMemOperand(a2, FixedArray::kLengthOffset));
2900  __ SmiUntag(t0);
2901
2902  // ----------- S t a t e -------------
2903  //  -- a0 : the number of arguments (not including the receiver)
2904  //  -- a1 : the function to call (checked to be a JSBoundFunction)
2905  //  -- a2 : the [[BoundArguments]] (implemented as FixedArray)
2906  //  -- a3 : the new target (checked to be a constructor)
2907  //  -- t0 : the number of [[BoundArguments]]
2908  // -----------------------------------
2909
2910  // Reserve stack space for the [[BoundArguments]].
2911  {
2912    Label done;
2913    __ sll(t1, t0, kPointerSizeLog2);
2914    __ Subu(sp, sp, Operand(t1));
2915    // Check the stack for overflow. We are not trying to catch interruptions
2916    // (i.e. debug break and preemption) here, so check the "real stack limit".
2917    __ LoadRoot(at, Heap::kRealStackLimitRootIndex);
2918    __ Branch(&done, gt, sp, Operand(at));  // Signed comparison.
2919    // Restore the stack pointer.
2920    __ Addu(sp, sp, Operand(t1));
2921    {
2922      FrameScope scope(masm, StackFrame::MANUAL);
2923      __ EnterFrame(StackFrame::INTERNAL);
2924      __ CallRuntime(Runtime::kThrowStackOverflow);
2925    }
2926    __ bind(&done);
2927  }
2928
2929  // Relocate arguments down the stack.
2930  {
2931    Label loop, done_loop;
2932    __ mov(t1, zero_reg);
2933    __ bind(&loop);
2934    __ Branch(&done_loop, ge, t1, Operand(a0));
2935    __ Lsa(t2, sp, t0, kPointerSizeLog2);
2936    __ lw(at, MemOperand(t2));
2937    __ Lsa(t2, sp, t1, kPointerSizeLog2);
2938    __ sw(at, MemOperand(t2));
2939    __ Addu(t0, t0, Operand(1));
2940    __ Addu(t1, t1, Operand(1));
2941    __ Branch(&loop);
2942    __ bind(&done_loop);
2943  }
2944
2945  // Copy [[BoundArguments]] to the stack (below the arguments).
2946  {
2947    Label loop, done_loop;
2948    __ lw(t0, FieldMemOperand(a2, FixedArray::kLengthOffset));
2949    __ SmiUntag(t0);
2950    __ Addu(a2, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
2951    __ bind(&loop);
2952    __ Subu(t0, t0, Operand(1));
2953    __ Branch(&done_loop, lt, t0, Operand(zero_reg));
2954    __ Lsa(t1, a2, t0, kPointerSizeLog2);
2955    __ lw(at, MemOperand(t1));
2956    __ Lsa(t1, sp, a0, kPointerSizeLog2);
2957    __ sw(at, MemOperand(t1));
2958    __ Addu(a0, a0, Operand(1));
2959    __ Branch(&loop);
2960    __ bind(&done_loop);
2961  }
2962
2963  // Patch new.target to [[BoundTargetFunction]] if new.target equals target.
2964  {
2965    Label skip_load;
2966    __ Branch(&skip_load, ne, a1, Operand(a3));
2967    __ lw(a3, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
2968    __ bind(&skip_load);
2969  }
2970
2971  // Construct the [[BoundTargetFunction]] via the Construct builtin.
2972  __ lw(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
2973  __ li(at, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
2974  __ lw(at, MemOperand(at));
2975  __ Addu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag));
2976  __ Jump(at);
2977}
2978
2979// static
2980void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
2981  // ----------- S t a t e -------------
2982  //  -- a0 : the number of arguments (not including the receiver)
2983  //  -- a1 : the constructor to call (checked to be a JSProxy)
2984  //  -- a3 : the new target (either the same as the constructor or
2985  //          the JSFunction on which new was invoked initially)
2986  // -----------------------------------
2987
2988  // Call into the Runtime for Proxy [[Construct]].
2989  __ Push(a1, a3);
2990  // Include the pushed new_target, constructor and the receiver.
2991  __ Addu(a0, a0, Operand(3));
2992  // Tail-call to the runtime.
2993  __ JumpToExternalReference(
2994      ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
2995}
2996
2997// static
2998void Builtins::Generate_Construct(MacroAssembler* masm) {
2999  // ----------- S t a t e -------------
3000  //  -- a0 : the number of arguments (not including the receiver)
3001  //  -- a1 : the constructor to call (can be any Object)
3002  //  -- a3 : the new target (either the same as the constructor or
3003  //          the JSFunction on which new was invoked initially)
3004  // -----------------------------------
3005
3006  // Check if target is a Smi.
3007  Label non_constructor;
3008  __ JumpIfSmi(a1, &non_constructor);
3009
3010  // Dispatch based on instance type.
3011  __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset));
3012  __ lbu(t2, FieldMemOperand(t1, Map::kInstanceTypeOffset));
3013  __ Jump(masm->isolate()->builtins()->ConstructFunction(),
3014          RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE));
3015
3016  // Check if target has a [[Construct]] internal method.
3017  __ lbu(t3, FieldMemOperand(t1, Map::kBitFieldOffset));
3018  __ And(t3, t3, Operand(1 << Map::kIsConstructor));
3019  __ Branch(&non_constructor, eq, t3, Operand(zero_reg));
3020
3021  // Only dispatch to bound functions after checking whether they are
3022  // constructors.
3023  __ Jump(masm->isolate()->builtins()->ConstructBoundFunction(),
3024          RelocInfo::CODE_TARGET, eq, t2, Operand(JS_BOUND_FUNCTION_TYPE));
3025
3026  // Only dispatch to proxies after checking whether they are constructors.
3027  __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
3028          eq, t2, Operand(JS_PROXY_TYPE));
3029
3030  // Called Construct on an exotic Object with a [[Construct]] internal method.
3031  {
3032    // Overwrite the original receiver with the (original) target.
3033    __ Lsa(at, sp, a0, kPointerSizeLog2);
3034    __ sw(a1, MemOperand(at));
3035    // Let the "call_as_constructor_delegate" take care of the rest.
3036    __ LoadNativeContextSlot(Context::CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, a1);
3037    __ Jump(masm->isolate()->builtins()->CallFunction(),
3038            RelocInfo::CODE_TARGET);
3039  }
3040
3041  // Called Construct on an Object that doesn't have a [[Construct]] internal
3042  // method.
3043  __ bind(&non_constructor);
3044  __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
3045          RelocInfo::CODE_TARGET);
3046}
3047
3048// static
3049void Builtins::Generate_ConstructWithSpread(MacroAssembler* masm) {
3050  // ----------- S t a t e -------------
3051  //  -- a0 : the number of arguments (not including the receiver)
3052  //  -- a1 : the constructor to call (can be any Object)
3053  //  -- a3 : the new target (either the same as the constructor or
3054  //          the JSFunction on which new was invoked initially)
3055  // -----------------------------------
3056
3057  CheckSpreadAndPushToStack(masm);
3058  __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
3059}
3060
3061// static
3062void Builtins::Generate_AllocateInNewSpace(MacroAssembler* masm) {
3063  // ----------- S t a t e -------------
3064  //  -- a0 : requested object size (untagged)
3065  //  -- ra : return address
3066  // -----------------------------------
3067  __ SmiTag(a0);
3068  __ Push(a0);
3069  __ Move(cp, Smi::kZero);
3070  __ TailCallRuntime(Runtime::kAllocateInNewSpace);
3071}
3072
3073// static
3074void Builtins::Generate_AllocateInOldSpace(MacroAssembler* masm) {
3075  // ----------- S t a t e -------------
3076  //  -- a0 : requested object size (untagged)
3077  //  -- ra : return address
3078  // -----------------------------------
3079  __ SmiTag(a0);
3080  __ Move(a1, Smi::FromInt(AllocateTargetSpace::encode(OLD_SPACE)));
3081  __ Push(a0, a1);
3082  __ Move(cp, Smi::kZero);
3083  __ TailCallRuntime(Runtime::kAllocateInTargetSpace);
3084}
3085
3086// static
3087void Builtins::Generate_Abort(MacroAssembler* masm) {
3088  // ----------- S t a t e -------------
3089  //  -- a0 : message_id as Smi
3090  //  -- ra : return address
3091  // -----------------------------------
3092  __ Push(a0);
3093  __ Move(cp, Smi::kZero);
3094  __ TailCallRuntime(Runtime::kAbort);
3095}
3096
3097void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
3098  // State setup as expected by MacroAssembler::InvokePrologue.
3099  // ----------- S t a t e -------------
3100  //  -- a0: actual arguments count
3101  //  -- a1: function (passed through to callee)
3102  //  -- a2: expected arguments count
3103  //  -- a3: new target (passed through to callee)
3104  // -----------------------------------
3105
3106  Label invoke, dont_adapt_arguments, stack_overflow;
3107
3108  Label enough, too_few;
3109  __ Branch(&dont_adapt_arguments, eq, a2,
3110            Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
3111  // We use Uless as the number of argument should always be greater than 0.
3112  __ Branch(&too_few, Uless, a0, Operand(a2));
3113
3114  {  // Enough parameters: actual >= expected.
3115    // a0: actual number of arguments as a smi
3116    // a1: function
3117    // a2: expected number of arguments
3118    // a3: new target (passed through to callee)
3119    __ bind(&enough);
3120    EnterArgumentsAdaptorFrame(masm);
3121    Generate_StackOverflowCheck(masm, a2, t1, at, &stack_overflow);
3122
3123    // Calculate copy start address into a0 and copy end address into t1.
3124    __ Lsa(a0, fp, a0, kPointerSizeLog2 - kSmiTagSize);
3125    // Adjust for return address and receiver.
3126    __ Addu(a0, a0, Operand(2 * kPointerSize));
3127    // Compute copy end address.
3128    __ sll(t1, a2, kPointerSizeLog2);
3129    __ subu(t1, a0, t1);
3130
3131    // Copy the arguments (including the receiver) to the new stack frame.
3132    // a0: copy start address
3133    // a1: function
3134    // a2: expected number of arguments
3135    // a3: new target (passed through to callee)
3136    // t1: copy end address
3137
3138    Label copy;
3139    __ bind(&copy);
3140    __ lw(t0, MemOperand(a0));
3141    __ push(t0);
3142    __ Branch(USE_DELAY_SLOT, &copy, ne, a0, Operand(t1));
3143    __ addiu(a0, a0, -kPointerSize);  // In delay slot.
3144
3145    __ jmp(&invoke);
3146  }
3147
3148  {  // Too few parameters: Actual < expected.
3149    __ bind(&too_few);
3150    EnterArgumentsAdaptorFrame(masm);
3151    Generate_StackOverflowCheck(masm, a2, t1, at, &stack_overflow);
3152
3153    // Calculate copy start address into a0 and copy end address into t3.
3154    // a0: actual number of arguments as a smi
3155    // a1: function
3156    // a2: expected number of arguments
3157    // a3: new target (passed through to callee)
3158    __ Lsa(a0, fp, a0, kPointerSizeLog2 - kSmiTagSize);
3159    // Adjust for return address and receiver.
3160    __ Addu(a0, a0, Operand(2 * kPointerSize));
3161    // Compute copy end address. Also adjust for return address.
3162    __ Addu(t3, fp, kPointerSize);
3163
3164    // Copy the arguments (including the receiver) to the new stack frame.
3165    // a0: copy start address
3166    // a1: function
3167    // a2: expected number of arguments
3168    // a3: new target (passed through to callee)
3169    // t3: copy end address
3170    Label copy;
3171    __ bind(&copy);
3172    __ lw(t0, MemOperand(a0));  // Adjusted above for return addr and receiver.
3173    __ Subu(sp, sp, kPointerSize);
3174    __ Subu(a0, a0, kPointerSize);
3175    __ Branch(USE_DELAY_SLOT, &copy, ne, a0, Operand(t3));
3176    __ sw(t0, MemOperand(sp));  // In the delay slot.
3177
3178    // Fill the remaining expected arguments with undefined.
3179    // a1: function
3180    // a2: expected number of arguments
3181    // a3: new target (passed through to callee)
3182    __ LoadRoot(t0, Heap::kUndefinedValueRootIndex);
3183    __ sll(t2, a2, kPointerSizeLog2);
3184    __ Subu(t1, fp, Operand(t2));
3185    // Adjust for frame.
3186    __ Subu(t1, t1, Operand(StandardFrameConstants::kFixedFrameSizeFromFp +
3187                            2 * kPointerSize));
3188
3189    Label fill;
3190    __ bind(&fill);
3191    __ Subu(sp, sp, kPointerSize);
3192    __ Branch(USE_DELAY_SLOT, &fill, ne, sp, Operand(t1));
3193    __ sw(t0, MemOperand(sp));
3194  }
3195
3196  // Call the entry point.
3197  __ bind(&invoke);
3198  __ mov(a0, a2);
3199  // a0 : expected number of arguments
3200  // a1 : function (passed through to callee)
3201  // a3 : new target (passed through to callee)
3202  __ lw(t0, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
3203  __ Call(t0);
3204
3205  // Store offset of return address for deoptimizer.
3206  masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
3207
3208  // Exit frame and return.
3209  LeaveArgumentsAdaptorFrame(masm);
3210  __ Ret();
3211
3212  // -------------------------------------------
3213  // Don't adapt arguments.
3214  // -------------------------------------------
3215  __ bind(&dont_adapt_arguments);
3216  __ lw(t0, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
3217  __ Jump(t0);
3218
3219  __ bind(&stack_overflow);
3220  {
3221    FrameScope frame(masm, StackFrame::MANUAL);
3222    __ CallRuntime(Runtime::kThrowStackOverflow);
3223    __ break_(0xCC);
3224  }
3225}
3226
3227#undef __
3228
3229}  // namespace internal
3230}  // namespace v8
3231
3232#endif  // V8_TARGET_ARCH_MIPS
3233