5 #if V8_TARGET_ARCH_MIPS64 7 #include "src/api-arguments.h" 8 #include "src/bootstrapper.h" 9 #include "src/code-stubs.h" 10 #include "src/frame-constants.h" 11 #include "src/frames.h" 12 #include "src/ic/ic.h" 13 #include "src/ic/stub-cache.h" 14 #include "src/isolate.h" 15 #include "src/macro-assembler.h" 16 #include "src/objects/api-callbacks.h" 17 #include "src/regexp/jsregexp.h" 18 #include "src/regexp/regexp-macro-assembler.h" 19 #include "src/runtime/runtime.h" 21 #include "src/mips64/code-stubs-mips64.h" 26 #define __ ACCESS_MASM(masm) 28 void JSEntryStub::Generate(MacroAssembler* masm) {
29 Label invoke, handler_entry, exit;
30 Isolate* isolate = masm->isolate();
33 NoRootArrayScope no_root_array(masm);
48 __ MultiPush(kCalleeSaved | ra.bit());
51 __ MultiPushFPU(kCalleeSavedFPU);
53 __ Move(kDoubleRegZero, 0.0);
58 __ InitializeRootRegister();
62 __ li(a7, Operand(-1));
63 StackFrame::Type marker = type();
64 __ li(a6, Operand(StackFrame::TypeToMarker(marker)));
65 __ li(a5, Operand(StackFrame::TypeToMarker(marker)));
66 ExternalReference c_entry_fp =
67 ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, isolate);
68 __ li(a4, Operand(c_entry_fp));
69 __ Ld(a4, MemOperand(a4));
70 __ Push(a7, a6, a5, a4);
72 __ daddiu(fp, sp, -EntryFrameConstants::kCallerFPOffset);
91 Label non_outermost_js;
92 ExternalReference js_entry_sp =
93 ExternalReference::Create(IsolateAddressId::kJSEntrySPAddress, isolate);
94 __ li(a5, js_entry_sp);
95 __ Ld(a6, MemOperand(a5));
96 __ Branch(&non_outermost_js, ne, a6, Operand(zero_reg));
97 __ Sd(fp, MemOperand(a5));
98 __ li(a4, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME));
102 __ bind(&non_outermost_js);
103 __ li(a4, Operand(StackFrame::INNER_JSENTRY_FRAME));
110 __ bind(&handler_entry);
111 handler_offset_ = handler_entry.pos();
116 __ li(a4, ExternalReference::Create(
117 IsolateAddressId::kPendingExceptionAddress, isolate));
118 __ Sd(v0, MemOperand(a4));
119 __ LoadRoot(v0, RootIndex::kException);
125 __ PushStackHandler();
148 __ Call(EntryTrampoline(), RelocInfo::CODE_TARGET);
151 __ PopStackHandler();
155 Label non_outermost_js_2;
157 __ Branch(&non_outermost_js_2, ne, a5,
158 Operand(StackFrame::OUTERMOST_JSENTRY_FRAME));
159 __ li(a5, ExternalReference(js_entry_sp));
160 __ Sd(zero_reg, MemOperand(a5));
161 __ bind(&non_outermost_js_2);
166 ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, isolate));
167 __ Sd(a5, MemOperand(a4));
170 __ daddiu(sp, sp, -EntryFrameConstants::kCallerFPOffset);
173 __ MultiPopFPU(kCalleeSavedFPU);
176 __ MultiPop(kCalleeSaved | ra.bit());
181 void DirectCEntryStub::Generate(MacroAssembler* masm) {
187 __ daddiu(sp, sp, -kCArgsSlotsSize);
190 __ Sd(ra, MemOperand(sp, kCArgsSlotsSize));
192 __ Ld(t9, MemOperand(sp, kCArgsSlotsSize));
194 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
198 __ Uld(a4, MemOperand(t9));
199 __ Assert(ne, AbortReason::kReceivedInvalidReturnAddress, a4,
200 Operand(reinterpret_cast<uint64_t>(kZapValue)));
206 void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
208 if (FLAG_embedded_builtins) {
209 if (masm->root_array_available() &&
210 isolate()->ShouldLoadConstantsFromRootList()) {
214 __ IndirectLoadConstant(kScratchReg, GetCode());
215 __ Daddu(kScratchReg, kScratchReg,
216 Operand(Code::kHeaderSize - kHeapObjectTag));
217 __ Call(kScratchReg);
222 reinterpret_cast<intptr_t
>(GetCode().location());
224 __ li(kScratchReg, Operand(loc, RelocInfo::CODE_TARGET), CONSTANT_SIZE);
225 __ Call(kScratchReg);
228 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
229 int64_t offset = (ref0.address() - ref1.address());
230 DCHECK(static_cast<int>(offset) == offset);
231 return static_cast<int>(offset);
239 static void CallApiFunctionAndReturn(MacroAssembler* masm,
240 Register function_address,
241 ExternalReference thunk_ref,
243 int32_t stack_space_offset,
244 MemOperand return_value_operand) {
245 Isolate* isolate = masm->isolate();
246 ExternalReference next_address =
247 ExternalReference::handle_scope_next_address(isolate);
248 const int kNextOffset = 0;
249 const int kLimitOffset = AddressOffset(
250 ExternalReference::handle_scope_limit_address(isolate), next_address);
251 const int kLevelOffset = AddressOffset(
252 ExternalReference::handle_scope_level_address(isolate), next_address);
254 DCHECK(function_address == a1 || function_address == a2);
256 Label profiler_disabled;
257 Label end_profiler_check;
258 __ li(t9, ExternalReference::is_profiling_address(isolate));
259 __ Lb(t9, MemOperand(t9, 0));
260 __ Branch(&profiler_disabled, eq, t9, Operand(zero_reg));
263 __ li(t9, thunk_ref);
264 __ jmp(&end_profiler_check);
266 __ bind(&profiler_disabled);
267 __ mov(t9, function_address);
268 __ bind(&end_profiler_check);
271 __ li(s5, next_address);
272 __ Ld(s0, MemOperand(s5, kNextOffset));
273 __ Ld(s1, MemOperand(s5, kLimitOffset));
274 __ Lw(s2, MemOperand(s5, kLevelOffset));
275 __ Addu(s2, s2, Operand(1));
276 __ Sw(s2, MemOperand(s5, kLevelOffset));
278 if (FLAG_log_timer_events) {
279 FrameScope frame(masm, StackFrame::MANUAL);
280 __ PushSafepointRegisters();
281 __ PrepareCallCFunction(1, a0);
282 __ li(a0, ExternalReference::isolate_address(isolate));
283 __ CallCFunction(ExternalReference::log_enter_external_function(), 1);
284 __ PopSafepointRegisters();
290 DirectCEntryStub stub(isolate);
291 stub.GenerateCall(masm, t9);
293 if (FLAG_log_timer_events) {
294 FrameScope frame(masm, StackFrame::MANUAL);
295 __ PushSafepointRegisters();
296 __ PrepareCallCFunction(1, a0);
297 __ li(a0, ExternalReference::isolate_address(isolate));
298 __ CallCFunction(ExternalReference::log_leave_external_function(), 1);
299 __ PopSafepointRegisters();
302 Label promote_scheduled_exception;
303 Label delete_allocated_handles;
304 Label leave_exit_frame;
305 Label return_value_loaded;
308 __ Ld(v0, return_value_operand);
309 __ bind(&return_value_loaded);
313 __ Sd(s0, MemOperand(s5, kNextOffset));
314 if (__ emit_debug_code()) {
315 __ Lw(a1, MemOperand(s5, kLevelOffset));
316 __ Check(eq, AbortReason::kUnexpectedLevelAfterReturnFromApiCall, a1,
319 __ Subu(s2, s2, Operand(1));
320 __ Sw(s2, MemOperand(s5, kLevelOffset));
321 __ Ld(kScratchReg, MemOperand(s5, kLimitOffset));
322 __ Branch(&delete_allocated_handles, ne, s1, Operand(kScratchReg));
325 __ bind(&leave_exit_frame);
327 if (stack_space_offset != kInvalidStackOffset) {
328 DCHECK_EQ(kCArgsSlotsSize, 0);
329 __ Ld(s0, MemOperand(sp, stack_space_offset));
331 __ li(s0, Operand(stack_space));
333 __ LeaveExitFrame(
false, s0, NO_EMIT_RETURN,
334 stack_space_offset != kInvalidStackOffset);
337 __ LoadRoot(a4, RootIndex::kTheHoleValue);
338 __ li(kScratchReg, ExternalReference::scheduled_exception_address(isolate));
339 __ Ld(a5, MemOperand(kScratchReg));
340 __ Branch(&promote_scheduled_exception, ne, a4, Operand(a5));
345 __ bind(&promote_scheduled_exception);
346 __ TailCallRuntime(Runtime::kPromoteScheduledException);
349 __ bind(&delete_allocated_handles);
350 __ Sd(s1, MemOperand(s5, kLimitOffset));
353 __ PrepareCallCFunction(1, s1);
354 __ li(a0, ExternalReference::isolate_address(isolate));
355 __ CallCFunction(ExternalReference::delete_handle_scope_extensions(), 1);
357 __ jmp(&leave_exit_frame);
360 void CallApiCallbackStub::Generate(MacroAssembler* masm) {
373 Register call_data = a4;
374 Register holder = a2;
375 Register api_function_address = a1;
377 typedef FunctionCallbackArguments FCA;
379 STATIC_ASSERT(FCA::kArgsLength == 6);
380 STATIC_ASSERT(FCA::kNewTargetIndex == 5);
381 STATIC_ASSERT(FCA::kDataIndex == 4);
382 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
383 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
384 STATIC_ASSERT(FCA::kIsolateIndex == 1);
385 STATIC_ASSERT(FCA::kHolderIndex == 0);
388 __ PushRoot(RootIndex::kUndefinedValue);
393 Register scratch = call_data;
394 __ LoadRoot(scratch, RootIndex::kUndefinedValue);
396 __ Push(scratch, scratch);
397 __ li(scratch, ExternalReference::isolate_address(masm->isolate()));
399 __ Push(scratch, holder);
406 const int kApiStackSpace = 3;
408 FrameScope frame_scope(masm, StackFrame::MANUAL);
409 __ EnterExitFrame(
false, kApiStackSpace);
411 DCHECK(api_function_address != a0 && scratch != a0);
414 __ Daddu(a0, sp, Operand(1 * kPointerSize));
416 __ Sd(scratch, MemOperand(a0, 0 * kPointerSize));
418 __ Daddu(kScratchReg, scratch,
419 Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
420 __ Sd(kScratchReg, MemOperand(a0, 1 * kPointerSize));
424 __ li(kScratchReg, Operand(argc()));
425 __ Sw(kScratchReg, MemOperand(a0, 2 * kPointerSize));
427 ExternalReference thunk_ref = ExternalReference::invoke_function_callback();
429 AllowExternalCallThatCantCauseGC scope(masm);
431 int return_value_offset = 2 + FCA::kReturnValueOffset;
432 MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
433 const int stack_space = argc() + FCA::kArgsLength + 1;
435 const int32_t stack_space_offset = kInvalidStackOffset;
436 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
437 stack_space_offset, return_value_operand);
441 void CallApiGetterStub::Generate(MacroAssembler* masm) {
444 STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
445 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
446 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
447 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
448 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
449 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
450 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
451 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
453 Register receiver = ApiGetterDescriptor::ReceiverRegister();
454 Register holder = ApiGetterDescriptor::HolderRegister();
455 Register callback = ApiGetterDescriptor::CallbackRegister();
456 Register scratch = a4;
457 DCHECK(!AreAliased(receiver, holder, callback, scratch));
459 Register api_function_address = a2;
462 typedef PropertyCallbackArguments PCA;
463 __ Dsubu(sp, sp, (PCA::kArgsLength + 1) * kPointerSize);
464 __ Sd(receiver, MemOperand(sp, (PCA::kThisIndex + 1) * kPointerSize));
465 __ Ld(scratch, FieldMemOperand(callback, AccessorInfo::kDataOffset));
466 __ Sd(scratch, MemOperand(sp, (PCA::kDataIndex + 1) * kPointerSize));
467 __ LoadRoot(scratch, RootIndex::kUndefinedValue);
468 __ Sd(scratch, MemOperand(sp, (PCA::kReturnValueOffset + 1) * kPointerSize));
469 __ Sd(scratch, MemOperand(sp, (PCA::kReturnValueDefaultValueIndex + 1) *
471 __ li(scratch, ExternalReference::isolate_address(isolate()));
472 __ Sd(scratch, MemOperand(sp, (PCA::kIsolateIndex + 1) * kPointerSize));
473 __ Sd(holder, MemOperand(sp, (PCA::kHolderIndex + 1) * kPointerSize));
475 DCHECK_NULL(Smi::kZero);
477 MemOperand(sp, (PCA::kShouldThrowOnErrorIndex + 1) * kPointerSize));
478 __ Ld(scratch, FieldMemOperand(callback, AccessorInfo::kNameOffset));
479 __ Sd(scratch, MemOperand(sp, 0 * kPointerSize));
482 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
486 __ Daddu(a1, a0, Operand(1 * kPointerSize));
488 const int kApiStackSpace = 1;
489 FrameScope frame_scope(masm, StackFrame::MANUAL);
490 __ EnterExitFrame(
false, kApiStackSpace);
494 __ Sd(a1, MemOperand(sp, 1 * kPointerSize));
495 __ Daddu(a1, sp, Operand(1 * kPointerSize));
498 ExternalReference thunk_ref =
499 ExternalReference::invoke_accessor_getter_callback();
501 __ Ld(scratch, FieldMemOperand(callback, AccessorInfo::kJsGetterOffset));
502 __ Ld(api_function_address,
503 FieldMemOperand(scratch, Foreign::kForeignAddressOffset));
506 MemOperand return_value_operand(
507 fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
508 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
509 kStackUnwindSpace, kInvalidStackOffset,
510 return_value_operand);
518 #endif // V8_TARGET_ARCH_MIPS64