7 #include "src/api-arguments-inl.h" 8 #include "src/assembler-inl.h" 9 #include "src/base/bits.h" 10 #include "src/bootstrapper.h" 11 #include "src/code-stubs.h" 12 #include "src/double.h" 13 #include "src/frame-constants.h" 14 #include "src/frames.h" 15 #include "src/ic/ic.h" 16 #include "src/ic/stub-cache.h" 17 #include "src/isolate.h" 18 #include "src/macro-assembler.h" 19 #include "src/objects/api-callbacks.h" 20 #include "src/regexp/jsregexp.h" 21 #include "src/regexp/regexp-macro-assembler.h" 22 #include "src/runtime/runtime.h" 24 #include "src/ppc/code-stubs-ppc.h" 29 #define __ ACCESS_MASM(masm) 31 void JSEntryStub::Generate(MacroAssembler* masm) {
38 Label invoke, handler_entry, exit;
41 __ function_descriptor();
44 NoRootArrayScope no_root_array(masm);
49 __ StoreP(r0, MemOperand(sp, kStackFrameLRSlot * kPointerSize));
52 __ MultiPush(kCalleeSaved);
55 __ MultiPushDoubles(kCalleeSavedDoubles);
57 __ LoadDoubleLiteral(kDoubleRegZero, Double(0.0), r0);
59 __ InitializeRootRegister();
68 __ li(r0, Operand(-1));
70 if (FLAG_enable_embedded_constant_pool) {
71 __ li(kConstantPoolRegister, Operand::Zero());
72 __ push(kConstantPoolRegister);
74 StackFrame::Type marker = type();
75 __ mov(r0, Operand(StackFrame::TypeToMarker(marker)));
79 __ mov(r8, Operand(ExternalReference::Create(
80 IsolateAddressId::kCEntryFPAddress, isolate())));
81 __ LoadP(r0, MemOperand(r8));
85 __ addi(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
88 Label non_outermost_js;
89 ExternalReference js_entry_sp =
90 ExternalReference::Create(IsolateAddressId::kJSEntrySPAddress, isolate());
91 __ mov(r8, Operand(js_entry_sp));
92 __ LoadP(r9, MemOperand(r8));
93 __ cmpi(r9, Operand::Zero());
94 __ bne(&non_outermost_js);
95 __ StoreP(fp, MemOperand(r8));
96 __ mov(ip, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME));
99 __ bind(&non_outermost_js);
100 __ mov(ip, Operand(StackFrame::INNER_JSENTRY_FRAME));
108 __ bind(&handler_entry);
109 handler_offset_ = handler_entry.pos();
114 __ mov(ip, Operand(ExternalReference::Create(
115 IsolateAddressId::kPendingExceptionAddress, isolate())));
117 __ StoreP(r3, MemOperand(ip));
118 __ LoadRoot(r3, RootIndex::kException);
124 __ PushStackHandler();
140 __ Call(EntryTrampoline(), RelocInfo::CODE_TARGET);
143 __ PopStackHandler();
147 Label non_outermost_js_2;
149 __ cmpi(r8, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME));
150 __ bne(&non_outermost_js_2);
151 __ mov(r9, Operand::Zero());
152 __ mov(r8, Operand(js_entry_sp));
153 __ StoreP(r9, MemOperand(r8));
154 __ bind(&non_outermost_js_2);
158 __ mov(ip, Operand(ExternalReference::Create(
159 IsolateAddressId::kCEntryFPAddress, isolate())));
160 __ StoreP(r6, MemOperand(ip));
163 __ addi(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
166 __ MultiPopDoubles(kCalleeSavedDoubles);
169 __ MultiPop(kCalleeSaved);
172 __ LoadP(r0, MemOperand(sp, kStackFrameLRSlot * kPointerSize));
178 void DirectCEntryStub::Generate(MacroAssembler* masm) {
182 __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize));
184 __ LoadP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize));
190 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, Register target) {
191 if (FLAG_embedded_builtins) {
192 if (masm->root_array_available() &&
193 isolate()->ShouldLoadConstantsFromRootList()) {
196 DCHECK_NE(ip, target);
197 __ IndirectLoadConstant(ip, GetCode());
198 __ addi(r0, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
204 if (ABI_USES_FUNCTION_DESCRIPTORS) {
206 __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(target, kPointerSize));
207 __ LoadP(ip, MemOperand(target, 0));
214 intptr_t code =
reinterpret_cast<intptr_t
>(GetCode().location());
215 __ mov(r0, Operand(code, RelocInfo::CODE_TARGET));
219 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
220 return ref0.address() - ref1.address();
228 static void CallApiFunctionAndReturn(MacroAssembler* masm,
229 Register function_address,
230 ExternalReference thunk_ref,
232 MemOperand* stack_space_operand,
233 MemOperand return_value_operand) {
234 Isolate* isolate = masm->isolate();
235 ExternalReference next_address =
236 ExternalReference::handle_scope_next_address(isolate);
237 const int kNextOffset = 0;
238 const int kLimitOffset = AddressOffset(
239 ExternalReference::handle_scope_limit_address(isolate), next_address);
240 const int kLevelOffset = AddressOffset(
241 ExternalReference::handle_scope_level_address(isolate), next_address);
244 DCHECK(function_address == r4 || function_address == r5);
245 Register scratch = r6;
247 __ Move(scratch, ExternalReference::is_profiling_address(isolate));
248 __ lbz(scratch, MemOperand(scratch, 0));
249 __ cmpi(scratch, Operand::Zero());
251 if (CpuFeatures::IsSupported(ISELECT)) {
252 __ Move(scratch, thunk_ref);
253 __ isel(eq, scratch, function_address, scratch);
255 Label profiler_disabled;
256 Label end_profiler_check;
257 __ beq(&profiler_disabled);
258 __ Move(scratch, thunk_ref);
259 __ b(&end_profiler_check);
260 __ bind(&profiler_disabled);
261 __ mr(scratch, function_address);
262 __ bind(&end_profiler_check);
270 __ Move(r17, next_address);
271 __ LoadP(r14, MemOperand(r17, kNextOffset));
272 __ LoadP(r15, MemOperand(r17, kLimitOffset));
273 __ lwz(r16, MemOperand(r17, kLevelOffset));
274 __ addi(r16, r16, Operand(1));
275 __ stw(r16, MemOperand(r17, kLevelOffset));
277 if (FLAG_log_timer_events) {
278 FrameScope frame(masm, StackFrame::MANUAL);
279 __ PushSafepointRegisters();
280 __ PrepareCallCFunction(1, r3);
281 __ Move(r3, ExternalReference::isolate_address(isolate));
282 __ CallCFunction(ExternalReference::log_enter_external_function(), 1);
283 __ PopSafepointRegisters();
289 DirectCEntryStub stub(isolate);
290 stub.GenerateCall(masm, scratch);
292 if (FLAG_log_timer_events) {
293 FrameScope frame(masm, StackFrame::MANUAL);
294 __ PushSafepointRegisters();
295 __ PrepareCallCFunction(1, r3);
296 __ Move(r3, ExternalReference::isolate_address(isolate));
297 __ CallCFunction(ExternalReference::log_leave_external_function(), 1);
298 __ PopSafepointRegisters();
301 Label promote_scheduled_exception;
302 Label delete_allocated_handles;
303 Label leave_exit_frame;
304 Label return_value_loaded;
307 __ LoadP(r3, return_value_operand);
308 __ bind(&return_value_loaded);
311 __ StoreP(r14, MemOperand(r17, kNextOffset));
312 if (__ emit_debug_code()) {
313 __ lwz(r4, MemOperand(r17, kLevelOffset));
315 __ Check(eq, AbortReason::kUnexpectedLevelAfterReturnFromApiCall);
317 __ subi(r16, r16, Operand(1));
318 __ stw(r16, MemOperand(r17, kLevelOffset));
319 __ LoadP(r0, MemOperand(r17, kLimitOffset));
321 __ bne(&delete_allocated_handles);
324 __ bind(&leave_exit_frame);
326 if (stack_space_operand !=
nullptr) {
327 __ lwz(r14, *stack_space_operand);
329 __ mov(r14, Operand(stack_space));
331 __ LeaveExitFrame(
false, r14, stack_space_operand !=
nullptr);
334 __ LoadRoot(r14, RootIndex::kTheHoleValue);
335 __ Move(r15, ExternalReference::scheduled_exception_address(isolate));
336 __ LoadP(r15, MemOperand(r15));
338 __ bne(&promote_scheduled_exception);
343 __ bind(&promote_scheduled_exception);
344 __ TailCallRuntime(Runtime::kPromoteScheduledException);
347 __ bind(&delete_allocated_handles);
348 __ StoreP(r15, MemOperand(r17, kLimitOffset));
350 __ PrepareCallCFunction(1, r15);
351 __ Move(r3, ExternalReference::isolate_address(isolate));
352 __ CallCFunction(ExternalReference::delete_handle_scope_extensions(), 1);
354 __ b(&leave_exit_frame);
357 void CallApiCallbackStub::Generate(MacroAssembler* masm) {
370 Register call_data = r7;
371 Register holder = r5;
372 Register api_function_address = r4;
374 typedef FunctionCallbackArguments FCA;
376 STATIC_ASSERT(FCA::kArgsLength == 6);
377 STATIC_ASSERT(FCA::kNewTargetIndex == 5);
378 STATIC_ASSERT(FCA::kDataIndex == 4);
379 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
380 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
381 STATIC_ASSERT(FCA::kIsolateIndex == 1);
382 STATIC_ASSERT(FCA::kHolderIndex == 0);
385 __ PushRoot(RootIndex::kUndefinedValue);
390 Register scratch = call_data;
391 __ LoadRoot(scratch, RootIndex::kUndefinedValue);
397 __ Move(scratch, ExternalReference::isolate_address(masm->isolate()));
412 const int kApiStackSpace = 4;
413 const int kFunctionCallbackInfoOffset =
414 (kStackFrameExtraParamSlot + 1) * kPointerSize;
416 FrameScope frame_scope(masm, StackFrame::MANUAL);
417 __ EnterExitFrame(
false, kApiStackSpace);
419 DCHECK(api_function_address != r3 && scratch != r3);
422 __ addi(r3, sp, Operand(kFunctionCallbackInfoOffset));
424 __ StoreP(scratch, MemOperand(r3, 0 * kPointerSize));
426 __ addi(ip, scratch, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
427 __ StoreP(ip, MemOperand(r3, 1 * kPointerSize));
429 __ li(ip, Operand(argc()));
430 __ stw(ip, MemOperand(r3, 2 * kPointerSize));
432 ExternalReference thunk_ref = ExternalReference::invoke_function_callback();
434 AllowExternalCallThatCantCauseGC scope(masm);
436 int return_value_offset = 2 + FCA::kReturnValueOffset;
437 MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
438 const int stack_space = argc() + FCA::kArgsLength + 1;
439 MemOperand* stack_space_operand =
nullptr;
440 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
441 stack_space_operand, return_value_operand);
445 void CallApiGetterStub::Generate(MacroAssembler* masm) {
447 int accessorInfoSlot = 0;
448 int apiStackSpace = 0;
451 STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
452 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
453 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
454 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
455 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
456 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
457 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
458 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
460 Register receiver = ApiGetterDescriptor::ReceiverRegister();
461 Register holder = ApiGetterDescriptor::HolderRegister();
462 Register callback = ApiGetterDescriptor::CallbackRegister();
463 Register scratch = r7;
464 DCHECK(!AreAliased(receiver, holder, callback, scratch));
466 Register api_function_address = r5;
470 __ LoadP(scratch, FieldMemOperand(callback, AccessorInfo::kDataOffset));
472 __ LoadRoot(scratch, RootIndex::kUndefinedValue);
473 __ Push(scratch, scratch);
474 __ Move(scratch, ExternalReference::isolate_address(isolate()));
475 __ Push(scratch, holder);
476 __ Push(Smi::zero());
477 __ LoadP(scratch, FieldMemOperand(callback, AccessorInfo::kNameOffset));
481 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
485 __ addi(r4, r3, Operand(1 * kPointerSize));
499 if (ABI_PASSES_HANDLES_IN_REGS) {
500 accessorInfoSlot = kStackFrameExtraParamSlot + 1;
503 arg0Slot = kStackFrameExtraParamSlot + 1;
504 accessorInfoSlot = arg0Slot + 1;
508 FrameScope frame_scope(masm, StackFrame::MANUAL);
509 __ EnterExitFrame(
false, apiStackSpace);
511 if (!ABI_PASSES_HANDLES_IN_REGS) {
513 __ StoreP(r3, MemOperand(sp, arg0Slot * kPointerSize));
514 __ addi(r3, sp, Operand(arg0Slot * kPointerSize));
519 __ StoreP(r4, MemOperand(sp, accessorInfoSlot * kPointerSize));
520 __ addi(r4, sp, Operand(accessorInfoSlot * kPointerSize));
523 ExternalReference thunk_ref =
524 ExternalReference::invoke_accessor_getter_callback();
526 __ LoadP(scratch, FieldMemOperand(callback, AccessorInfo::kJsGetterOffset));
527 __ LoadP(api_function_address,
528 FieldMemOperand(scratch, Foreign::kForeignAddressOffset));
531 MemOperand return_value_operand(
532 fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
533 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
534 kStackUnwindSpace,
nullptr, return_value_operand);
541 #endif // V8_TARGET_ARCH_PPC