Home | History | Annotate | Download | only in mips64
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #if V8_TARGET_ARCH_MIPS64
      6 
      7 #include "src/codegen.h"
      8 #include "src/debug/debug.h"
      9 #include "src/deoptimizer.h"
     10 #include "src/full-codegen/full-codegen.h"
     11 #include "src/runtime/runtime.h"
     12 
     13 namespace v8 {
     14 namespace internal {
     15 
     16 
     17 #define __ ACCESS_MASM(masm)
     18 
     19 
     20 void Builtins::Generate_Adaptor(MacroAssembler* masm,
     21                                 CFunctionId id,
     22                                 BuiltinExtraArguments extra_args) {
     23   // ----------- S t a t e -------------
     24   //  -- a0                 : number of arguments excluding receiver
     25   //  -- a1                 : target
     26   //  -- a3                 : new.target
     27   //  -- sp[0]              : last argument
     28   //  -- ...
     29   //  -- sp[8 * (argc - 1)] : first argument
     30   //  -- sp[8 * agrc]       : receiver
     31   // -----------------------------------
     32   __ AssertFunction(a1);
     33 
     34   // Make sure we operate in the context of the called function (for example
     35   // ConstructStubs implemented in C++ will be run in the context of the caller
     36   // instead of the callee, due to the way that [[Construct]] is defined for
     37   // ordinary functions).
     38   __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
     39 
     40   // Insert extra arguments.
     41   int num_extra_args = 0;
     42   switch (extra_args) {
     43     case BuiltinExtraArguments::kTarget:
     44       __ Push(a1);
     45       ++num_extra_args;
     46       break;
     47     case BuiltinExtraArguments::kNewTarget:
     48       __ Push(a3);
     49       ++num_extra_args;
     50       break;
     51     case BuiltinExtraArguments::kTargetAndNewTarget:
     52       __ Push(a1, a3);
     53       num_extra_args += 2;
     54       break;
     55     case BuiltinExtraArguments::kNone:
     56       break;
     57   }
     58 
     59   // JumpToExternalReference expects a0 to contain the number of arguments
     60   // including the receiver and the extra arguments.
     61   __ Daddu(a0, a0, num_extra_args + 1);
     62 
     63   __ JumpToExternalReference(ExternalReference(id, masm->isolate()));
     64 }
     65 
     66 
     67 // Load the built-in InternalArray function from the current context.
     68 static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
     69                                               Register result) {
     70   // Load the InternalArray function from the native context.
     71   __ LoadNativeContextSlot(Context::INTERNAL_ARRAY_FUNCTION_INDEX, result);
     72 }
     73 
     74 
     75 // Load the built-in Array function from the current context.
     76 static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
     77   // Load the Array function from the native context.
     78   __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, result);
     79 }
     80 
     81 
     82 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
     83   // ----------- S t a t e -------------
     84   //  -- a0     : number of arguments
     85   //  -- ra     : return address
     86   //  -- sp[...]: constructor arguments
     87   // -----------------------------------
     88   Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
     89 
     90   // Get the InternalArray function.
     91   GenerateLoadInternalArrayFunction(masm, a1);
     92 
     93   if (FLAG_debug_code) {
     94     // Initial map for the builtin InternalArray functions should be maps.
     95     __ ld(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
     96     __ SmiTst(a2, a4);
     97     __ Assert(ne, kUnexpectedInitialMapForInternalArrayFunction,
     98               a4, Operand(zero_reg));
     99     __ GetObjectType(a2, a3, a4);
    100     __ Assert(eq, kUnexpectedInitialMapForInternalArrayFunction,
    101               a4, Operand(MAP_TYPE));
    102   }
    103 
    104   // Run the native code for the InternalArray function called as a normal
    105   // function.
    106   // Tail call a stub.
    107   InternalArrayConstructorStub stub(masm->isolate());
    108   __ TailCallStub(&stub);
    109 }
    110 
    111 
    112 void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
    113   // ----------- S t a t e -------------
    114   //  -- a0     : number of arguments
    115   //  -- ra     : return address
    116   //  -- sp[...]: constructor arguments
    117   // -----------------------------------
    118   Label generic_array_code;
    119 
    120   // Get the Array function.
    121   GenerateLoadArrayFunction(masm, a1);
    122 
    123   if (FLAG_debug_code) {
    124     // Initial map for the builtin Array functions should be maps.
    125     __ ld(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
    126     __ SmiTst(a2, a4);
    127     __ Assert(ne, kUnexpectedInitialMapForArrayFunction1,
    128               a4, Operand(zero_reg));
    129     __ GetObjectType(a2, a3, a4);
    130     __ Assert(eq, kUnexpectedInitialMapForArrayFunction2,
    131               a4, Operand(MAP_TYPE));
    132   }
    133 
    134   // Run the native code for the Array function called as a normal function.
    135   // Tail call a stub.
    136   __ mov(a3, a1);
    137   __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
    138   ArrayConstructorStub stub(masm->isolate());
    139   __ TailCallStub(&stub);
    140 }
    141 
    142 
    143 // static
    144 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) {
    145   // ----------- S t a t e -------------
    146   //  -- a0                     : number of arguments
    147   //  -- a1                     : constructor function
    148   //  -- ra                     : return address
    149   //  -- sp[(argc - n - 1) * 8] : arg[n] (zero based)
    150   //  -- sp[argc * 8]           : receiver
    151   // -----------------------------------
    152 
    153   // 1. Load the first argument into a0 and get rid of the rest (including the
    154   // receiver).
    155   Label no_arguments;
    156   {
    157     __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg));
    158     __ Dsubu(a0, a0, Operand(1));
    159     __ dsll(a0, a0, kPointerSizeLog2);
    160     __ Daddu(sp, a0, sp);
    161     __ ld(a0, MemOperand(sp));
    162     __ Drop(2);
    163   }
    164 
    165   // 2a. Convert first argument to number.
    166   ToNumberStub stub(masm->isolate());
    167   __ TailCallStub(&stub);
    168 
    169   // 2b. No arguments, return +0.
    170   __ bind(&no_arguments);
    171   __ Move(v0, Smi::FromInt(0));
    172   __ DropAndRet(1);
    173 }
    174 
    175 
    176 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
    177   // ----------- S t a t e -------------
    178   //  -- a0                     : number of arguments
    179   //  -- a1                     : constructor function
    180   //  -- a3                     : new target
    181   //  -- ra                     : return address
    182   //  -- sp[(argc - n - 1) * 8] : arg[n] (zero based)
    183   //  -- sp[argc * 8]           : receiver
    184   // -----------------------------------
    185 
    186   // 1. Make sure we operate in the context of the called function.
    187   __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
    188 
    189   // 2. Load the first argument into a0 and get rid of the rest (including the
    190   // receiver).
    191   {
    192     Label no_arguments, done;
    193     __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg));
    194     __ Dsubu(a0, a0, Operand(1));
    195     __ dsll(a0, a0, kPointerSizeLog2);
    196     __ Daddu(sp, a0, sp);
    197     __ ld(a0, MemOperand(sp));
    198     __ Drop(2);
    199     __ jmp(&done);
    200     __ bind(&no_arguments);
    201     __ Move(a0, Smi::FromInt(0));
    202     __ Drop(1);
    203     __ bind(&done);
    204   }
    205 
    206   // 3. Make sure a0 is a number.
    207   {
    208     Label done_convert;
    209     __ JumpIfSmi(a0, &done_convert);
    210     __ GetObjectType(a0, a2, a2);
    211     __ Branch(&done_convert, eq, t0, Operand(HEAP_NUMBER_TYPE));
    212     {
    213       FrameScope scope(masm, StackFrame::INTERNAL);
    214       __ Push(a1, a3);
    215       ToNumberStub stub(masm->isolate());
    216       __ CallStub(&stub);
    217       __ Move(a0, v0);
    218       __ Pop(a1, a3);
    219     }
    220     __ bind(&done_convert);
    221   }
    222 
    223   // 4. Check if new target and constructor differ.
    224   Label new_object;
    225   __ Branch(&new_object, ne, a1, Operand(a3));
    226 
    227   // 5. Allocate a JSValue wrapper for the number.
    228   __ AllocateJSValue(v0, a1, a0, a2, t0, &new_object);
    229   __ Ret();
    230 
    231   // 6. Fallback to the runtime to create new object.
    232   __ bind(&new_object);
    233   {
    234     FrameScope scope(masm, StackFrame::INTERNAL);
    235     __ Push(a0, a1, a3);  // first argument, constructor, new target
    236     __ CallRuntime(Runtime::kNewObject);
    237     __ Pop(a0);
    238   }
    239   __ Ret(USE_DELAY_SLOT);
    240   __ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset));  // In delay slot.
    241 }
    242 
    243 
    244 // static
    245 void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
    246   // ----------- S t a t e -------------
    247   //  -- a0                     : number of arguments
    248   //  -- a1                     : constructor function
    249   //  -- ra                     : return address
    250   //  -- sp[(argc - n - 1) * 8] : arg[n] (zero based)
    251   //  -- sp[argc * 8]           : receiver
    252   // -----------------------------------
    253 
    254   // 1. Load the first argument into a0 and get rid of the rest (including the
    255   // receiver).
    256   Label no_arguments;
    257   {
    258     __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg));
    259     __ Dsubu(a0, a0, Operand(1));
    260     __ dsll(a0, a0, kPointerSizeLog2);
    261     __ Daddu(sp, a0, sp);
    262     __ ld(a0, MemOperand(sp));
    263     __ Drop(2);
    264   }
    265 
    266   // 2a. At least one argument, return a0 if it's a string, otherwise
    267   // dispatch to appropriate conversion.
    268   Label to_string, symbol_descriptive_string;
    269   {
    270     __ JumpIfSmi(a0, &to_string);
    271     __ GetObjectType(a0, a1, a1);
    272     STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE);
    273     __ Subu(a1, a1, Operand(FIRST_NONSTRING_TYPE));
    274     __ Branch(&symbol_descriptive_string, eq, a1, Operand(zero_reg));
    275     __ Branch(&to_string, gt, a1, Operand(zero_reg));
    276     __ Ret(USE_DELAY_SLOT);
    277     __ mov(v0, a0);
    278   }
    279 
    280   // 2b. No arguments, return the empty string (and pop the receiver).
    281   __ bind(&no_arguments);
    282   {
    283     __ LoadRoot(v0, Heap::kempty_stringRootIndex);
    284     __ DropAndRet(1);
    285   }
    286 
    287   // 3a. Convert a0 to a string.
    288   __ bind(&to_string);
    289   {
    290     ToStringStub stub(masm->isolate());
    291     __ TailCallStub(&stub);
    292   }
    293 
    294   // 3b. Convert symbol in a0 to a string.
    295   __ bind(&symbol_descriptive_string);
    296   {
    297     __ Push(a0);
    298     __ TailCallRuntime(Runtime::kSymbolDescriptiveString);
    299   }
    300 }
    301 
    302 
    303 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
    304   // ----------- S t a t e -------------
    305   //  -- a0                     : number of arguments
    306   //  -- a1                     : constructor function
    307   //  -- a3                     : new target
    308   //  -- ra                     : return address
    309   //  -- sp[(argc - n - 1) * 8] : arg[n] (zero based)
    310   //  -- sp[argc * 8]           : receiver
    311   // -----------------------------------
    312 
    313   // 1. Make sure we operate in the context of the called function.
    314   __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
    315 
    316   // 2. Load the first argument into a0 and get rid of the rest (including the
    317   // receiver).
    318   {
    319     Label no_arguments, done;
    320     __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg));
    321     __ Dsubu(a0, a0, Operand(1));
    322     __ dsll(a0, a0, kPointerSizeLog2);
    323     __ Daddu(sp, a0, sp);
    324     __ ld(a0, MemOperand(sp));
    325     __ Drop(2);
    326     __ jmp(&done);
    327     __ bind(&no_arguments);
    328     __ LoadRoot(a0, Heap::kempty_stringRootIndex);
    329     __ Drop(1);
    330     __ bind(&done);
    331   }
    332 
    333   // 3. Make sure a0 is a string.
    334   {
    335     Label convert, done_convert;
    336     __ JumpIfSmi(a0, &convert);
    337     __ GetObjectType(a0, a2, a2);
    338     __ And(t0, a2, Operand(kIsNotStringMask));
    339     __ Branch(&done_convert, eq, t0, Operand(zero_reg));
    340     __ bind(&convert);
    341     {
    342       FrameScope scope(masm, StackFrame::INTERNAL);
    343       ToStringStub stub(masm->isolate());
    344       __ Push(a1, a3);
    345       __ CallStub(&stub);
    346       __ Move(a0, v0);
    347       __ Pop(a1, a3);
    348     }
    349     __ bind(&done_convert);
    350   }
    351 
    352   // 4. Check if new target and constructor differ.
    353   Label new_object;
    354   __ Branch(&new_object, ne, a1, Operand(a3));
    355 
    356   // 5. Allocate a JSValue wrapper for the string.
    357   __ AllocateJSValue(v0, a1, a0, a2, t0, &new_object);
    358   __ Ret();
    359 
    360   // 6. Fallback to the runtime to create new object.
    361   __ bind(&new_object);
    362   {
    363     FrameScope scope(masm, StackFrame::INTERNAL);
    364     __ Push(a0, a1, a3);  // first argument, constructor, new target
    365     __ CallRuntime(Runtime::kNewObject);
    366     __ Pop(a0);
    367   }
    368   __ Ret(USE_DELAY_SLOT);
    369   __ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset));  // In delay slot.
    370 }
    371 
    372 
    373 static void CallRuntimePassFunction(
    374     MacroAssembler* masm, Runtime::FunctionId function_id) {
    375   // ----------- S t a t e -------------
    376   //  -- a1 : target function (preserved for callee)
    377   //  -- a3 : new target (preserved for callee)
    378   // -----------------------------------
    379 
    380   FrameScope scope(masm, StackFrame::INTERNAL);
    381   // Push a copy of the function onto the stack.
    382   // Push a copy of the target function and the new target.
    383   __ Push(a1, a3, a1);
    384 
    385   __ CallRuntime(function_id, 1);
    386   // Restore target function and new target.
    387   __ Pop(a1, a3);
    388 }
    389 
    390 
    391 static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
    392   __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
    393   __ ld(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset));
    394   __ Daddu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag));
    395   __ Jump(at);
    396 }
    397 
    398 
    399 static void GenerateTailCallToReturnedCode(MacroAssembler* masm) {
    400   __ Daddu(at, v0, Operand(Code::kHeaderSize - kHeapObjectTag));
    401   __ Jump(at);
    402 }
    403 
    404 
    405 void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) {
    406   // Checking whether the queued function is ready for install is optional,
    407   // since we come across interrupts and stack checks elsewhere.  However,
    408   // not checking may delay installing ready functions, and always checking
    409   // would be quite expensive.  A good compromise is to first check against
    410   // stack limit as a cue for an interrupt signal.
    411   Label ok;
    412   __ LoadRoot(a4, Heap::kStackLimitRootIndex);
    413   __ Branch(&ok, hs, sp, Operand(a4));
    414 
    415   CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode);
    416   GenerateTailCallToReturnedCode(masm);
    417 
    418   __ bind(&ok);
    419   GenerateTailCallToSharedCode(masm);
    420 }
    421 
    422 
    423 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
    424                                            bool is_api_function,
    425                                            bool create_implicit_receiver) {
    426   // ----------- S t a t e -------------
    427   //  -- a0     : number of arguments
    428   //  -- a1     : constructor function
    429   //  -- a2     : allocation site or undefined
    430   //  -- a3     : new target
    431   //  -- ra     : return address
    432   //  -- sp[...]: constructor arguments
    433   // -----------------------------------
    434 
    435   Isolate* isolate = masm->isolate();
    436 
    437   // Enter a construct frame.
    438   {
    439     FrameScope scope(masm, StackFrame::CONSTRUCT);
    440 
    441     // Preserve the incoming parameters on the stack.
    442     __ AssertUndefinedOrAllocationSite(a2, t0);
    443     __ SmiTag(a0);
    444     __ Push(a2, a0);
    445 
    446     if (create_implicit_receiver) {
    447       // Try to allocate the object without transitioning into C code. If any of
    448       // the preconditions is not met, the code bails out to the runtime call.
    449       Label rt_call, allocated;
    450       if (FLAG_inline_new) {
    451         // Verify that the new target is a JSFunction.
    452         __ GetObjectType(a3, a5, a4);
    453         __ Branch(&rt_call, ne, a4, Operand(JS_FUNCTION_TYPE));
    454 
    455         // Load the initial map and verify that it is in fact a map.
    456         // a3: new target
    457         __ ld(a2,
    458               FieldMemOperand(a3, JSFunction::kPrototypeOrInitialMapOffset));
    459         __ JumpIfSmi(a2, &rt_call);
    460         __ GetObjectType(a2, t1, t0);
    461         __ Branch(&rt_call, ne, t0, Operand(MAP_TYPE));
    462 
    463         // Fall back to runtime if the expected base constructor and base
    464         // constructor differ.
    465         __ ld(a5, FieldMemOperand(a2, Map::kConstructorOrBackPointerOffset));
    466         __ Branch(&rt_call, ne, a1, Operand(a5));
    467 
    468         // Check that the constructor is not constructing a JSFunction (see
    469         // comments in Runtime_NewObject in runtime.cc). In which case the
    470         // initial map's instance type would be JS_FUNCTION_TYPE.
    471         // a1: constructor function
    472         // a2: initial map
    473         __ lbu(t1, FieldMemOperand(a2, Map::kInstanceTypeOffset));
    474         __ Branch(&rt_call, eq, t1, Operand(JS_FUNCTION_TYPE));
    475 
    476         // Now allocate the JSObject on the heap.
    477         // a1: constructor function
    478         // a2: initial map
    479         __ lbu(a4, FieldMemOperand(a2, Map::kInstanceSizeOffset));
    480         __ Allocate(a4, t0, a4, t2, &rt_call, SIZE_IN_WORDS);
    481 
    482         // Allocated the JSObject, now initialize the fields. Map is set to
    483         // initial map and properties and elements are set to empty fixed array.
    484         // a1: constructor function
    485         // a2: initial map
    486         // a3: object size
    487         // t0: JSObject (not HeapObject tagged - the actual address).
    488         // a4: start of next object
    489         __ LoadRoot(t2, Heap::kEmptyFixedArrayRootIndex);
    490         __ mov(t1, t0);
    491         STATIC_ASSERT(0 * kPointerSize == JSObject::kMapOffset);
    492         __ sd(a2, MemOperand(t1, JSObject::kMapOffset));
    493         STATIC_ASSERT(1 * kPointerSize == JSObject::kPropertiesOffset);
    494         __ sd(t2, MemOperand(t1, JSObject::kPropertiesOffset));
    495         STATIC_ASSERT(2 * kPointerSize == JSObject::kElementsOffset);
    496         __ sd(t2, MemOperand(t1, JSObject::kElementsOffset));
    497         STATIC_ASSERT(3 * kPointerSize == JSObject::kHeaderSize);
    498         __ Daddu(t1, t1, Operand(3 * kPointerSize));
    499 
    500         // Add the object tag to make the JSObject real, so that we can continue
    501         // and jump into the continuation code at any time from now on.
    502         __ Daddu(t0, t0, Operand(kHeapObjectTag));
    503 
    504         // Fill all the in-object properties with appropriate filler.
    505         // t0: JSObject (tagged)
    506         // t1: First in-object property of JSObject (not tagged)
    507         __ LoadRoot(t3, Heap::kUndefinedValueRootIndex);
    508 
    509         if (!is_api_function) {
    510           Label no_inobject_slack_tracking;
    511 
    512           MemOperand bit_field3 = FieldMemOperand(a2, Map::kBitField3Offset);
    513           // Check if slack tracking is enabled.
    514           __ lwu(t2, bit_field3);
    515           __ DecodeField<Map::ConstructionCounter>(a6, t2);
    516           // a6: slack tracking counter
    517           __ Branch(&no_inobject_slack_tracking, lt, a6,
    518                     Operand(Map::kSlackTrackingCounterEnd));
    519           // Decrease generous allocation count.
    520           __ Dsubu(t2, t2, Operand(1 << Map::ConstructionCounter::kShift));
    521           __ sw(t2, bit_field3);
    522 
    523           // Allocate object with a slack.
    524           __ lbu(a0, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset));
    525           __ dsll(a0, a0, kPointerSizeLog2);
    526           __ dsubu(a0, a4, a0);
    527           // a0: offset of first field after pre-allocated fields
    528           if (FLAG_debug_code) {
    529             __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields, t1,
    530                       Operand(a0));
    531           }
    532           __ InitializeFieldsWithFiller(t1, a0, t3);
    533 
    534           // To allow truncation fill the remaining fields with one pointer
    535           // filler map.
    536           __ LoadRoot(t3, Heap::kOnePointerFillerMapRootIndex);
    537           __ InitializeFieldsWithFiller(t1, a4, t3);
    538 
    539           // a6: slack tracking counter value before decreasing.
    540           __ Branch(&allocated, ne, a6, Operand(Map::kSlackTrackingCounterEnd));
    541 
    542           // Push the constructor, new_target and the object to the stack,
    543           // and then the initial map as an argument to the runtime call.
    544           __ Push(a1, a3, t0, a2);
    545           __ CallRuntime(Runtime::kFinalizeInstanceSize);
    546           __ Pop(a1, a3, t0);
    547 
    548           // Continue with JSObject being successfully allocated.
    549           // a1: constructor function
    550           // a3: new target
    551           // t0: JSObject
    552           __ jmp(&allocated);
    553 
    554           __ bind(&no_inobject_slack_tracking);
    555         }
    556 
    557         __ InitializeFieldsWithFiller(t1, a4, t3);
    558 
    559         // Continue with JSObject being successfully allocated.
    560         // a1: constructor function
    561         // a3: new target
    562         // t0: JSObject
    563         __ jmp(&allocated);
    564       }
    565 
    566       // Allocate the new receiver object using the runtime call.
    567       // a1: constructor function
    568       // a3: new target
    569       __ bind(&rt_call);
    570 
    571       // Push the constructor and new_target twice, second pair as arguments
    572       // to the runtime call.
    573       __ Push(a1, a3, a1, a3);  // constructor function, new target
    574       __ CallRuntime(Runtime::kNewObject);
    575       __ mov(t0, v0);
    576       __ Pop(a1, a3);
    577 
    578       // Receiver for constructor call allocated.
    579       // a1: constructor function
    580       // a3: new target
    581       // t0: JSObject
    582       __ bind(&allocated);
    583 
    584       __ ld(a0, MemOperand(sp));
    585     }
    586     __ SmiUntag(a0);
    587 
    588     if (create_implicit_receiver) {
    589       // Push the allocated receiver to the stack. We need two copies
    590       // because we may have to return the original one and the calling
    591       // conventions dictate that the called function pops the receiver.
    592       __ Push(t0, t0);
    593     } else {
    594       __ PushRoot(Heap::kTheHoleValueRootIndex);
    595     }
    596 
    597     // Set up pointer to last argument.
    598     __ Daddu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
    599 
    600     // Copy arguments and receiver to the expression stack.
    601     // a0: number of arguments
    602     // a1: constructor function
    603     // a2: address of last argument (caller sp)
    604     // a3: new target
    605     // t0: number of arguments (smi-tagged)
    606     // sp[0]: receiver
    607     // sp[1]: receiver
    608     // sp[2]: number of arguments (smi-tagged)
    609     Label loop, entry;
    610     __ mov(t0, a0);
    611     __ jmp(&entry);
    612     __ bind(&loop);
    613     __ dsll(a4, t0, kPointerSizeLog2);
    614     __ Daddu(a4, a2, Operand(a4));
    615     __ ld(a5, MemOperand(a4));
    616     __ push(a5);
    617     __ bind(&entry);
    618     __ Daddu(t0, t0, Operand(-1));
    619     __ Branch(&loop, greater_equal, t0, Operand(zero_reg));
    620 
    621     // Call the function.
    622     // a0: number of arguments
    623     // a1: constructor function
    624     // a3: new target
    625     if (is_api_function) {
    626       __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
    627       Handle<Code> code =
    628           masm->isolate()->builtins()->HandleApiCallConstruct();
    629       __ Call(code, RelocInfo::CODE_TARGET);
    630     } else {
    631       ParameterCount actual(a0);
    632       __ InvokeFunction(a1, a3, actual, CALL_FUNCTION,
    633                         CheckDebugStepCallWrapper());
    634     }
    635 
    636     // Store offset of return address for deoptimizer.
    637     if (create_implicit_receiver && !is_api_function) {
    638       masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
    639     }
    640 
    641     // Restore context from the frame.
    642     __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
    643 
    644     if (create_implicit_receiver) {
    645       // If the result is an object (in the ECMA sense), we should get rid
    646       // of the receiver and use the result; see ECMA-262 section 13.2.2-7
    647       // on page 74.
    648       Label use_receiver, exit;
    649 
    650       // If the result is a smi, it is *not* an object in the ECMA sense.
    651       // v0: result
    652       // sp[0]: receiver (newly allocated object)
    653       // sp[1]: number of arguments (smi-tagged)
    654       __ JumpIfSmi(v0, &use_receiver);
    655 
    656       // If the type of the result (stored in its map) is less than
    657       // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
    658       __ GetObjectType(v0, a1, a3);
    659       __ Branch(&exit, greater_equal, a3, Operand(FIRST_JS_RECEIVER_TYPE));
    660 
    661       // Throw away the result of the constructor invocation and use the
    662       // on-stack receiver as the result.
    663       __ bind(&use_receiver);
    664       __ ld(v0, MemOperand(sp));
    665 
    666       // Remove receiver from the stack, remove caller arguments, and
    667       // return.
    668       __ bind(&exit);
    669       // v0: result
    670       // sp[0]: receiver (newly allocated object)
    671       // sp[1]: number of arguments (smi-tagged)
    672       __ ld(a1, MemOperand(sp, 1 * kPointerSize));
    673     } else {
    674       __ ld(a1, MemOperand(sp));
    675     }
    676 
    677     // Leave construct frame.
    678   }
    679 
    680   __ SmiScale(a4, a1, kPointerSizeLog2);
    681   __ Daddu(sp, sp, a4);
    682   __ Daddu(sp, sp, kPointerSize);
    683   if (create_implicit_receiver) {
    684     __ IncrementCounter(isolate->counters()->constructed_objects(), 1, a1, a2);
    685   }
    686   __ Ret();
    687 }
    688 
    689 
    690 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
    691   Generate_JSConstructStubHelper(masm, false, true);
    692 }
    693 
    694 
    695 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
    696   Generate_JSConstructStubHelper(masm, true, true);
    697 }
    698 
    699 
    700 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
    701   Generate_JSConstructStubHelper(masm, false, false);
    702 }
    703 
    704 
    705 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
    706   FrameScope scope(masm, StackFrame::INTERNAL);
    707   __ Push(a1);
    708   __ CallRuntime(Runtime::kThrowConstructedNonConstructable);
    709 }
    710 
    711 
    712 enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt };
    713 
    714 
    715 // Clobbers a2; preserves all other registers.
    716 static void Generate_CheckStackOverflow(MacroAssembler* masm, Register argc,
    717                                         IsTagged argc_is_tagged) {
    718   // Check the stack for overflow. We are not trying to catch
    719   // interruptions (e.g. debug break and preemption) here, so the "real stack
    720   // limit" is checked.
    721   Label okay;
    722   __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
    723   // Make a2 the space we have left. The stack might already be overflowed
    724   // here which will cause r2 to become negative.
    725   __ dsubu(a2, sp, a2);
    726   // Check if the arguments will overflow the stack.
    727   if (argc_is_tagged == kArgcIsSmiTagged) {
    728     __ SmiScale(a7, v0, kPointerSizeLog2);
    729   } else {
    730     DCHECK(argc_is_tagged == kArgcIsUntaggedInt);
    731     __ dsll(a7, argc, kPointerSizeLog2);
    732   }
    733   __ Branch(&okay, gt, a2, Operand(a7));  // Signed comparison.
    734 
    735   // Out of stack space.
    736   __ CallRuntime(Runtime::kThrowStackOverflow);
    737 
    738   __ bind(&okay);
    739 }
    740 
    741 
    742 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
    743                                              bool is_construct) {
    744   // Called from JSEntryStub::GenerateBody
    745 
    746   // ----------- S t a t e -------------
    747   //  -- a0: new.target
    748   //  -- a1: function
    749   //  -- a2: receiver_pointer
    750   //  -- a3: argc
    751   //  -- s0: argv
    752   // -----------------------------------
    753   ProfileEntryHookStub::MaybeCallEntryHook(masm);
    754   // Clear the context before we push it when entering the JS frame.
    755   __ mov(cp, zero_reg);
    756 
    757   // Enter an internal frame.
    758   {
    759     FrameScope scope(masm, StackFrame::INTERNAL);
    760 
    761     // Setup the context (we need to use the caller context from the isolate).
    762     ExternalReference context_address(Isolate::kContextAddress,
    763                                       masm->isolate());
    764     __ li(cp, Operand(context_address));
    765     __ ld(cp, MemOperand(cp));
    766 
    767     // Push the function and the receiver onto the stack.
    768     __ Push(a1, a2);
    769 
    770     // Check if we have enough stack space to push all arguments.
    771     // Clobbers a2.
    772     Generate_CheckStackOverflow(masm, a3, kArgcIsUntaggedInt);
    773 
    774     // Remember new.target.
    775     __ mov(a5, a0);
    776 
    777     // Copy arguments to the stack in a loop.
    778     // a3: argc
    779     // s0: argv, i.e. points to first arg
    780     Label loop, entry;
    781     __ dsll(a4, a3, kPointerSizeLog2);
    782     __ daddu(a6, s0, a4);
    783     __ b(&entry);
    784     __ nop();   // Branch delay slot nop.
    785     // a6 points past last arg.
    786     __ bind(&loop);
    787     __ ld(a4, MemOperand(s0));  // Read next parameter.
    788     __ daddiu(s0, s0, kPointerSize);
    789     __ ld(a4, MemOperand(a4));  // Dereference handle.
    790     __ push(a4);  // Push parameter.
    791     __ bind(&entry);
    792     __ Branch(&loop, ne, s0, Operand(a6));
    793 
    794     // Setup new.target and argc.
    795     __ mov(a0, a3);
    796     __ mov(a3, a5);
    797 
    798     // Initialize all JavaScript callee-saved registers, since they will be seen
    799     // by the garbage collector as part of handlers.
    800     __ LoadRoot(a4, Heap::kUndefinedValueRootIndex);
    801     __ mov(s1, a4);
    802     __ mov(s2, a4);
    803     __ mov(s3, a4);
    804     __ mov(s4, a4);
    805     __ mov(s5, a4);
    806     // s6 holds the root address. Do not clobber.
    807     // s7 is cp. Do not init.
    808 
    809     // Invoke the code.
    810     Handle<Code> builtin = is_construct
    811                                ? masm->isolate()->builtins()->Construct()
    812                                : masm->isolate()->builtins()->Call();
    813     __ Call(builtin, RelocInfo::CODE_TARGET);
    814 
    815     // Leave internal frame.
    816   }
    817   __ Jump(ra);
    818 }
    819 
    820 
    821 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
    822   Generate_JSEntryTrampolineHelper(masm, false);
    823 }
    824 
    825 
    826 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
    827   Generate_JSEntryTrampolineHelper(masm, true);
    828 }
    829 
    830 
    831 // Generate code for entering a JS function with the interpreter.
    832 // On entry to the function the receiver and arguments have been pushed on the
    833 // stack left to right.  The actual argument count matches the formal parameter
    834 // count expected by the function.
    835 //
    836 // The live registers are:
    837 //   o a1: the JS function object being called.
    838 //   o a3: the new target
    839 //   o cp: our context
    840 //   o fp: the caller's frame pointer
    841 //   o sp: stack pointer
    842 //   o ra: return address
    843 //
    844 // The function builds a JS frame. Please see JavaScriptFrameConstants in
    845 // frames-mips.h for its layout.
    846 // TODO(rmcilroy): We will need to include the current bytecode pointer in the
    847 // frame.
    848 void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
    849   // Open a frame scope to indicate that there is a frame on the stack.  The
    850   // MANUAL indicates that the scope shouldn't actually generate code to set up
    851   // the frame (that is done below).
    852   FrameScope frame_scope(masm, StackFrame::MANUAL);
    853 
    854   __ Push(ra, fp, cp, a1);
    855   __ Daddu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
    856   __ Push(a3);
    857 
    858   // Push zero for bytecode array offset.
    859   __ Push(zero_reg);
    860 
    861   // Get the bytecode array from the function object and load the pointer to the
    862   // first entry into kInterpreterBytecodeRegister.
    863   __ ld(a0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
    864   __ ld(kInterpreterBytecodeArrayRegister,
    865         FieldMemOperand(a0, SharedFunctionInfo::kFunctionDataOffset));
    866 
    867   if (FLAG_debug_code) {
    868     // Check function data field is actually a BytecodeArray object.
    869     __ SmiTst(kInterpreterBytecodeArrayRegister, a4);
    870     __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry, a4,
    871               Operand(zero_reg));
    872     __ GetObjectType(kInterpreterBytecodeArrayRegister, a4, a4);
    873     __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry, a4,
    874               Operand(BYTECODE_ARRAY_TYPE));
    875   }
    876 
    877   // Allocate the local and temporary register file on the stack.
    878   {
    879     // Load frame size (word) from the BytecodeArray object.
    880     __ lw(a4, FieldMemOperand(kInterpreterBytecodeArrayRegister,
    881                               BytecodeArray::kFrameSizeOffset));
    882 
    883     // Do a stack check to ensure we don't go over the limit.
    884     Label ok;
    885     __ Dsubu(a5, sp, Operand(a4));
    886     __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
    887     __ Branch(&ok, hs, a5, Operand(a2));
    888     __ CallRuntime(Runtime::kThrowStackOverflow);
    889     __ bind(&ok);
    890 
    891     // If ok, push undefined as the initial value for all register file entries.
    892     Label loop_header;
    893     Label loop_check;
    894     __ LoadRoot(a5, Heap::kUndefinedValueRootIndex);
    895     __ Branch(&loop_check);
    896     __ bind(&loop_header);
    897     // TODO(rmcilroy): Consider doing more than one push per loop iteration.
    898     __ push(a5);
    899     // Continue loop if not done.
    900     __ bind(&loop_check);
    901     __ Dsubu(a4, a4, Operand(kPointerSize));
    902     __ Branch(&loop_header, ge, a4, Operand(zero_reg));
    903   }
    904 
    905   // TODO(rmcilroy): List of things not currently dealt with here but done in
    906   // fullcodegen's prologue:
    907   //  - Support profiler (specifically profiling_counter).
    908   //  - Call ProfileEntryHookStub when isolate has a function_entry_hook.
    909   //  - Allow simulator stop operations if FLAG_stop_at is set.
    910   //  - Code aging of the BytecodeArray object.
    911 
    912   // Perform stack guard check.
    913   {
    914     Label ok;
    915     __ LoadRoot(at, Heap::kStackLimitRootIndex);
    916     __ Branch(&ok, hs, sp, Operand(at));
    917     __ push(kInterpreterBytecodeArrayRegister);
    918     __ CallRuntime(Runtime::kStackGuard);
    919     __ pop(kInterpreterBytecodeArrayRegister);
    920     __ bind(&ok);
    921   }
    922 
    923   // Load bytecode offset and dispatch table into registers.
    924   __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
    925   __ Daddu(kInterpreterRegisterFileRegister, fp,
    926            Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
    927   __ li(kInterpreterBytecodeOffsetRegister,
    928         Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
    929   __ LoadRoot(kInterpreterDispatchTableRegister,
    930               Heap::kInterpreterTableRootIndex);
    931   __ Daddu(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
    932            Operand(FixedArray::kHeaderSize - kHeapObjectTag));
    933 
    934   // Dispatch to the first bytecode handler for the function.
    935   __ Daddu(a0, kInterpreterBytecodeArrayRegister,
    936            kInterpreterBytecodeOffsetRegister);
    937   __ lbu(a0, MemOperand(a0));
    938   __ dsll(at, a0, kPointerSizeLog2);
    939   __ Daddu(at, kInterpreterDispatchTableRegister, at);
    940   __ ld(at, MemOperand(at));
    941   // TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging
    942   // and header removal.
    943   __ Daddu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag));
    944   __ Call(at);
    945 }
    946 
    947 
    948 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
    949   // TODO(rmcilroy): List of things not currently dealt with here but done in
    950   // fullcodegen's EmitReturnSequence.
    951   //  - Supporting FLAG_trace for Runtime::TraceExit.
    952   //  - Support profiler (specifically decrementing profiling_counter
    953   //    appropriately and calling out to HandleInterrupts if necessary).
    954 
    955   // The return value is in accumulator, which is already in v0.
    956 
    957   // Leave the frame (also dropping the register file).
    958   __ LeaveFrame(StackFrame::JAVA_SCRIPT);
    959 
    960   // Drop receiver + arguments and return.
    961   __ lw(at, FieldMemOperand(kInterpreterBytecodeArrayRegister,
    962                             BytecodeArray::kParameterSizeOffset));
    963   __ Daddu(sp, sp, at);
    964   __ Jump(ra);
    965 }
    966 
    967 
    968 // static
    969 void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
    970   // ----------- S t a t e -------------
    971   //  -- a0 : the number of arguments (not including the receiver)
    972   //  -- a2 : the address of the first argument to be pushed. Subsequent
    973   //          arguments should be consecutive above this, in the same order as
    974   //          they are to be pushed onto the stack.
    975   //  -- a1 : the target to call (can be any Object).
    976   // -----------------------------------
    977 
    978   // Find the address of the last argument.
    979   __ Daddu(a3, a0, Operand(1));  // Add one for receiver.
    980   __ dsll(a3, a3, kPointerSizeLog2);
    981   __ Dsubu(a3, a2, Operand(a3));
    982 
    983   // Push the arguments.
    984   Label loop_header, loop_check;
    985   __ Branch(&loop_check);
    986   __ bind(&loop_header);
    987   __ ld(t0, MemOperand(a2));
    988   __ Daddu(a2, a2, Operand(-kPointerSize));
    989   __ push(t0);
    990   __ bind(&loop_check);
    991   __ Branch(&loop_header, gt, a2, Operand(a3));
    992 
    993   // Call the target.
    994   __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
    995 }
    996 
    997 
    998 // static
    999 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
   1000   // ----------- S t a t e -------------
   1001   // -- a0 : argument count (not including receiver)
   1002   // -- a3 : new target
   1003   // -- a1 : constructor to call
   1004   // -- a2 : address of the first argument
   1005   // -----------------------------------
   1006 
   1007   // Find the address of the last argument.
   1008   __ dsll(t0, a0, kPointerSizeLog2);
   1009   __ Dsubu(t0, a2, Operand(t0));
   1010 
   1011   // Push a slot for the receiver.
   1012   __ push(zero_reg);
   1013 
   1014   // Push the arguments.
   1015   Label loop_header, loop_check;
   1016   __ Branch(&loop_check);
   1017   __ bind(&loop_header);
   1018   __ ld(t1, MemOperand(a2));
   1019   __ Daddu(a2, a2, Operand(-kPointerSize));
   1020   __ push(t1);
   1021   __ bind(&loop_check);
   1022   __ Branch(&loop_header, gt, a2, Operand(t0));
   1023 
   1024   // Call the constructor with a0, a1, and a3 unmodified.
   1025   __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
   1026 }
   1027 
   1028 
   1029 static void Generate_InterpreterNotifyDeoptimizedHelper(
   1030     MacroAssembler* masm, Deoptimizer::BailoutType type) {
   1031   // Enter an internal frame.
   1032   {
   1033     FrameScope scope(masm, StackFrame::INTERNAL);
   1034     __ push(kInterpreterAccumulatorRegister);  // Save accumulator register.
   1035 
   1036     // Pass the deoptimization type to the runtime system.
   1037     __ li(a1, Operand(Smi::FromInt(static_cast<int>(type))));
   1038     __ push(a1);
   1039     __ CallRuntime(Runtime::kNotifyDeoptimized);
   1040 
   1041     __ pop(kInterpreterAccumulatorRegister);  // Restore accumulator register.
   1042     // Tear down internal frame.
   1043   }
   1044 
   1045   // Drop state (we don't use this for interpreter deopts).
   1046   __ Drop(1);
   1047 
   1048   // Initialize register file register and dispatch table register.
   1049   __ Daddu(kInterpreterRegisterFileRegister, fp,
   1050            Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
   1051   __ LoadRoot(kInterpreterDispatchTableRegister,
   1052               Heap::kInterpreterTableRootIndex);
   1053   __ Daddu(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
   1054            Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   1055 
   1056   // Get the context from the frame.
   1057   // TODO(rmcilroy): Update interpreter frame to expect current context at the
   1058   // context slot instead of the function context.
   1059   __ ld(kContextRegister,
   1060         MemOperand(kInterpreterRegisterFileRegister,
   1061                    InterpreterFrameConstants::kContextFromRegisterPointer));
   1062 
   1063   // Get the bytecode array pointer from the frame.
   1064   __ ld(a1,
   1065         MemOperand(kInterpreterRegisterFileRegister,
   1066                    InterpreterFrameConstants::kFunctionFromRegisterPointer));
   1067   __ ld(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
   1068   __ ld(kInterpreterBytecodeArrayRegister,
   1069         FieldMemOperand(a1, SharedFunctionInfo::kFunctionDataOffset));
   1070 
   1071   if (FLAG_debug_code) {
   1072     // Check function data field is actually a BytecodeArray object.
   1073     __ SmiTst(kInterpreterBytecodeArrayRegister, at);
   1074     __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry, at,
   1075               Operand(zero_reg));
   1076     __ GetObjectType(kInterpreterBytecodeArrayRegister, a1, a1);
   1077     __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry, a1,
   1078               Operand(BYTECODE_ARRAY_TYPE));
   1079   }
   1080 
   1081   // Get the target bytecode offset from the frame.
   1082   __ ld(kInterpreterBytecodeOffsetRegister,
   1083         MemOperand(
   1084             kInterpreterRegisterFileRegister,
   1085             InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer));
   1086   __ SmiUntag(kInterpreterBytecodeOffsetRegister);
   1087 
   1088   // Dispatch to the target bytecode.
   1089   __ Daddu(a1, kInterpreterBytecodeArrayRegister,
   1090            kInterpreterBytecodeOffsetRegister);
   1091   __ lbu(a1, MemOperand(a1));
   1092   __ dsll(a1, a1, kPointerSizeLog2);
   1093   __ Daddu(a1, kInterpreterDispatchTableRegister, a1);
   1094   __ ld(a1, MemOperand(a1));
   1095   __ Daddu(a1, a1, Operand(Code::kHeaderSize - kHeapObjectTag));
   1096   __ Jump(a1);
   1097 }
   1098 
   1099 
   1100 void Builtins::Generate_InterpreterNotifyDeoptimized(MacroAssembler* masm) {
   1101   Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
   1102 }
   1103 
   1104 
   1105 void Builtins::Generate_InterpreterNotifySoftDeoptimized(MacroAssembler* masm) {
   1106   Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
   1107 }
   1108 
   1109 
   1110 void Builtins::Generate_InterpreterNotifyLazyDeoptimized(MacroAssembler* masm) {
   1111   Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
   1112 }
   1113 
   1114 
   1115 void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
   1116   CallRuntimePassFunction(masm, Runtime::kCompileLazy);
   1117   GenerateTailCallToReturnedCode(masm);
   1118 }
   1119 
   1120 
   1121 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) {
   1122   CallRuntimePassFunction(masm, Runtime::kCompileOptimized_NotConcurrent);
   1123   GenerateTailCallToReturnedCode(masm);
   1124 }
   1125 
   1126 
   1127 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
   1128   CallRuntimePassFunction(masm, Runtime::kCompileOptimized_Concurrent);
   1129   GenerateTailCallToReturnedCode(masm);
   1130 }
   1131 
   1132 
   1133 static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
   1134   // For now, we are relying on the fact that make_code_young doesn't do any
   1135   // garbage collection which allows us to save/restore the registers without
   1136   // worrying about which of them contain pointers. We also don't build an
   1137   // internal frame to make the code faster, since we shouldn't have to do stack
   1138   // crawls in MakeCodeYoung. This seems a bit fragile.
   1139 
   1140   // Set a0 to point to the head of the PlatformCodeAge sequence.
   1141   __ Dsubu(a0, a0,
   1142       Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize));
   1143 
   1144   // The following registers must be saved and restored when calling through to
   1145   // the runtime:
   1146   //   a0 - contains return address (beginning of patch sequence)
   1147   //   a1 - isolate
   1148   //   a3 - new target
   1149   RegList saved_regs =
   1150       (a0.bit() | a1.bit() | a3.bit() | ra.bit() | fp.bit()) & ~sp.bit();
   1151   FrameScope scope(masm, StackFrame::MANUAL);
   1152   __ MultiPush(saved_regs);
   1153   __ PrepareCallCFunction(2, 0, a2);
   1154   __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate())));
   1155   __ CallCFunction(
   1156       ExternalReference::get_make_code_young_function(masm->isolate()), 2);
   1157   __ MultiPop(saved_regs);
   1158   __ Jump(a0);
   1159 }
   1160 
   1161 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C)                 \
   1162 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking(  \
   1163     MacroAssembler* masm) {                                  \
   1164   GenerateMakeCodeYoungAgainCommon(masm);                    \
   1165 }                                                            \
   1166 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking(   \
   1167     MacroAssembler* masm) {                                  \
   1168   GenerateMakeCodeYoungAgainCommon(masm);                    \
   1169 }
   1170 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR)
   1171 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
   1172 
   1173 
   1174 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
   1175   // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact
   1176   // that make_code_young doesn't do any garbage collection which allows us to
   1177   // save/restore the registers without worrying about which of them contain
   1178   // pointers.
   1179 
   1180   // Set a0 to point to the head of the PlatformCodeAge sequence.
   1181   __ Dsubu(a0, a0,
   1182       Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize));
   1183 
   1184   // The following registers must be saved and restored when calling through to
   1185   // the runtime:
   1186   //   a0 - contains return address (beginning of patch sequence)
   1187   //   a1 - isolate
   1188   //   a3 - new target
   1189   RegList saved_regs =
   1190       (a0.bit() | a1.bit() | a3.bit() | ra.bit() | fp.bit()) & ~sp.bit();
   1191   FrameScope scope(masm, StackFrame::MANUAL);
   1192   __ MultiPush(saved_regs);
   1193   __ PrepareCallCFunction(2, 0, a2);
   1194   __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate())));
   1195   __ CallCFunction(
   1196       ExternalReference::get_mark_code_as_executed_function(masm->isolate()),
   1197       2);
   1198   __ MultiPop(saved_regs);
   1199 
   1200   // Perform prologue operations usually performed by the young code stub.
   1201   __ Push(ra, fp, cp, a1);
   1202   __ Daddu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
   1203 
   1204   // Jump to point after the code-age stub.
   1205   __ Daddu(a0, a0, Operand((kNoCodeAgeSequenceLength)));
   1206   __ Jump(a0);
   1207 }
   1208 
   1209 
   1210 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
   1211   GenerateMakeCodeYoungAgainCommon(masm);
   1212 }
   1213 
   1214 
   1215 void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
   1216   Generate_MarkCodeAsExecutedOnce(masm);
   1217 }
   1218 
   1219 
   1220 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
   1221                                              SaveFPRegsMode save_doubles) {
   1222   {
   1223     FrameScope scope(masm, StackFrame::INTERNAL);
   1224 
   1225     // Preserve registers across notification, this is important for compiled
   1226     // stubs that tail call the runtime on deopts passing their parameters in
   1227     // registers.
   1228     __ MultiPush(kJSCallerSaved | kCalleeSaved);
   1229     // Pass the function and deoptimization type to the runtime system.
   1230     __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles);
   1231     __ MultiPop(kJSCallerSaved | kCalleeSaved);
   1232   }
   1233 
   1234   __ Daddu(sp, sp, Operand(kPointerSize));  // Ignore state
   1235   __ Jump(ra);  // Jump to miss handler
   1236 }
   1237 
   1238 
   1239 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
   1240   Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs);
   1241 }
   1242 
   1243 
   1244 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
   1245   Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
   1246 }
   1247 
   1248 
   1249 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
   1250                                              Deoptimizer::BailoutType type) {
   1251   {
   1252     FrameScope scope(masm, StackFrame::INTERNAL);
   1253     // Pass the function and deoptimization type to the runtime system.
   1254     __ li(a0, Operand(Smi::FromInt(static_cast<int>(type))));
   1255     __ push(a0);
   1256     __ CallRuntime(Runtime::kNotifyDeoptimized);
   1257   }
   1258 
   1259   // Get the full codegen state from the stack and untag it -> a6.
   1260   __ ld(a6, MemOperand(sp, 0 * kPointerSize));
   1261   __ SmiUntag(a6);
   1262   // Switch on the state.
   1263   Label with_tos_register, unknown_state;
   1264   __ Branch(&with_tos_register,
   1265             ne, a6, Operand(FullCodeGenerator::NO_REGISTERS));
   1266   __ Ret(USE_DELAY_SLOT);
   1267   // Safe to fill delay slot Addu will emit one instruction.
   1268   __ Daddu(sp, sp, Operand(1 * kPointerSize));  // Remove state.
   1269 
   1270   __ bind(&with_tos_register);
   1271   __ ld(v0, MemOperand(sp, 1 * kPointerSize));
   1272   __ Branch(&unknown_state, ne, a6, Operand(FullCodeGenerator::TOS_REG));
   1273 
   1274   __ Ret(USE_DELAY_SLOT);
   1275   // Safe to fill delay slot Addu will emit one instruction.
   1276   __ Daddu(sp, sp, Operand(2 * kPointerSize));  // Remove state.
   1277 
   1278   __ bind(&unknown_state);
   1279   __ stop("no cases left");
   1280 }
   1281 
   1282 
   1283 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
   1284   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
   1285 }
   1286 
   1287 
   1288 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) {
   1289   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
   1290 }
   1291 
   1292 
   1293 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
   1294   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
   1295 }
   1296 
   1297 
   1298 // Clobbers {t2, t3, a4, a5}.
   1299 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver,
   1300                                     Register function_template_info,
   1301                                     Label* receiver_check_failed) {
   1302   Register signature = t2;
   1303   Register map = t3;
   1304   Register constructor = a4;
   1305   Register scratch = a5;
   1306 
   1307   // If there is no signature, return the holder.
   1308   __ ld(signature, FieldMemOperand(function_template_info,
   1309                                    FunctionTemplateInfo::kSignatureOffset));
   1310   Label receiver_check_passed;
   1311   __ JumpIfRoot(signature, Heap::kUndefinedValueRootIndex,
   1312                 &receiver_check_passed);
   1313 
   1314   // Walk the prototype chain.
   1315   __ ld(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
   1316   Label prototype_loop_start;
   1317   __ bind(&prototype_loop_start);
   1318 
   1319   // Get the constructor, if any.
   1320   __ GetMapConstructor(constructor, map, scratch, scratch);
   1321   Label next_prototype;
   1322   __ Branch(&next_prototype, ne, scratch, Operand(JS_FUNCTION_TYPE));
   1323   Register type = constructor;
   1324   __ ld(type,
   1325         FieldMemOperand(constructor, JSFunction::kSharedFunctionInfoOffset));
   1326   __ ld(type, FieldMemOperand(type, SharedFunctionInfo::kFunctionDataOffset));
   1327 
   1328   // Loop through the chain of inheriting function templates.
   1329   Label function_template_loop;
   1330   __ bind(&function_template_loop);
   1331 
   1332   // If the signatures match, we have a compatible receiver.
   1333   __ Branch(&receiver_check_passed, eq, signature, Operand(type),
   1334             USE_DELAY_SLOT);
   1335 
   1336   // If the current type is not a FunctionTemplateInfo, load the next prototype
   1337   // in the chain.
   1338   __ JumpIfSmi(type, &next_prototype);
   1339   __ GetObjectType(type, scratch, scratch);
   1340   __ Branch(&next_prototype, ne, scratch, Operand(FUNCTION_TEMPLATE_INFO_TYPE));
   1341 
   1342   // Otherwise load the parent function template and iterate.
   1343   __ ld(type,
   1344         FieldMemOperand(type, FunctionTemplateInfo::kParentTemplateOffset));
   1345   __ Branch(&function_template_loop);
   1346 
   1347   // Load the next prototype.
   1348   __ bind(&next_prototype);
   1349   __ ld(receiver, FieldMemOperand(map, Map::kPrototypeOffset));
   1350   // End if the prototype is null or not hidden.
   1351   __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, receiver_check_failed);
   1352   __ ld(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
   1353   __ lwu(scratch, FieldMemOperand(map, Map::kBitField3Offset));
   1354   __ DecodeField<Map::IsHiddenPrototype>(scratch);
   1355   __ Branch(receiver_check_failed, eq, scratch, Operand(zero_reg));
   1356   // Iterate.
   1357   __ Branch(&prototype_loop_start);
   1358 
   1359   __ bind(&receiver_check_passed);
   1360 }
   1361 
   1362 
   1363 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) {
   1364   // ----------- S t a t e -------------
   1365   //  -- a0                 : number of arguments excluding receiver
   1366   //  -- a1                 : callee
   1367   //  -- ra                 : return address
   1368   //  -- sp[0]              : last argument
   1369   //  -- ...
   1370   //  -- sp[8 * (argc - 1)] : first argument
   1371   //  -- sp[8 * argc]       : receiver
   1372   // -----------------------------------
   1373 
   1374   // Load the FunctionTemplateInfo.
   1375   __ ld(t1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
   1376   __ ld(t1, FieldMemOperand(t1, SharedFunctionInfo::kFunctionDataOffset));
   1377 
   1378   // Do the compatible receiver check
   1379   Label receiver_check_failed;
   1380   __ sll(at, a0, kPointerSizeLog2);
   1381   __ Daddu(t8, sp, at);
   1382   __ ld(t0, MemOperand(t8));
   1383   CompatibleReceiverCheck(masm, t0, t1, &receiver_check_failed);
   1384 
   1385   // Get the callback offset from the FunctionTemplateInfo, and jump to the
   1386   // beginning of the code.
   1387   __ ld(t2, FieldMemOperand(t1, FunctionTemplateInfo::kCallCodeOffset));
   1388   __ ld(t2, FieldMemOperand(t2, CallHandlerInfo::kFastHandlerOffset));
   1389   __ Daddu(t2, t2, Operand(Code::kHeaderSize - kHeapObjectTag));
   1390   __ Jump(t2);
   1391 
   1392   // Compatible receiver check failed: throw an Illegal Invocation exception.
   1393   __ bind(&receiver_check_failed);
   1394   // Drop the arguments (including the receiver);
   1395   __ Daddu(t8, t8, Operand(kPointerSize));
   1396   __ daddu(sp, t8, zero_reg);
   1397   __ TailCallRuntime(Runtime::kThrowIllegalInvocation);
   1398 }
   1399 
   1400 
   1401 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
   1402   // Lookup the function in the JavaScript frame.
   1403   __ ld(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
   1404   {
   1405     FrameScope scope(masm, StackFrame::INTERNAL);
   1406     // Pass function as argument.
   1407     __ push(a0);
   1408     __ CallRuntime(Runtime::kCompileForOnStackReplacement);
   1409   }
   1410 
   1411   // If the code object is null, just return to the unoptimized code.
   1412   __ Ret(eq, v0, Operand(Smi::FromInt(0)));
   1413 
   1414   // Load deoptimization data from the code object.
   1415   // <deopt_data> = <code>[#deoptimization_data_offset]
   1416   __ ld(a1, MemOperand(v0, Code::kDeoptimizationDataOffset - kHeapObjectTag));
   1417 
   1418   // Load the OSR entrypoint offset from the deoptimization data.
   1419   // <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset]
   1420   __ ld(a1, MemOperand(a1, FixedArray::OffsetOfElementAt(
   1421       DeoptimizationInputData::kOsrPcOffsetIndex) - kHeapObjectTag));
   1422   __ SmiUntag(a1);
   1423 
   1424   // Compute the target address = code_obj + header_size + osr_offset
   1425   // <entry_addr> = <code_obj> + #header_size + <osr_offset>
   1426   __ daddu(v0, v0, a1);
   1427   __ daddiu(ra, v0, Code::kHeaderSize - kHeapObjectTag);
   1428 
   1429   // And "return" to the OSR entry point of the function.
   1430   __ Ret();
   1431 }
   1432 
   1433 
   1434 void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) {
   1435   // We check the stack limit as indicator that recompilation might be done.
   1436   Label ok;
   1437   __ LoadRoot(at, Heap::kStackLimitRootIndex);
   1438   __ Branch(&ok, hs, sp, Operand(at));
   1439   {
   1440     FrameScope scope(masm, StackFrame::INTERNAL);
   1441     __ CallRuntime(Runtime::kStackGuard);
   1442   }
   1443   __ Jump(masm->isolate()->builtins()->OnStackReplacement(),
   1444           RelocInfo::CODE_TARGET);
   1445 
   1446   __ bind(&ok);
   1447   __ Ret();
   1448 }
   1449 
   1450 
   1451 // static
   1452 void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
   1453                                                int field_index) {
   1454   // ----------- S t a t e -------------
   1455   //  -- sp[0] : receiver
   1456   // -----------------------------------
   1457 
   1458   // 1. Pop receiver into a0 and check that it's actually a JSDate object.
   1459   Label receiver_not_date;
   1460   {
   1461     __ Pop(a0);
   1462     __ JumpIfSmi(a0, &receiver_not_date);
   1463     __ GetObjectType(a0, t0, t0);
   1464     __ Branch(&receiver_not_date, ne, t0, Operand(JS_DATE_TYPE));
   1465   }
   1466 
   1467   // 2. Load the specified date field, falling back to the runtime as necessary.
   1468   if (field_index == JSDate::kDateValue) {
   1469     __ Ret(USE_DELAY_SLOT);
   1470     __ ld(v0, FieldMemOperand(a0, JSDate::kValueOffset));  // In delay slot.
   1471   } else {
   1472     if (field_index < JSDate::kFirstUncachedField) {
   1473       Label stamp_mismatch;
   1474       __ li(a1, Operand(ExternalReference::date_cache_stamp(masm->isolate())));
   1475       __ ld(a1, MemOperand(a1));
   1476       __ ld(t0, FieldMemOperand(a0, JSDate::kCacheStampOffset));
   1477       __ Branch(&stamp_mismatch, ne, t0, Operand(a1));
   1478       __ Ret(USE_DELAY_SLOT);
   1479       __ ld(v0, FieldMemOperand(
   1480                     a0, JSDate::kValueOffset +
   1481                             field_index * kPointerSize));  // In delay slot.
   1482       __ bind(&stamp_mismatch);
   1483     }
   1484     FrameScope scope(masm, StackFrame::INTERNAL);
   1485     __ PrepareCallCFunction(2, t0);
   1486     __ li(a1, Operand(Smi::FromInt(field_index)));
   1487     __ CallCFunction(
   1488         ExternalReference::get_date_field_function(masm->isolate()), 2);
   1489   }
   1490   __ Ret();
   1491 
   1492   // 3. Raise a TypeError if the receiver is not a date.
   1493   __ bind(&receiver_not_date);
   1494   __ TailCallRuntime(Runtime::kThrowNotDateError);
   1495 }
   1496 
   1497 
   1498 // static
   1499 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
   1500   // ----------- S t a t e -------------
   1501   //  -- a0    : argc
   1502   //  -- sp[0] : argArray
   1503   //  -- sp[4] : thisArg
   1504   //  -- sp[8] : receiver
   1505   // -----------------------------------
   1506 
   1507   // 1. Load receiver into a1, argArray into a0 (if present), remove all
   1508   // arguments from the stack (including the receiver), and push thisArg (if
   1509   // present) instead.
   1510   {
   1511     Label no_arg;
   1512     Register scratch = a4;
   1513     __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
   1514     __ mov(a3, a2);
   1515     __ dsll(scratch, a0, kPointerSizeLog2);
   1516     __ Daddu(a0, sp, Operand(scratch));
   1517     __ ld(a1, MemOperand(a0));  // receiver
   1518     __ Dsubu(a0, a0, Operand(kPointerSize));
   1519     __ Branch(&no_arg, lt, a0, Operand(sp));
   1520     __ ld(a2, MemOperand(a0));  // thisArg
   1521     __ Dsubu(a0, a0, Operand(kPointerSize));
   1522     __ Branch(&no_arg, lt, a0, Operand(sp));
   1523     __ ld(a3, MemOperand(a0));  // argArray
   1524     __ bind(&no_arg);
   1525     __ Daddu(sp, sp, Operand(scratch));
   1526     __ sd(a2, MemOperand(sp));
   1527     __ mov(a0, a3);
   1528   }
   1529 
   1530   // ----------- S t a t e -------------
   1531   //  -- a0    : argArray
   1532   //  -- a1    : receiver
   1533   //  -- sp[0] : thisArg
   1534   // -----------------------------------
   1535 
   1536   // 2. Make sure the receiver is actually callable.
   1537   Label receiver_not_callable;
   1538   __ JumpIfSmi(a1, &receiver_not_callable);
   1539   __ ld(a4, FieldMemOperand(a1, HeapObject::kMapOffset));
   1540   __ lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset));
   1541   __ And(a4, a4, Operand(1 << Map::kIsCallable));
   1542   __ Branch(&receiver_not_callable, eq, a4, Operand(zero_reg));
   1543 
   1544   // 3. Tail call with no arguments if argArray is null or undefined.
   1545   Label no_arguments;
   1546   __ JumpIfRoot(a0, Heap::kNullValueRootIndex, &no_arguments);
   1547   __ JumpIfRoot(a0, Heap::kUndefinedValueRootIndex, &no_arguments);
   1548 
   1549   // 4a. Apply the receiver to the given argArray (passing undefined for
   1550   // new.target).
   1551   __ LoadRoot(a3, Heap::kUndefinedValueRootIndex);
   1552   __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
   1553 
   1554   // 4b. The argArray is either null or undefined, so we tail call without any
   1555   // arguments to the receiver.
   1556   __ bind(&no_arguments);
   1557   {
   1558     __ mov(a0, zero_reg);
   1559     __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
   1560   }
   1561 
   1562   // 4c. The receiver is not callable, throw an appropriate TypeError.
   1563   __ bind(&receiver_not_callable);
   1564   {
   1565     __ sd(a1, MemOperand(sp));
   1566     __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
   1567   }
   1568 }
   1569 
   1570 
   1571 // static
   1572 void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) {
   1573   // 1. Make sure we have at least one argument.
   1574   // a0: actual number of arguments
   1575   {
   1576     Label done;
   1577     __ Branch(&done, ne, a0, Operand(zero_reg));
   1578     __ PushRoot(Heap::kUndefinedValueRootIndex);
   1579     __ Daddu(a0, a0, Operand(1));
   1580     __ bind(&done);
   1581   }
   1582 
   1583   // 2. Get the function to call (passed as receiver) from the stack.
   1584   // a0: actual number of arguments
   1585   __ dsll(at, a0, kPointerSizeLog2);
   1586   __ daddu(at, sp, at);
   1587   __ ld(a1, MemOperand(at));
   1588 
   1589   // 3. Shift arguments and return address one slot down on the stack
   1590   //    (overwriting the original receiver).  Adjust argument count to make
   1591   //    the original first argument the new receiver.
   1592   // a0: actual number of arguments
   1593   // a1: function
   1594   {
   1595     Label loop;
   1596     // Calculate the copy start address (destination). Copy end address is sp.
   1597     __ dsll(at, a0, kPointerSizeLog2);
   1598     __ daddu(a2, sp, at);
   1599 
   1600     __ bind(&loop);
   1601     __ ld(at, MemOperand(a2, -kPointerSize));
   1602     __ sd(at, MemOperand(a2));
   1603     __ Dsubu(a2, a2, Operand(kPointerSize));
   1604     __ Branch(&loop, ne, a2, Operand(sp));
   1605     // Adjust the actual number of arguments and remove the top element
   1606     // (which is a copy of the last argument).
   1607     __ Dsubu(a0, a0, Operand(1));
   1608     __ Pop();
   1609   }
   1610 
   1611   // 4. Call the callable.
   1612   __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
   1613 }
   1614 
   1615 
   1616 void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
   1617   // ----------- S t a t e -------------
   1618   //  -- a0     : argc
   1619   //  -- sp[0]  : argumentsList
   1620   //  -- sp[4]  : thisArgument
   1621   //  -- sp[8]  : target
   1622   //  -- sp[12] : receiver
   1623   // -----------------------------------
   1624 
   1625   // 1. Load target into a1 (if present), argumentsList into a0 (if present),
   1626   // remove all arguments from the stack (including the receiver), and push
   1627   // thisArgument (if present) instead.
   1628   {
   1629     Label no_arg;
   1630     Register scratch = a4;
   1631     __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
   1632     __ mov(a2, a1);
   1633     __ mov(a3, a1);
   1634     __ dsll(scratch, a0, kPointerSizeLog2);
   1635     __ mov(a0, scratch);
   1636     __ Dsubu(a0, a0, Operand(kPointerSize));
   1637     __ Branch(&no_arg, lt, a0, Operand(zero_reg));
   1638     __ Daddu(a0, sp, Operand(a0));
   1639     __ ld(a1, MemOperand(a0));  // target
   1640     __ Dsubu(a0, a0, Operand(kPointerSize));
   1641     __ Branch(&no_arg, lt, a0, Operand(sp));
   1642     __ ld(a2, MemOperand(a0));  // thisArgument
   1643     __ Dsubu(a0, a0, Operand(kPointerSize));
   1644     __ Branch(&no_arg, lt, a0, Operand(sp));
   1645     __ ld(a3, MemOperand(a0));  // argumentsList
   1646     __ bind(&no_arg);
   1647     __ Daddu(sp, sp, Operand(scratch));
   1648     __ sd(a2, MemOperand(sp));
   1649     __ mov(a0, a3);
   1650   }
   1651 
   1652   // ----------- S t a t e -------------
   1653   //  -- a0    : argumentsList
   1654   //  -- a1    : target
   1655   //  -- sp[0] : thisArgument
   1656   // -----------------------------------
   1657 
   1658   // 2. Make sure the target is actually callable.
   1659   Label target_not_callable;
   1660   __ JumpIfSmi(a1, &target_not_callable);
   1661   __ ld(a4, FieldMemOperand(a1, HeapObject::kMapOffset));
   1662   __ lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset));
   1663   __ And(a4, a4, Operand(1 << Map::kIsCallable));
   1664   __ Branch(&target_not_callable, eq, a4, Operand(zero_reg));
   1665 
   1666   // 3a. Apply the target to the given argumentsList (passing undefined for
   1667   // new.target).
   1668   __ LoadRoot(a3, Heap::kUndefinedValueRootIndex);
   1669   __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
   1670 
   1671   // 3b. The target is not callable, throw an appropriate TypeError.
   1672   __ bind(&target_not_callable);
   1673   {
   1674     __ sd(a1, MemOperand(sp));
   1675     __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
   1676   }
   1677 }
   1678 
   1679 
   1680 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
   1681   // ----------- S t a t e -------------
   1682   //  -- a0     : argc
   1683   //  -- sp[0]  : new.target (optional)
   1684   //  -- sp[4]  : argumentsList
   1685   //  -- sp[8]  : target
   1686   //  -- sp[12] : receiver
   1687   // -----------------------------------
   1688 
   1689   // 1. Load target into a1 (if present), argumentsList into a0 (if present),
   1690   // new.target into a3 (if present, otherwise use target), remove all
   1691   // arguments from the stack (including the receiver), and push thisArgument
   1692   // (if present) instead.
   1693   {
   1694     Label no_arg;
   1695     Register scratch = a4;
   1696     __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
   1697     __ mov(a2, a1);
   1698     __ dsll(scratch, a0, kPointerSizeLog2);
   1699     __ Daddu(a0, sp, Operand(scratch));
   1700     __ sd(a2, MemOperand(a0));  // receiver
   1701     __ Dsubu(a0, a0, Operand(kPointerSize));
   1702     __ Branch(&no_arg, lt, a0, Operand(sp));
   1703     __ ld(a1, MemOperand(a0));  // target
   1704     __ mov(a3, a1);             // new.target defaults to target
   1705     __ Dsubu(a0, a0, Operand(kPointerSize));
   1706     __ Branch(&no_arg, lt, a0, Operand(sp));
   1707     __ ld(a2, MemOperand(a0));  // argumentsList
   1708     __ Dsubu(a0, a0, Operand(kPointerSize));
   1709     __ Branch(&no_arg, lt, a0, Operand(sp));
   1710     __ ld(a3, MemOperand(a0));  // new.target
   1711     __ bind(&no_arg);
   1712     __ Daddu(sp, sp, Operand(scratch));
   1713     __ mov(a0, a2);
   1714   }
   1715 
   1716   // ----------- S t a t e -------------
   1717   //  -- a0    : argumentsList
   1718   //  -- a3    : new.target
   1719   //  -- a1    : target
   1720   //  -- sp[0] : receiver (undefined)
   1721   // -----------------------------------
   1722 
   1723   // 2. Make sure the target is actually a constructor.
   1724   Label target_not_constructor;
   1725   __ JumpIfSmi(a1, &target_not_constructor);
   1726   __ ld(a4, FieldMemOperand(a1, HeapObject::kMapOffset));
   1727   __ lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset));
   1728   __ And(a4, a4, Operand(1 << Map::kIsConstructor));
   1729   __ Branch(&target_not_constructor, eq, a4, Operand(zero_reg));
   1730 
   1731   // 3. Make sure the target is actually a constructor.
   1732   Label new_target_not_constructor;
   1733   __ JumpIfSmi(a3, &new_target_not_constructor);
   1734   __ ld(a4, FieldMemOperand(a3, HeapObject::kMapOffset));
   1735   __ lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset));
   1736   __ And(a4, a4, Operand(1 << Map::kIsConstructor));
   1737   __ Branch(&new_target_not_constructor, eq, a4, Operand(zero_reg));
   1738 
   1739   // 4a. Construct the target with the given new.target and argumentsList.
   1740   __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
   1741 
   1742   // 4b. The target is not a constructor, throw an appropriate TypeError.
   1743   __ bind(&target_not_constructor);
   1744   {
   1745     __ sd(a1, MemOperand(sp));
   1746     __ TailCallRuntime(Runtime::kThrowCalledNonCallable);
   1747   }
   1748 
   1749   // 4c. The new.target is not a constructor, throw an appropriate TypeError.
   1750   __ bind(&new_target_not_constructor);
   1751   {
   1752     __ sd(a3, MemOperand(sp));
   1753     __ TailCallRuntime(Runtime::kThrowCalledNonCallable);
   1754   }
   1755 }
   1756 
   1757 
   1758 static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
   1759                                       Label* stack_overflow) {
   1760   // ----------- S t a t e -------------
   1761   //  -- a0 : actual number of arguments
   1762   //  -- a1 : function (passed through to callee)
   1763   //  -- a2 : expected number of arguments
   1764   //  -- a3 : new target (passed through to callee)
   1765   // -----------------------------------
   1766   // Check the stack for overflow. We are not trying to catch
   1767   // interruptions (e.g. debug break and preemption) here, so the "real stack
   1768   // limit" is checked.
   1769   __ LoadRoot(a5, Heap::kRealStackLimitRootIndex);
   1770   // Make a5 the space we have left. The stack might already be overflowed
   1771   // here which will cause a5 to become negative.
   1772   __ dsubu(a5, sp, a5);
   1773   // Check if the arguments will overflow the stack.
   1774   __ dsll(at, a2, kPointerSizeLog2);
   1775   // Signed comparison.
   1776   __ Branch(stack_overflow, le, a5, Operand(at));
   1777 }
   1778 
   1779 
   1780 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
   1781   // __ sll(a0, a0, kSmiTagSize);
   1782   __ dsll32(a0, a0, 0);
   1783   __ li(a4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
   1784   __ MultiPush(a0.bit() | a1.bit() | a4.bit() | fp.bit() | ra.bit());
   1785   __ Daddu(fp, sp,
   1786       Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize));
   1787 }
   1788 
   1789 
   1790 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
   1791   // ----------- S t a t e -------------
   1792   //  -- v0 : result being passed through
   1793   // -----------------------------------
   1794   // Get the number of arguments passed (as a smi), tear down the frame and
   1795   // then tear down the parameters.
   1796   __ ld(a1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
   1797                              kPointerSize)));
   1798   __ mov(sp, fp);
   1799   __ MultiPop(fp.bit() | ra.bit());
   1800   __ SmiScale(a4, a1, kPointerSizeLog2);
   1801   __ Daddu(sp, sp, a4);
   1802   // Adjust for the receiver.
   1803   __ Daddu(sp, sp, Operand(kPointerSize));
   1804 }
   1805 
   1806 
   1807 // static
   1808 void Builtins::Generate_Apply(MacroAssembler* masm) {
   1809   // ----------- S t a t e -------------
   1810   //  -- a0    : argumentsList
   1811   //  -- a1    : target
   1812   //  -- a3    : new.target (checked to be constructor or undefined)
   1813   //  -- sp[0] : thisArgument
   1814   // -----------------------------------
   1815 
   1816   // Create the list of arguments from the array-like argumentsList.
   1817   {
   1818     Label create_arguments, create_array, create_runtime, done_create;
   1819     __ JumpIfSmi(a0, &create_runtime);
   1820 
   1821     // Load the map of argumentsList into a2.
   1822     __ ld(a2, FieldMemOperand(a0, HeapObject::kMapOffset));
   1823 
   1824     // Load native context into a4.
   1825     __ ld(a4, NativeContextMemOperand());
   1826 
   1827     // Check if argumentsList is an (unmodified) arguments object.
   1828     __ ld(at, ContextMemOperand(a4, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
   1829     __ Branch(&create_arguments, eq, a2, Operand(at));
   1830     __ ld(at, ContextMemOperand(a4, Context::STRICT_ARGUMENTS_MAP_INDEX));
   1831     __ Branch(&create_arguments, eq, a2, Operand(at));
   1832 
   1833     // Check if argumentsList is a fast JSArray.
   1834     __ ld(v0, FieldMemOperand(a2, HeapObject::kMapOffset));
   1835     __ lbu(v0, FieldMemOperand(v0, Map::kInstanceTypeOffset));
   1836     __ Branch(&create_array, eq, v0, Operand(JS_ARRAY_TYPE));
   1837 
   1838     // Ask the runtime to create the list (actually a FixedArray).
   1839     __ bind(&create_runtime);
   1840     {
   1841       FrameScope scope(masm, StackFrame::INTERNAL);
   1842       __ Push(a1, a3, a0);
   1843       __ CallRuntime(Runtime::kCreateListFromArrayLike);
   1844       __ mov(a0, v0);
   1845       __ Pop(a1, a3);
   1846       __ ld(a2, FieldMemOperand(v0, FixedArray::kLengthOffset));
   1847       __ SmiUntag(a2);
   1848     }
   1849     __ Branch(&done_create);
   1850 
   1851     // Try to create the list from an arguments object.
   1852     __ bind(&create_arguments);
   1853     __ ld(a2,
   1854           FieldMemOperand(a0, JSObject::kHeaderSize +
   1855                                   Heap::kArgumentsLengthIndex * kPointerSize));
   1856     __ ld(a4, FieldMemOperand(a0, JSObject::kElementsOffset));
   1857     __ ld(at, FieldMemOperand(a4, FixedArray::kLengthOffset));
   1858     __ Branch(&create_runtime, ne, a2, Operand(at));
   1859     __ SmiUntag(a2);
   1860     __ mov(a0, a4);
   1861     __ Branch(&done_create);
   1862 
   1863     // Try to create the list from a JSArray object.
   1864     __ bind(&create_array);
   1865     __ ld(a2, FieldMemOperand(a2, Map::kBitField2Offset));
   1866     __ DecodeField<Map::ElementsKindBits>(a2);
   1867     STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
   1868     STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
   1869     STATIC_ASSERT(FAST_ELEMENTS == 2);
   1870     __ Branch(&create_runtime, hi, a2, Operand(FAST_ELEMENTS));
   1871     __ Branch(&create_runtime, eq, a2, Operand(FAST_HOLEY_SMI_ELEMENTS));
   1872     __ ld(a2, FieldMemOperand(a0, JSArray::kLengthOffset));
   1873     __ ld(a0, FieldMemOperand(a0, JSArray::kElementsOffset));
   1874     __ SmiUntag(a2);
   1875 
   1876     __ bind(&done_create);
   1877   }
   1878 
   1879   // Check for stack overflow.
   1880   {
   1881     // Check the stack for overflow. We are not trying to catch interruptions
   1882     // (i.e. debug break and preemption) here, so check the "real stack limit".
   1883     Label done;
   1884     __ LoadRoot(a4, Heap::kRealStackLimitRootIndex);
   1885     // Make ip the space we have left. The stack might already be overflowed
   1886     // here which will cause ip to become negative.
   1887     __ Dsubu(a4, sp, a4);
   1888     // Check if the arguments will overflow the stack.
   1889     __ dsll(at, a2, kPointerSizeLog2);
   1890     __ Branch(&done, gt, a4, Operand(at));  // Signed comparison.
   1891     __ TailCallRuntime(Runtime::kThrowStackOverflow);
   1892     __ bind(&done);
   1893   }
   1894 
   1895   // ----------- S t a t e -------------
   1896   //  -- a1    : target
   1897   //  -- a0    : args (a FixedArray built from argumentsList)
   1898   //  -- a2    : len (number of elements to push from args)
   1899   //  -- a3    : new.target (checked to be constructor or undefined)
   1900   //  -- sp[0] : thisArgument
   1901   // -----------------------------------
   1902 
   1903   // Push arguments onto the stack (thisArgument is already on the stack).
   1904   {
   1905     __ mov(a4, zero_reg);
   1906     Label done, loop;
   1907     __ bind(&loop);
   1908     __ Branch(&done, eq, a4, Operand(a2));
   1909     __ dsll(at, a4, kPointerSizeLog2);
   1910     __ Daddu(at, a0, at);
   1911     __ ld(at, FieldMemOperand(at, FixedArray::kHeaderSize));
   1912     __ Push(at);
   1913     __ Daddu(a4, a4, Operand(1));
   1914     __ Branch(&loop);
   1915     __ bind(&done);
   1916     __ Move(a0, a4);
   1917   }
   1918 
   1919   // Dispatch to Call or Construct depending on whether new.target is undefined.
   1920   {
   1921     Label construct;
   1922     __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
   1923     __ Branch(&construct, ne, a3, Operand(at));
   1924     __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
   1925     __ bind(&construct);
   1926     __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
   1927   }
   1928 }
   1929 
   1930 
   1931 // static
   1932 void Builtins::Generate_CallFunction(MacroAssembler* masm,
   1933                                      ConvertReceiverMode mode) {
   1934   // ----------- S t a t e -------------
   1935   //  -- a0 : the number of arguments (not including the receiver)
   1936   //  -- a1 : the function to call (checked to be a JSFunction)
   1937   // -----------------------------------
   1938   __ AssertFunction(a1);
   1939 
   1940   // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
   1941   // Check that function is not a "classConstructor".
   1942   Label class_constructor;
   1943   __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
   1944   __ lbu(a3, FieldMemOperand(a2, SharedFunctionInfo::kFunctionKindByteOffset));
   1945   __ And(at, a3, Operand(SharedFunctionInfo::kClassConstructorBitsWithinByte));
   1946   __ Branch(&class_constructor, ne, at, Operand(zero_reg));
   1947 
   1948   // Enter the context of the function; ToObject has to run in the function
   1949   // context, and we also need to take the global proxy from the function
   1950   // context in case of conversion.
   1951   STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset ==
   1952                 SharedFunctionInfo::kStrictModeByteOffset);
   1953   __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
   1954   // We need to convert the receiver for non-native sloppy mode functions.
   1955   Label done_convert;
   1956   __ lbu(a3, FieldMemOperand(a2, SharedFunctionInfo::kNativeByteOffset));
   1957   __ And(at, a3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) |
   1958                          (1 << SharedFunctionInfo::kStrictModeBitWithinByte)));
   1959   __ Branch(&done_convert, ne, at, Operand(zero_reg));
   1960   {
   1961     // ----------- S t a t e -------------
   1962     //  -- a0 : the number of arguments (not including the receiver)
   1963     //  -- a1 : the function to call (checked to be a JSFunction)
   1964     //  -- a2 : the shared function info.
   1965     //  -- cp : the function context.
   1966     // -----------------------------------
   1967 
   1968     if (mode == ConvertReceiverMode::kNullOrUndefined) {
   1969       // Patch receiver to global proxy.
   1970       __ LoadGlobalProxy(a3);
   1971     } else {
   1972       Label convert_to_object, convert_receiver;
   1973       __ dsll(at, a0, kPointerSizeLog2);
   1974       __ daddu(at, sp, at);
   1975       __ ld(a3, MemOperand(at));
   1976       __ JumpIfSmi(a3, &convert_to_object);
   1977       STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
   1978       __ GetObjectType(a3, a4, a4);
   1979       __ Branch(&done_convert, hs, a4, Operand(FIRST_JS_RECEIVER_TYPE));
   1980       if (mode != ConvertReceiverMode::kNotNullOrUndefined) {
   1981         Label convert_global_proxy;
   1982         __ JumpIfRoot(a3, Heap::kUndefinedValueRootIndex,
   1983                       &convert_global_proxy);
   1984         __ JumpIfNotRoot(a3, Heap::kNullValueRootIndex, &convert_to_object);
   1985         __ bind(&convert_global_proxy);
   1986         {
   1987           // Patch receiver to global proxy.
   1988           __ LoadGlobalProxy(a3);
   1989         }
   1990         __ Branch(&convert_receiver);
   1991       }
   1992       __ bind(&convert_to_object);
   1993       {
   1994         // Convert receiver using ToObject.
   1995         // TODO(bmeurer): Inline the allocation here to avoid building the frame
   1996         // in the fast case? (fall back to AllocateInNewSpace?)
   1997         FrameScope scope(masm, StackFrame::INTERNAL);
   1998         __ SmiTag(a0);
   1999         __ Push(a0, a1);
   2000         __ mov(a0, a3);
   2001         ToObjectStub stub(masm->isolate());
   2002         __ CallStub(&stub);
   2003         __ mov(a3, v0);
   2004         __ Pop(a0, a1);
   2005         __ SmiUntag(a0);
   2006       }
   2007       __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
   2008       __ bind(&convert_receiver);
   2009     }
   2010     __ dsll(at, a0, kPointerSizeLog2);
   2011     __ daddu(at, sp, at);
   2012     __ sd(a3, MemOperand(at));
   2013   }
   2014   __ bind(&done_convert);
   2015 
   2016   // ----------- S t a t e -------------
   2017   //  -- a0 : the number of arguments (not including the receiver)
   2018   //  -- a1 : the function to call (checked to be a JSFunction)
   2019   //  -- a2 : the shared function info.
   2020   //  -- cp : the function context.
   2021   // -----------------------------------
   2022 
   2023   __ lw(a2,
   2024         FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset));
   2025   ParameterCount actual(a0);
   2026   ParameterCount expected(a2);
   2027   __ InvokeFunctionCode(a1, no_reg, expected, actual, JUMP_FUNCTION,
   2028                         CheckDebugStepCallWrapper());
   2029 
   2030   // The function is a "classConstructor", need to raise an exception.
   2031   __ bind(&class_constructor);
   2032   {
   2033     FrameScope frame(masm, StackFrame::INTERNAL);
   2034     __ Push(a1);
   2035     __ CallRuntime(Runtime::kThrowConstructorNonCallableError);
   2036   }
   2037 }
   2038 
   2039 
   2040 // static
   2041 void Builtins::Generate_CallBoundFunction(MacroAssembler* masm) {
   2042   // ----------- S t a t e -------------
   2043   //  -- a0 : the number of arguments (not including the receiver)
   2044   //  -- a1 : the function to call (checked to be a JSBoundFunction)
   2045   // -----------------------------------
   2046   __ AssertBoundFunction(a1);
   2047 
   2048   // Patch the receiver to [[BoundThis]].
   2049   {
   2050     __ ld(at, FieldMemOperand(a1, JSBoundFunction::kBoundThisOffset));
   2051     __ dsll(a4, a0, kPointerSizeLog2);
   2052     __ daddu(a4, a4, sp);
   2053     __ sd(at, MemOperand(a4));
   2054   }
   2055 
   2056   // Load [[BoundArguments]] into a2 and length of that into a4.
   2057   __ ld(a2, FieldMemOperand(a1, JSBoundFunction::kBoundArgumentsOffset));
   2058   __ ld(a4, FieldMemOperand(a2, FixedArray::kLengthOffset));
   2059   __ SmiUntag(a4);
   2060 
   2061   // ----------- S t a t e -------------
   2062   //  -- a0 : the number of arguments (not including the receiver)
   2063   //  -- a1 : the function to call (checked to be a JSBoundFunction)
   2064   //  -- a2 : the [[BoundArguments]] (implemented as FixedArray)
   2065   //  -- a4 : the number of [[BoundArguments]]
   2066   // -----------------------------------
   2067 
   2068   // Reserve stack space for the [[BoundArguments]].
   2069   {
   2070     Label done;
   2071     __ dsll(a5, a4, kPointerSizeLog2);
   2072     __ Dsubu(sp, sp, Operand(a5));
   2073     // Check the stack for overflow. We are not trying to catch interruptions
   2074     // (i.e. debug break and preemption) here, so check the "real stack limit".
   2075     __ LoadRoot(at, Heap::kRealStackLimitRootIndex);
   2076     __ Branch(&done, gt, sp, Operand(at));  // Signed comparison.
   2077     // Restore the stack pointer.
   2078     __ Daddu(sp, sp, Operand(a5));
   2079     {
   2080       FrameScope scope(masm, StackFrame::MANUAL);
   2081       __ EnterFrame(StackFrame::INTERNAL);
   2082       __ CallRuntime(Runtime::kThrowStackOverflow);
   2083     }
   2084     __ bind(&done);
   2085   }
   2086 
   2087   // Relocate arguments down the stack.
   2088   {
   2089     Label loop, done_loop;
   2090     __ mov(a5, zero_reg);
   2091     __ bind(&loop);
   2092     __ Branch(&done_loop, gt, a5, Operand(a0));
   2093     __ dsll(a6, a4, kPointerSizeLog2);
   2094     __ daddu(a6, a6, sp);
   2095     __ ld(at, MemOperand(a6));
   2096     __ dsll(a6, a5, kPointerSizeLog2);
   2097     __ daddu(a6, a6, sp);
   2098     __ sd(at, MemOperand(a6));
   2099     __ Daddu(a4, a4, Operand(1));
   2100     __ Daddu(a5, a5, Operand(1));
   2101     __ Branch(&loop);
   2102     __ bind(&done_loop);
   2103   }
   2104 
   2105   // Copy [[BoundArguments]] to the stack (below the arguments).
   2106   {
   2107     Label loop, done_loop;
   2108     __ ld(a4, FieldMemOperand(a2, FixedArray::kLengthOffset));
   2109     __ SmiUntag(a4);
   2110     __ Daddu(a2, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   2111     __ bind(&loop);
   2112     __ Dsubu(a4, a4, Operand(1));
   2113     __ Branch(&done_loop, lt, a4, Operand(zero_reg));
   2114     __ dsll(a5, a4, kPointerSizeLog2);
   2115     __ daddu(a5, a5, a2);
   2116     __ ld(at, MemOperand(a5));
   2117     __ dsll(a5, a0, kPointerSizeLog2);
   2118     __ daddu(a5, a5, sp);
   2119     __ sd(at, MemOperand(a5));
   2120     __ Daddu(a0, a0, Operand(1));
   2121     __ Branch(&loop);
   2122     __ bind(&done_loop);
   2123   }
   2124 
   2125   // Call the [[BoundTargetFunction]] via the Call builtin.
   2126   __ ld(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
   2127   __ li(at, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny,
   2128                                       masm->isolate())));
   2129   __ ld(at, MemOperand(at));
   2130   __ Daddu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag));
   2131   __ Jump(at);
   2132 }
   2133 
   2134 
   2135 // static
   2136 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
   2137   // ----------- S t a t e -------------
   2138   //  -- a0 : the number of arguments (not including the receiver)
   2139   //  -- a1 : the target to call (can be any Object).
   2140   // -----------------------------------
   2141 
   2142   Label non_callable, non_function, non_smi;
   2143   __ JumpIfSmi(a1, &non_callable);
   2144   __ bind(&non_smi);
   2145   __ GetObjectType(a1, t1, t2);
   2146   __ Jump(masm->isolate()->builtins()->CallFunction(mode),
   2147           RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE));
   2148   __ Jump(masm->isolate()->builtins()->CallBoundFunction(),
   2149           RelocInfo::CODE_TARGET, eq, t2, Operand(JS_BOUND_FUNCTION_TYPE));
   2150   __ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE));
   2151 
   2152   // 1. Runtime fallback for Proxy [[Call]].
   2153   __ Push(a1);
   2154   // Increase the arguments size to include the pushed function and the
   2155   // existing receiver on the stack.
   2156   __ Daddu(a0, a0, 2);
   2157   // Tail-call to the runtime.
   2158   __ JumpToExternalReference(
   2159       ExternalReference(Runtime::kJSProxyCall, masm->isolate()));
   2160 
   2161   // 2. Call to something else, which might have a [[Call]] internal method (if
   2162   // not we raise an exception).
   2163   __ bind(&non_function);
   2164   // Check if target has a [[Call]] internal method.
   2165   __ lbu(t1, FieldMemOperand(t1, Map::kBitFieldOffset));
   2166   __ And(t1, t1, Operand(1 << Map::kIsCallable));
   2167   __ Branch(&non_callable, eq, t1, Operand(zero_reg));
   2168   // Overwrite the original receiver with the (original) target.
   2169   __ dsll(at, a0, kPointerSizeLog2);
   2170   __ daddu(at, sp, at);
   2171   __ sd(a1, MemOperand(at));
   2172   // Let the "call_as_function_delegate" take care of the rest.
   2173   __ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, a1);
   2174   __ Jump(masm->isolate()->builtins()->CallFunction(
   2175               ConvertReceiverMode::kNotNullOrUndefined),
   2176           RelocInfo::CODE_TARGET);
   2177 
   2178   // 3. Call to something that is not callable.
   2179   __ bind(&non_callable);
   2180   {
   2181     FrameScope scope(masm, StackFrame::INTERNAL);
   2182     __ Push(a1);
   2183     __ CallRuntime(Runtime::kThrowCalledNonCallable);
   2184   }
   2185 }
   2186 
   2187 
   2188 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
   2189   // ----------- S t a t e -------------
   2190   //  -- a0 : the number of arguments (not including the receiver)
   2191   //  -- a1 : the constructor to call (checked to be a JSFunction)
   2192   //  -- a3 : the new target (checked to be a constructor)
   2193   // -----------------------------------
   2194   __ AssertFunction(a1);
   2195 
   2196   // Calling convention for function specific ConstructStubs require
   2197   // a2 to contain either an AllocationSite or undefined.
   2198   __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
   2199 
   2200   // Tail call to the function-specific construct stub (still in the caller
   2201   // context at this point).
   2202   __ ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
   2203   __ ld(a4, FieldMemOperand(a4, SharedFunctionInfo::kConstructStubOffset));
   2204   __ Daddu(at, a4, Operand(Code::kHeaderSize - kHeapObjectTag));
   2205   __ Jump(at);
   2206 }
   2207 
   2208 
   2209 // static
   2210 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
   2211   // ----------- S t a t e -------------
   2212   //  -- a0 : the number of arguments (not including the receiver)
   2213   //  -- a1 : the function to call (checked to be a JSBoundFunction)
   2214   //  -- a3 : the new target (checked to be a constructor)
   2215   // -----------------------------------
   2216   __ AssertBoundFunction(a1);
   2217 
   2218   // Load [[BoundArguments]] into a2 and length of that into a4.
   2219   __ ld(a2, FieldMemOperand(a1, JSBoundFunction::kBoundArgumentsOffset));
   2220   __ ld(a4, FieldMemOperand(a2, FixedArray::kLengthOffset));
   2221   __ SmiUntag(a4);
   2222 
   2223   // ----------- S t a t e -------------
   2224   //  -- a0 : the number of arguments (not including the receiver)
   2225   //  -- a1 : the function to call (checked to be a JSBoundFunction)
   2226   //  -- a2 : the [[BoundArguments]] (implemented as FixedArray)
   2227   //  -- a3 : the new target (checked to be a constructor)
   2228   //  -- a4 : the number of [[BoundArguments]]
   2229   // -----------------------------------
   2230 
   2231   // Reserve stack space for the [[BoundArguments]].
   2232   {
   2233     Label done;
   2234     __ dsll(a5, a4, kPointerSizeLog2);
   2235     __ Dsubu(sp, sp, Operand(a5));
   2236     // Check the stack for overflow. We are not trying to catch interruptions
   2237     // (i.e. debug break and preemption) here, so check the "real stack limit".
   2238     __ LoadRoot(at, Heap::kRealStackLimitRootIndex);
   2239     __ Branch(&done, gt, sp, Operand(at));  // Signed comparison.
   2240     // Restore the stack pointer.
   2241     __ Daddu(sp, sp, Operand(a5));
   2242     {
   2243       FrameScope scope(masm, StackFrame::MANUAL);
   2244       __ EnterFrame(StackFrame::INTERNAL);
   2245       __ CallRuntime(Runtime::kThrowStackOverflow);
   2246     }
   2247     __ bind(&done);
   2248   }
   2249 
   2250   // Relocate arguments down the stack.
   2251   {
   2252     Label loop, done_loop;
   2253     __ mov(a5, zero_reg);
   2254     __ bind(&loop);
   2255     __ Branch(&done_loop, ge, a5, Operand(a0));
   2256     __ dsll(a6, a4, kPointerSizeLog2);
   2257     __ daddu(a6, a6, sp);
   2258     __ ld(at, MemOperand(a6));
   2259     __ dsll(a6, a5, kPointerSizeLog2);
   2260     __ daddu(a6, a6, sp);
   2261     __ sd(at, MemOperand(a6));
   2262     __ Daddu(a4, a4, Operand(1));
   2263     __ Daddu(a5, a5, Operand(1));
   2264     __ Branch(&loop);
   2265     __ bind(&done_loop);
   2266   }
   2267 
   2268   // Copy [[BoundArguments]] to the stack (below the arguments).
   2269   {
   2270     Label loop, done_loop;
   2271     __ ld(a4, FieldMemOperand(a2, FixedArray::kLengthOffset));
   2272     __ SmiUntag(a4);
   2273     __ Daddu(a2, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   2274     __ bind(&loop);
   2275     __ Dsubu(a4, a4, Operand(1));
   2276     __ Branch(&done_loop, lt, a4, Operand(zero_reg));
   2277     __ dsll(a5, a4, kPointerSizeLog2);
   2278     __ daddu(a5, a5, a2);
   2279     __ ld(at, MemOperand(a5));
   2280     __ dsll(a5, a0, kPointerSizeLog2);
   2281     __ daddu(a5, a5, sp);
   2282     __ sd(at, MemOperand(a5));
   2283     __ Daddu(a0, a0, Operand(1));
   2284     __ Branch(&loop);
   2285     __ bind(&done_loop);
   2286   }
   2287 
   2288   // Patch new.target to [[BoundTargetFunction]] if new.target equals target.
   2289   {
   2290     Label skip_load;
   2291     __ Branch(&skip_load, ne, a1, Operand(a3));
   2292     __ ld(a3, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
   2293     __ bind(&skip_load);
   2294   }
   2295 
   2296   // Construct the [[BoundTargetFunction]] via the Construct builtin.
   2297   __ ld(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
   2298   __ li(at, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
   2299   __ ld(at, MemOperand(at));
   2300   __ Daddu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag));
   2301   __ Jump(at);
   2302 }
   2303 
   2304 
   2305 // static
   2306 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
   2307   // ----------- S t a t e -------------
   2308   //  -- a0 : the number of arguments (not including the receiver)
   2309   //  -- a1 : the constructor to call (checked to be a JSProxy)
   2310   //  -- a3 : the new target (either the same as the constructor or
   2311   //          the JSFunction on which new was invoked initially)
   2312   // -----------------------------------
   2313 
   2314   // Call into the Runtime for Proxy [[Construct]].
   2315   __ Push(a1, a3);
   2316   // Include the pushed new_target, constructor and the receiver.
   2317   __ Daddu(a0, a0, Operand(3));
   2318   // Tail-call to the runtime.
   2319   __ JumpToExternalReference(
   2320       ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
   2321 }
   2322 
   2323 
   2324 // static
   2325 void Builtins::Generate_Construct(MacroAssembler* masm) {
   2326   // ----------- S t a t e -------------
   2327   //  -- a0 : the number of arguments (not including the receiver)
   2328   //  -- a1 : the constructor to call (can be any Object)
   2329   //  -- a3 : the new target (either the same as the constructor or
   2330   //          the JSFunction on which new was invoked initially)
   2331   // -----------------------------------
   2332 
   2333   // Check if target is a Smi.
   2334   Label non_constructor;
   2335   __ JumpIfSmi(a1, &non_constructor);
   2336 
   2337   // Dispatch based on instance type.
   2338   __ ld(t1, FieldMemOperand(a1, HeapObject::kMapOffset));
   2339   __ lbu(t2, FieldMemOperand(t1, Map::kInstanceTypeOffset));
   2340   __ Jump(masm->isolate()->builtins()->ConstructFunction(),
   2341           RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE));
   2342 
   2343   // Check if target has a [[Construct]] internal method.
   2344   __ lbu(t3, FieldMemOperand(t1, Map::kBitFieldOffset));
   2345   __ And(t3, t3, Operand(1 << Map::kIsConstructor));
   2346   __ Branch(&non_constructor, eq, t3, Operand(zero_reg));
   2347 
   2348   // Only dispatch to bound functions after checking whether they are
   2349   // constructors.
   2350   __ Jump(masm->isolate()->builtins()->ConstructBoundFunction(),
   2351           RelocInfo::CODE_TARGET, eq, t2, Operand(JS_BOUND_FUNCTION_TYPE));
   2352 
   2353   // Only dispatch to proxies after checking whether they are constructors.
   2354   __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
   2355           eq, t2, Operand(JS_PROXY_TYPE));
   2356 
   2357   // Called Construct on an exotic Object with a [[Construct]] internal method.
   2358   {
   2359     // Overwrite the original receiver with the (original) target.
   2360     __ dsll(at, a0, kPointerSizeLog2);
   2361     __ daddu(at, sp, at);
   2362     __ sd(a1, MemOperand(at));
   2363     // Let the "call_as_constructor_delegate" take care of the rest.
   2364     __ LoadNativeContextSlot(Context::CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, a1);
   2365     __ Jump(masm->isolate()->builtins()->CallFunction(),
   2366             RelocInfo::CODE_TARGET);
   2367   }
   2368 
   2369   // Called Construct on an Object that doesn't have a [[Construct]] internal
   2370   // method.
   2371   __ bind(&non_constructor);
   2372   __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
   2373           RelocInfo::CODE_TARGET);
   2374 }
   2375 
   2376 
   2377 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
   2378   // State setup as expected by MacroAssembler::InvokePrologue.
   2379   // ----------- S t a t e -------------
   2380   //  -- a0: actual arguments count
   2381   //  -- a1: function (passed through to callee)
   2382   //  -- a2: expected arguments count
   2383   //  -- a3: new target (passed through to callee)
   2384   // -----------------------------------
   2385 
   2386   Label invoke, dont_adapt_arguments, stack_overflow;
   2387 
   2388   Label enough, too_few;
   2389   __ Branch(&dont_adapt_arguments, eq,
   2390       a2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
   2391   // We use Uless as the number of argument should always be greater than 0.
   2392   __ Branch(&too_few, Uless, a0, Operand(a2));
   2393 
   2394   {  // Enough parameters: actual >= expected.
   2395     // a0: actual number of arguments as a smi
   2396     // a1: function
   2397     // a2: expected number of arguments
   2398     // a3: new target (passed through to callee)
   2399     __ bind(&enough);
   2400     EnterArgumentsAdaptorFrame(masm);
   2401     ArgumentAdaptorStackCheck(masm, &stack_overflow);
   2402 
   2403     // Calculate copy start address into a0 and copy end address into a4.
   2404     __ SmiScale(a0, a0, kPointerSizeLog2);
   2405     __ Daddu(a0, fp, a0);
   2406     // Adjust for return address and receiver.
   2407     __ Daddu(a0, a0, Operand(2 * kPointerSize));
   2408     // Compute copy end address.
   2409     __ dsll(a4, a2, kPointerSizeLog2);
   2410     __ dsubu(a4, a0, a4);
   2411 
   2412     // Copy the arguments (including the receiver) to the new stack frame.
   2413     // a0: copy start address
   2414     // a1: function
   2415     // a2: expected number of arguments
   2416     // a3: new target (passed through to callee)
   2417     // a4: copy end address
   2418 
   2419     Label copy;
   2420     __ bind(&copy);
   2421     __ ld(a5, MemOperand(a0));
   2422     __ push(a5);
   2423     __ Branch(USE_DELAY_SLOT, &copy, ne, a0, Operand(a4));
   2424     __ daddiu(a0, a0, -kPointerSize);  // In delay slot.
   2425 
   2426     __ jmp(&invoke);
   2427   }
   2428 
   2429   {  // Too few parameters: Actual < expected.
   2430     __ bind(&too_few);
   2431 
   2432     // If the function is strong we need to throw an error.
   2433     Label no_strong_error;
   2434     __ ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
   2435     __ lbu(a5, FieldMemOperand(a4, SharedFunctionInfo::kStrongModeByteOffset));
   2436     __ And(a5, a5, Operand(1 << SharedFunctionInfo::kStrongModeBitWithinByte));
   2437     __ Branch(&no_strong_error, eq, a5, Operand(zero_reg));
   2438 
   2439     // What we really care about is the required number of arguments.
   2440     DCHECK_EQ(kPointerSize, kInt64Size);
   2441     __ lw(a5, FieldMemOperand(a4, SharedFunctionInfo::kLengthOffset));
   2442     __ srl(a5, a5, 1);
   2443     __ Branch(&no_strong_error, ge, a0, Operand(a5));
   2444 
   2445     {
   2446       FrameScope frame(masm, StackFrame::MANUAL);
   2447       EnterArgumentsAdaptorFrame(masm);
   2448       __ CallRuntime(Runtime::kThrowStrongModeTooFewArguments);
   2449     }
   2450 
   2451     __ bind(&no_strong_error);
   2452     EnterArgumentsAdaptorFrame(masm);
   2453     ArgumentAdaptorStackCheck(masm, &stack_overflow);
   2454 
   2455     // Calculate copy start address into a0 and copy end address into a7.
   2456     // a0: actual number of arguments as a smi
   2457     // a1: function
   2458     // a2: expected number of arguments
   2459     // a3: new target (passed through to callee)
   2460     __ SmiScale(a0, a0, kPointerSizeLog2);
   2461     __ Daddu(a0, fp, a0);
   2462     // Adjust for return address and receiver.
   2463     __ Daddu(a0, a0, Operand(2 * kPointerSize));
   2464     // Compute copy end address. Also adjust for return address.
   2465     __ Daddu(a7, fp, kPointerSize);
   2466 
   2467     // Copy the arguments (including the receiver) to the new stack frame.
   2468     // a0: copy start address
   2469     // a1: function
   2470     // a2: expected number of arguments
   2471     // a3: new target (passed through to callee)
   2472     // a7: copy end address
   2473     Label copy;
   2474     __ bind(&copy);
   2475     __ ld(a4, MemOperand(a0));  // Adjusted above for return addr and receiver.
   2476     __ Dsubu(sp, sp, kPointerSize);
   2477     __ Dsubu(a0, a0, kPointerSize);
   2478     __ Branch(USE_DELAY_SLOT, &copy, ne, a0, Operand(a7));
   2479     __ sd(a4, MemOperand(sp));  // In the delay slot.
   2480 
   2481     // Fill the remaining expected arguments with undefined.
   2482     // a1: function
   2483     // a2: expected number of arguments
   2484     // a3: new target (passed through to callee)
   2485     __ LoadRoot(a5, Heap::kUndefinedValueRootIndex);
   2486     __ dsll(a6, a2, kPointerSizeLog2);
   2487     __ Dsubu(a4, fp, Operand(a6));
   2488     // Adjust for frame.
   2489     __ Dsubu(a4, a4, Operand(StandardFrameConstants::kFixedFrameSizeFromFp +
   2490                              2 * kPointerSize));
   2491 
   2492     Label fill;
   2493     __ bind(&fill);
   2494     __ Dsubu(sp, sp, kPointerSize);
   2495     __ Branch(USE_DELAY_SLOT, &fill, ne, sp, Operand(a4));
   2496     __ sd(a5, MemOperand(sp));
   2497   }
   2498 
   2499   // Call the entry point.
   2500   __ bind(&invoke);
   2501   __ mov(a0, a2);
   2502   // a0 : expected number of arguments
   2503   // a1 : function (passed through to callee)
   2504   // a3: new target (passed through to callee)
   2505   __ ld(a4, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
   2506   __ Call(a4);
   2507 
   2508   // Store offset of return address for deoptimizer.
   2509   masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
   2510 
   2511   // Exit frame and return.
   2512   LeaveArgumentsAdaptorFrame(masm);
   2513   __ Ret();
   2514 
   2515 
   2516   // -------------------------------------------
   2517   // Don't adapt arguments.
   2518   // -------------------------------------------
   2519   __ bind(&dont_adapt_arguments);
   2520   __ ld(a4, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
   2521   __ Jump(a4);
   2522 
   2523   __ bind(&stack_overflow);
   2524   {
   2525     FrameScope frame(masm, StackFrame::MANUAL);
   2526     __ CallRuntime(Runtime::kThrowStackOverflow);
   2527     __ break_(0xCC);
   2528   }
   2529 }
   2530 
   2531 
   2532 #undef __
   2533 
   2534 }  // namespace internal
   2535 }  // namespace v8
   2536 
   2537 #endif  // V8_TARGET_ARCH_MIPS64
   2538