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