blob: af9b2e1cf2703bd237c2a3073cc3c966edf315bd [file] [log] [blame]
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_CODEGEN_X64_INTERFACE_DESCRIPTORS_X64_INL_H_
#define V8_CODEGEN_X64_INTERFACE_DESCRIPTORS_X64_INL_H_
#if V8_TARGET_ARCH_X64
#include "src/codegen/interface-descriptors.h"
namespace v8 {
namespace internal {
constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
auto registers = RegisterArray(rax, rbx, rcx, rdx, rdi);
STATIC_ASSERT(registers.size() == kMaxBuiltinRegisterParams);
return registers;
}
#if DEBUG
template <typename DerivedDescriptor>
void StaticCallInterfaceDescriptor<DerivedDescriptor>::
VerifyArgumentRegisterCount(CallInterfaceDescriptorData* data,
int nof_expected_args) {
RegList allocatable_regs = data->allocatable_registers();
if (nof_expected_args >= 1) DCHECK(allocatable_regs.has(arg_reg_1));
if (nof_expected_args >= 2) DCHECK(allocatable_regs.has(arg_reg_2));
if (nof_expected_args >= 3) DCHECK(allocatable_regs.has(arg_reg_3));
if (nof_expected_args >= 4) DCHECK(allocatable_regs.has(arg_reg_4));
// Additional arguments are passed on the stack.
}
#endif // DEBUG
// static
constexpr auto WriteBarrierDescriptor::registers() {
#if V8_TARGET_OS_WIN
return RegisterArray(rdi, r8, rcx, rax, r9, rdx, rsi);
#else
return RegisterArray(rdi, rbx, rdx, rcx, rax, rsi);
#endif // V8_TARGET_OS_WIN
}
#ifdef V8_IS_TSAN
// static
constexpr auto TSANStoreDescriptor::registers() {
return RegisterArray(arg_reg_1, arg_reg_2, kReturnRegister0);
}
// static
constexpr auto TSANLoadDescriptor::registers() {
return RegisterArray(arg_reg_1, kReturnRegister0);
}
#endif // V8_IS_TSAN
// static
constexpr auto DynamicCheckMapsDescriptor::registers() {
#if V8_TARGET_OS_WIN
return RegisterArray(kReturnRegister0, arg_reg_1, arg_reg_2, arg_reg_3,
kRuntimeCallFunctionRegister, kContextRegister);
#else
STATIC_ASSERT(kContextRegister == arg_reg_2);
return RegisterArray(kReturnRegister0, arg_reg_1, arg_reg_2, arg_reg_3,
kRuntimeCallFunctionRegister);
#endif // V8_TARGET_OS_WIN
}
// static
constexpr auto DynamicCheckMapsWithFeedbackVectorDescriptor::registers() {
#if V8_TARGET_OS_WIN
return RegisterArray(kReturnRegister0, arg_reg_1, arg_reg_2, arg_reg_3,
kRuntimeCallFunctionRegister, kContextRegister);
#else
STATIC_ASSERT(kContextRegister == arg_reg_2);
return RegisterArray(kReturnRegister0, arg_reg_1, arg_reg_2, arg_reg_3,
kRuntimeCallFunctionRegister);
#endif // V8_TARGET_OS_WIN
}
// static
constexpr Register LoadDescriptor::ReceiverRegister() { return rdx; }
// static
constexpr Register LoadDescriptor::NameRegister() { return rcx; }
// static
constexpr Register LoadDescriptor::SlotRegister() { return rax; }
// static
constexpr Register LoadWithVectorDescriptor::VectorRegister() { return rbx; }
// static
constexpr Register KeyedLoadBaselineDescriptor::ReceiverRegister() {
return rdx;
}
// static
constexpr Register KeyedLoadBaselineDescriptor::NameRegister() {
return kInterpreterAccumulatorRegister;
}
// static
constexpr Register KeyedLoadBaselineDescriptor::SlotRegister() { return rcx; }
// static
constexpr Register KeyedLoadWithVectorDescriptor::VectorRegister() {
return rbx;
}
// static
constexpr Register KeyedHasICBaselineDescriptor::ReceiverRegister() {
return kInterpreterAccumulatorRegister;
}
// static
constexpr Register KeyedHasICBaselineDescriptor::NameRegister() { return rdx; }
// static
constexpr Register KeyedHasICBaselineDescriptor::SlotRegister() { return rcx; }
// static
constexpr Register KeyedHasICWithVectorDescriptor::VectorRegister() {
return rbx;
}
// static
constexpr Register
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
return rdi;
}
// static
constexpr Register StoreDescriptor::ReceiverRegister() { return rdx; }
// static
constexpr Register StoreDescriptor::NameRegister() { return rcx; }
// static
constexpr Register StoreDescriptor::ValueRegister() { return rax; }
// static
constexpr Register StoreDescriptor::SlotRegister() { return rdi; }
// static
constexpr Register StoreWithVectorDescriptor::VectorRegister() { return rbx; }
// static
constexpr Register StoreTransitionDescriptor::MapRegister() { return r11; }
// static
constexpr Register ApiGetterDescriptor::HolderRegister() { return rcx; }
// static
constexpr Register ApiGetterDescriptor::CallbackRegister() { return rbx; }
// static
constexpr Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; }
// static
constexpr Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; }
// static
constexpr Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() {
return rbx;
}
// static
constexpr Register BaselineLeaveFrameDescriptor::WeightRegister() {
return rcx;
}
// static
constexpr Register TypeConversionDescriptor::ArgumentRegister() { return rax; }
// static
constexpr auto TypeofDescriptor::registers() { return RegisterArray(rax); }
// static
constexpr auto CallTrampolineDescriptor::registers() {
// rax : number of arguments
// rdi : the target to call
return RegisterArray(rdi, rax);
}
// static
constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() {
// rdi : the source
// rax : the excluded property count
return RegisterArray(rdi, rax);
}
// static
constexpr auto
CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() {
// rdi : the source
// rax : the excluded property count
// rcx : the excluded property base
return RegisterArray(rdi, rax, rcx);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
// rax : number of arguments (on the stack)
// rdi : the target to call
// rcx : arguments list length (untagged)
// rbx : arguments list (FixedArray)
return RegisterArray(rdi, rax, rcx, rbx);
}
// static
constexpr auto CallForwardVarargsDescriptor::registers() {
// rax : number of arguments
// rcx : start index (to support rest parameters)
// rdi : the target to call
return RegisterArray(rdi, rax, rcx);
}
// static
constexpr auto CallFunctionTemplateDescriptor::registers() {
// rdx: the function template info
// rcx: number of arguments (on the stack)
return RegisterArray(rdx, rcx);
}
// static
constexpr auto CallWithSpreadDescriptor::registers() {
// rax : number of arguments (on the stack)
// rdi : the target to call
// rbx : the object to spread
return RegisterArray(rdi, rax, rbx);
}
// static
constexpr auto CallWithArrayLikeDescriptor::registers() {
// rdi : the target to call
// rbx : the arguments list
return RegisterArray(rdi, rbx);
}
// static
constexpr auto ConstructVarargsDescriptor::registers() {
// rax : number of arguments (on the stack)
// rdi : the target to call
// rdx : the new target
// rcx : arguments list length (untagged)
// rbx : arguments list (FixedArray)
return RegisterArray(rdi, rdx, rax, rcx, rbx);
}
// static
constexpr auto ConstructForwardVarargsDescriptor::registers() {
// rax : number of arguments
// rdx : the new target
// rcx : start index (to support rest parameters)
// rdi : the target to call
return RegisterArray(rdi, rdx, rax, rcx);
}
// static
constexpr auto ConstructWithSpreadDescriptor::registers() {
// rax : number of arguments (on the stack)
// rdi : the target to call
// rdx : the new target
// rbx : the object to spread
return RegisterArray(rdi, rdx, rax, rbx);
}
// static
constexpr auto ConstructWithArrayLikeDescriptor::registers() {
// rdi : the target to call
// rdx : the new target
// rbx : the arguments list
return RegisterArray(rdi, rdx, rbx);
}
// static
constexpr auto ConstructStubDescriptor::registers() {
// rax : number of arguments
// rdx : the new target
// rdi : the target to call
// rbx : allocation site or undefined
return RegisterArray(rdi, rdx, rax, rbx);
}
// static
constexpr auto AbortDescriptor::registers() { return RegisterArray(rdx); }
// static
constexpr auto CompareDescriptor::registers() {
return RegisterArray(rdx, rax);
}
// static
constexpr auto BinaryOpDescriptor::registers() {
return RegisterArray(rdx, rax);
}
// static
constexpr auto Compare_BaselineDescriptor::registers() {
return RegisterArray(rdx, rax, rbx);
}
// static
constexpr auto BinaryOp_BaselineDescriptor::registers() {
return RegisterArray(rdx, rax, rbx);
}
// static
constexpr auto BinarySmiOp_BaselineDescriptor::registers() {
return RegisterArray(rax, rdx, rbx);
}
// static
constexpr auto ApiCallbackDescriptor::registers() {
return RegisterArray(rdx, // api function address
rcx, // argument count (not including receiver)
rbx, // call data
rdi); // holder
}
// static
constexpr auto InterpreterDispatchDescriptor::registers() {
return RegisterArray(
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister);
}
// static
constexpr auto InterpreterPushArgsThenCallDescriptor::registers() {
return RegisterArray(rax, // argument count
rbx, // address of first argument
rdi); // the target callable to be call
}
// static
constexpr auto InterpreterPushArgsThenConstructDescriptor::registers() {
return RegisterArray(
rax, // argument count
rcx, // address of first argument
rdi, // constructor to call
rdx, // new target
rbx); // allocation site feedback if available, undefined otherwise
}
// static
constexpr auto ResumeGeneratorDescriptor::registers() {
return RegisterArray(
rax, // the value to pass to the generator
rdx); // the JSGeneratorObject / JSAsyncGeneratorObject to resume
}
// static
constexpr auto RunMicrotasksEntryDescriptor::registers() {
return RegisterArray(arg_reg_1, arg_reg_2);
}
} // namespace internal
} // namespace v8
#endif // V8_TARGET_ARCH_X64
#endif // V8_CODEGEN_X64_INTERFACE_DESCRIPTORS_X64_INL_H_