5 #if V8_TARGET_ARCH_S390 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/frame-constants.h" 13 #include "src/frames.h" 14 #include "src/ic/ic.h" 15 #include "src/ic/stub-cache.h" 16 #include "src/isolate.h" 17 #include "src/macro-assembler.h" 18 #include "src/objects/api-callbacks.h" 19 #include "src/regexp/jsregexp.h" 20 #include "src/regexp/regexp-macro-assembler.h" 21 #include "src/runtime/runtime.h" 23 #include "src/s390/code-stubs-s390.h" 28 #define __ ACCESS_MASM(masm) 30 void JSEntryStub::Generate(MacroAssembler* masm) {
37 Label invoke, handler_entry, exit;
40 NoRootArrayScope no_root_array(masm);
43 #if V8_TARGET_ARCH_S390X 45 __ lay(sp, MemOperand(sp, -8 * kDoubleSize));
46 __
std(d8, MemOperand(sp));
47 __
std(d9, MemOperand(sp, 1 * kDoubleSize));
48 __
std(d10, MemOperand(sp, 2 * kDoubleSize));
49 __
std(d11, MemOperand(sp, 3 * kDoubleSize));
50 __
std(d12, MemOperand(sp, 4 * kDoubleSize));
51 __
std(d13, MemOperand(sp, 5 * kDoubleSize));
52 __
std(d14, MemOperand(sp, 6 * kDoubleSize));
53 __
std(d15, MemOperand(sp, 7 * kDoubleSize));
57 __ lay(sp, MemOperand(sp, -2 * kDoubleSize));
58 __
std(d4, MemOperand(sp));
59 __
std(d6, MemOperand(sp, kDoubleSize));
72 __ lay(sp, MemOperand(sp, -10 * kPointerSize));
73 __ StoreMultipleP(r6, sp, MemOperand(sp, 0));
84 __ lay(sp, MemOperand(sp, -5 * kPointerSize));
87 __ LoadImmP(r10, Operand(-1));
89 StackFrame::Type marker = type();
90 __ Load(r9, Operand(StackFrame::TypeToMarker(marker)));
91 __ Load(r8, Operand(StackFrame::TypeToMarker(marker)));
93 __ mov(r7, Operand(ExternalReference::Create(
94 IsolateAddressId::kCEntryFPAddress, isolate())));
95 __ LoadP(r7, MemOperand(r7));
96 __ StoreMultipleP(r7, r10, MemOperand(sp, kPointerSize));
100 __ lay(fp, MemOperand(
101 sp, -EntryFrameConstants::kCallerFPOffset + kPointerSize));
103 __ InitializeRootRegister();
107 Label non_outermost_js;
108 ExternalReference js_entry_sp =
109 ExternalReference::Create(IsolateAddressId::kJSEntrySPAddress, isolate());
110 __ mov(r7, Operand(js_entry_sp));
111 __ LoadAndTestP(r8, MemOperand(r7));
112 __ bne(&non_outermost_js, Label::kNear);
113 __ StoreP(fp, MemOperand(r7));
114 __ Load(ip, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME));
116 __ b(&cont, Label::kNear);
117 __ bind(&non_outermost_js);
118 __ Load(ip, Operand(StackFrame::INNER_JSENTRY_FRAME));
121 __ StoreP(ip, MemOperand(sp));
125 __ b(&invoke, Label::kNear);
127 __ bind(&handler_entry);
128 handler_offset_ = handler_entry.pos();
133 __ mov(ip, Operand(ExternalReference::Create(
134 IsolateAddressId::kPendingExceptionAddress, isolate())));
136 __ StoreP(r2, MemOperand(ip));
137 __ LoadRoot(r2, RootIndex::kException);
138 __ b(&exit, Label::kNear);
143 __ PushStackHandler();
159 __ Call(EntryTrampoline(), RelocInfo::CODE_TARGET);
162 __ PopStackHandler();
166 Label non_outermost_js_2;
168 __ CmpP(r7, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME));
169 __ bne(&non_outermost_js_2, Label::kNear);
170 __ mov(r8, Operand::Zero());
171 __ mov(r7, Operand(js_entry_sp));
172 __ StoreP(r8, MemOperand(r7));
173 __ bind(&non_outermost_js_2);
177 __ mov(ip, Operand(ExternalReference::Create(
178 IsolateAddressId::kCEntryFPAddress, isolate())));
179 __ StoreP(r5, MemOperand(ip));
182 __ lay(sp, MemOperand(sp, -EntryFrameConstants::kCallerFPOffset));
185 __ LoadMultipleP(r6, sp, MemOperand(sp, 0));
186 __ la(sp, MemOperand(sp, 10 * kPointerSize));
189 #if V8_TARGET_ARCH_S390X 191 __ ld(d8, MemOperand(sp));
192 __ ld(d9, MemOperand(sp, 1 * kDoubleSize));
193 __ ld(d10, MemOperand(sp, 2 * kDoubleSize));
194 __ ld(d11, MemOperand(sp, 3 * kDoubleSize));
195 __ ld(d12, MemOperand(sp, 4 * kDoubleSize));
196 __ ld(d13, MemOperand(sp, 5 * kDoubleSize));
197 __ ld(d14, MemOperand(sp, 6 * kDoubleSize));
198 __ ld(d15, MemOperand(sp, 7 * kDoubleSize));
199 __ la(sp, MemOperand(sp, 8 * kDoubleSize));
203 __ ld(d4, MemOperand(sp));
204 __ ld(d6, MemOperand(sp, kDoubleSize));
205 __ la(sp, MemOperand(sp, 2 * kDoubleSize));
212 void DirectCEntryStub::Generate(MacroAssembler* masm) {
218 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, Register target) {
219 if (FLAG_embedded_builtins) {
220 if (masm->root_array_available() &&
221 isolate()->ShouldLoadConstantsFromRootList()) {
225 __ IndirectLoadConstant(r1, GetCode());
226 __ AddP(r1, r1, Operand(Code::kHeaderSize - kHeapObjectTag));
231 #if ABI_USES_FUNCTION_DESCRIPTORS && !defined(USE_SIMULATOR) 233 __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(target, kPointerSize));
234 __ LoadP(target, MemOperand(target, 0));
241 __ call(GetCode(), RelocInfo::CODE_TARGET);
244 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
245 return ref0.address() - ref1.address();
252 static void CallApiFunctionAndReturn(MacroAssembler* masm,
253 Register function_address,
254 ExternalReference thunk_ref,
256 MemOperand* stack_space_operand,
257 MemOperand return_value_operand) {
258 Isolate* isolate = masm->isolate();
259 ExternalReference next_address =
260 ExternalReference::handle_scope_next_address(isolate);
261 const int kNextOffset = 0;
262 const int kLimitOffset = AddressOffset(
263 ExternalReference::handle_scope_limit_address(isolate), next_address);
264 const int kLevelOffset = AddressOffset(
265 ExternalReference::handle_scope_level_address(isolate), next_address);
268 DCHECK(function_address == r3 || function_address == r4);
269 Register scratch = r5;
271 __ Move(scratch, ExternalReference::is_profiling_address(isolate));
272 __ LoadlB(scratch, MemOperand(scratch, 0));
273 __ CmpP(scratch, Operand::Zero());
275 Label profiler_disabled;
276 Label end_profiler_check;
277 __ beq(&profiler_disabled, Label::kNear);
278 __ Move(scratch, thunk_ref);
279 __ b(&end_profiler_check, Label::kNear);
280 __ bind(&profiler_disabled);
281 __ LoadRR(scratch, function_address);
282 __ bind(&end_profiler_check);
289 __ Move(r9, next_address);
290 __ LoadP(r6, MemOperand(r9, kNextOffset));
291 __ LoadP(r7, MemOperand(r9, kLimitOffset));
292 __ LoadlW(r8, MemOperand(r9, kLevelOffset));
293 __ AddP(r8, Operand(1));
294 __ StoreW(r8, MemOperand(r9, kLevelOffset));
296 if (FLAG_log_timer_events) {
297 FrameScope frame(masm, StackFrame::MANUAL);
298 __ PushSafepointRegisters();
299 __ PrepareCallCFunction(1, r2);
300 __ Move(r2, ExternalReference::isolate_address(isolate));
301 __ CallCFunction(ExternalReference::log_enter_external_function(), 1);
302 __ PopSafepointRegisters();
308 DirectCEntryStub stub(isolate);
309 stub.GenerateCall(masm, scratch);
311 if (FLAG_log_timer_events) {
312 FrameScope frame(masm, StackFrame::MANUAL);
313 __ PushSafepointRegisters();
314 __ PrepareCallCFunction(1, r2);
315 __ Move(r2, ExternalReference::isolate_address(isolate));
316 __ CallCFunction(ExternalReference::log_leave_external_function(), 1);
317 __ PopSafepointRegisters();
320 Label promote_scheduled_exception;
321 Label delete_allocated_handles;
322 Label leave_exit_frame;
323 Label return_value_loaded;
326 __ LoadP(r2, return_value_operand);
327 __ bind(&return_value_loaded);
330 __ StoreP(r6, MemOperand(r9, kNextOffset));
331 if (__ emit_debug_code()) {
332 __ LoadlW(r3, MemOperand(r9, kLevelOffset));
334 __ Check(eq, AbortReason::kUnexpectedLevelAfterReturnFromApiCall);
336 __ SubP(r8, Operand(1));
337 __ StoreW(r8, MemOperand(r9, kLevelOffset));
338 __ CmpP(r7, MemOperand(r9, kLimitOffset));
339 __ bne(&delete_allocated_handles, Label::kNear);
342 __ bind(&leave_exit_frame);
344 if (stack_space_operand !=
nullptr) {
345 __ l(r6, *stack_space_operand);
347 __ mov(r6, Operand(stack_space));
349 __ LeaveExitFrame(
false, r6, stack_space_operand !=
nullptr);
352 __ Move(r7, ExternalReference::scheduled_exception_address(isolate));
353 __ LoadP(r7, MemOperand(r7));
354 __ CompareRoot(r7, RootIndex::kTheHoleValue);
355 __ bne(&promote_scheduled_exception, Label::kNear);
360 __ bind(&promote_scheduled_exception);
361 __ TailCallRuntime(Runtime::kPromoteScheduledException);
364 __ bind(&delete_allocated_handles);
365 __ StoreP(r7, MemOperand(r9, kLimitOffset));
367 __ PrepareCallCFunction(1, r7);
368 __ Move(r2, ExternalReference::isolate_address(isolate));
369 __ CallCFunction(ExternalReference::delete_handle_scope_extensions(), 1);
371 __ b(&leave_exit_frame, Label::kNear);
374 void CallApiCallbackStub::Generate(MacroAssembler* masm) {
387 Register call_data = r6;
388 Register holder = r4;
389 Register api_function_address = r3;
391 typedef FunctionCallbackArguments FCA;
393 STATIC_ASSERT(FCA::kArgsLength == 6);
394 STATIC_ASSERT(FCA::kNewTargetIndex == 5);
395 STATIC_ASSERT(FCA::kDataIndex == 4);
396 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
397 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
398 STATIC_ASSERT(FCA::kIsolateIndex == 1);
399 STATIC_ASSERT(FCA::kHolderIndex == 0);
402 __ PushRoot(RootIndex::kUndefinedValue);
407 Register scratch = call_data;
408 __ LoadRoot(scratch, RootIndex::kUndefinedValue);
414 __ Move(scratch, ExternalReference::isolate_address(masm->isolate()));
420 __ LoadRR(scratch, sp);
429 const int kApiStackSpace = 4;
430 const int kFunctionCallbackInfoOffset =
431 (kStackFrameExtraParamSlot + 1) * kPointerSize;
433 FrameScope frame_scope(masm, StackFrame::MANUAL);
434 __ EnterExitFrame(
false, kApiStackSpace);
436 DCHECK(api_function_address != r2 && scratch != r2);
439 __ AddP(r2, sp, Operand(kFunctionCallbackInfoOffset));
441 __ StoreP(scratch, MemOperand(r2, 0 * kPointerSize));
443 __ AddP(ip, scratch, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
444 __ StoreP(ip, MemOperand(r2, 1 * kPointerSize));
446 __ LoadImmP(ip, Operand(argc()));
447 __ StoreW(ip, MemOperand(r2, 2 * kPointerSize));
449 ExternalReference thunk_ref = ExternalReference::invoke_function_callback();
451 AllowExternalCallThatCantCauseGC scope(masm);
453 int return_value_offset = 2 + FCA::kReturnValueOffset;
454 MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
455 const int stack_space = argc() + FCA::kArgsLength + 1;
456 MemOperand* stack_space_operand =
nullptr;
457 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
458 stack_space_operand, return_value_operand);
461 void CallApiGetterStub::Generate(MacroAssembler* masm) {
463 int accessorInfoSlot = 0;
464 int apiStackSpace = 0;
467 STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
468 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
469 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
470 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
471 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
472 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
473 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
474 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
476 Register receiver = ApiGetterDescriptor::ReceiverRegister();
477 Register holder = ApiGetterDescriptor::HolderRegister();
478 Register callback = ApiGetterDescriptor::CallbackRegister();
479 Register scratch = r6;
480 DCHECK(!AreAliased(receiver, holder, callback, scratch));
482 Register api_function_address = r4;
486 __ LoadP(scratch, FieldMemOperand(callback, AccessorInfo::kDataOffset));
488 __ LoadRoot(scratch, RootIndex::kUndefinedValue);
489 __ Push(scratch, scratch);
490 __ Move(scratch, ExternalReference::isolate_address(isolate()));
491 __ Push(scratch, holder);
492 __ Push(Smi::zero());
493 __ LoadP(scratch, FieldMemOperand(callback, AccessorInfo::kNameOffset));
497 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
501 __ AddP(r3, r2, Operand(1 * kPointerSize));
515 if (ABI_PASSES_HANDLES_IN_REGS) {
516 accessorInfoSlot = kStackFrameExtraParamSlot + 1;
519 arg0Slot = kStackFrameExtraParamSlot + 1;
520 accessorInfoSlot = arg0Slot + 1;
524 FrameScope frame_scope(masm, StackFrame::MANUAL);
525 __ EnterExitFrame(
false, apiStackSpace);
527 if (!ABI_PASSES_HANDLES_IN_REGS) {
529 __ StoreP(r2, MemOperand(sp, arg0Slot * kPointerSize));
530 __ AddP(r2, sp, Operand(arg0Slot * kPointerSize));
535 __ StoreP(r3, MemOperand(sp, accessorInfoSlot * kPointerSize));
536 __ AddP(r3, sp, Operand(accessorInfoSlot * kPointerSize));
539 ExternalReference thunk_ref =
540 ExternalReference::invoke_accessor_getter_callback();
542 __ LoadP(scratch, FieldMemOperand(callback, AccessorInfo::kJsGetterOffset));
543 __ LoadP(api_function_address,
544 FieldMemOperand(scratch, Foreign::kForeignAddressOffset));
547 MemOperand return_value_operand(
548 fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
549 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
550 kStackUnwindSpace,
nullptr, return_value_operand);
558 #endif // V8_TARGET_ARCH_S390