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