// 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() { #ifdef 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 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 return RegisterArray(rdi, rdx, rax); } // 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_