Home | History | Annotate | Download | only in mips
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #if V8_TARGET_ARCH_MIPS
      6 
      7 #include "src/codegen.h"
      8 #include "src/debug/debug.h"
      9 #include "src/deoptimizer.h"
     10 #include "src/full-codegen/full-codegen.h"
     11 #include "src/runtime/runtime.h"
     12 
     13 namespace v8 {
     14 namespace internal {
     15 
     16 #define __ ACCESS_MASM(masm)
     17 
     18 void 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.
     52 static 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.
     59 static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
     60   // Load the Array function from the native context.
     61   __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, result);
     62 }
     63 
     64 void 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 
     93 void 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
    124 void 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
    241 void 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
    284 void 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
    363 void 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
    433 void 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 
    513 static 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 
    520 static 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 
    545 void 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 
    561 namespace {
    562 
    563 void 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 
    747 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
    748   Generate_JSConstructStubHelper(masm, false, true, false);
    749 }
    750 
    751 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
    752   Generate_JSConstructStubHelper(masm, true, false, false);
    753 }
    754 
    755 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
    756   Generate_JSConstructStubHelper(masm, false, false, false);
    757 }
    758 
    759 void Builtins::Generate_JSBuiltinsConstructStubForDerived(
    760     MacroAssembler* masm) {
    761   Generate_JSConstructStubHelper(masm, false, false, true);
    762 }
    763 
    764 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
    765   FrameScope scope(masm, StackFrame::INTERNAL);
    766   __ Push(a1);
    767   __ CallRuntime(Runtime::kThrowConstructedNonConstructable);
    768 }
    769 
    770 enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt };
    771 
    772 // Clobbers a2; preserves all other registers.
    773 static 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 
    799 static 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 
    875 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
    876   Generate_JSEntryTrampolineHelper(masm, false);
    877 }
    878 
    879 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
    880   Generate_JSEntryTrampolineHelper(masm, true);
    881 }
    882 
    883 // static
    884 void 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 
    996 static 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.
   1027 void 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 
   1154 static 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 
   1170 static 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
   1194 void 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
   1234 void 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
   1280 void 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 
   1311 static 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 
   1354 void 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 
   1373 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
   1374   Generate_InterpreterEnterBytecode(masm);
   1375 }
   1376 
   1377 void 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 
   1504 void Builtins::Generate_CompileBaseline(MacroAssembler* masm) {
   1505   GenerateTailCallToReturnedCode(masm, Runtime::kCompileBaseline);
   1506 }
   1507 
   1508 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) {
   1509   GenerateTailCallToReturnedCode(masm,
   1510                                  Runtime::kCompileOptimized_NotConcurrent);
   1511 }
   1512 
   1513 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
   1514   GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
   1515 }
   1516 
   1517 void 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 
   1578 static 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   }
   1609 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR)
   1610 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
   1611 
   1612 void 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 
   1645 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
   1646   GenerateMakeCodeYoungAgainCommon(masm);
   1647 }
   1648 
   1649 void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
   1650   Generate_MarkCodeAsExecutedOnce(masm);
   1651 }
   1652 
   1653 static 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 
   1671 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
   1672   Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs);
   1673 }
   1674 
   1675 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
   1676   Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
   1677 }
   1678 
   1679 static 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 
   1714 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
   1715   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
   1716 }
   1717 
   1718 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) {
   1719   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
   1720 }
   1721 
   1722 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
   1723   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
   1724 }
   1725 
   1726 // Clobbers {t2, t3, t4, t5}.
   1727 static 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 
   1788 void 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 
   1824 static 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 
   1870 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
   1871   Generate_OnStackReplacementHelper(masm, false);
   1872 }
   1873 
   1874 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
   1875   Generate_OnStackReplacementHelper(masm, true);
   1876 }
   1877 
   1878 // static
   1879 void 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
   1952 void 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 
   1993 void 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 
   2056 void 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 
   2134 static 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 
   2142 static 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
   2158 void 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
   2299 void 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 
   2364 namespace {
   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 //
   2393 void 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
   2456 void 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
   2570 void 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
   2664 void 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 
   2722 static 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
   2853 void 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
   2868 void 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
   2889 void 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
   2980 void 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
   2998 void 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
   3049 void 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
   3062 void 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
   3074 void 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
   3087 void 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 
   3097 void 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