blob: 2ac0ee94d3de7da757c7748da9cf66cd6dcbad23 [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_IA32_INTERFACE_DESCRIPTORS_IA32_INL_H_
#define V8_CODEGEN_IA32_INTERFACE_DESCRIPTORS_IA32_INL_H_
#if V8_TARGET_ARCH_IA32
#include "src/codegen/interface-descriptors.h"
namespace v8 {
namespace internal {
constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
auto registers = RegisterArray(eax, ecx, edx, edi);
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(esi));
if (nof_expected_args >= 2) DCHECK(allocatable_regs.has(edi));
// Additional arguments are passed on the stack.
}
#endif // DEBUG
// static
constexpr auto WriteBarrierDescriptor::registers() {
return RegisterArray(edi, ecx, edx, esi, kReturnRegister0);
}
// static
constexpr Register LoadDescriptor::ReceiverRegister() { return edx; }
// static
constexpr Register LoadDescriptor::NameRegister() { return ecx; }
// static
constexpr Register LoadDescriptor::SlotRegister() { return eax; }
// static
constexpr Register LoadWithVectorDescriptor::VectorRegister() { return no_reg; }
// static
constexpr Register KeyedLoadBaselineDescriptor::ReceiverRegister() {
return edx;
}
// static
constexpr Register KeyedLoadBaselineDescriptor::NameRegister() {
return kInterpreterAccumulatorRegister;
}
// static
constexpr Register KeyedLoadBaselineDescriptor::SlotRegister() { return ecx; }
// static
constexpr Register KeyedLoadWithVectorDescriptor::VectorRegister() {
return no_reg;
}
// static
constexpr Register KeyedHasICBaselineDescriptor::ReceiverRegister() {
return kInterpreterAccumulatorRegister;
}
// static
constexpr Register KeyedHasICBaselineDescriptor::NameRegister() { return edx; }
// static
constexpr Register KeyedHasICBaselineDescriptor::SlotRegister() { return ecx; }
// static
constexpr Register KeyedHasICWithVectorDescriptor::VectorRegister() {
return no_reg;
}
// static
constexpr Register
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
return edi;
}
// static
constexpr Register StoreDescriptor::ReceiverRegister() { return edx; }
// static
constexpr Register StoreDescriptor::NameRegister() { return ecx; }
// static
constexpr Register StoreDescriptor::ValueRegister() { return no_reg; }
// static
constexpr Register StoreDescriptor::SlotRegister() { return no_reg; }
// static
constexpr Register StoreWithVectorDescriptor::VectorRegister() {
return no_reg;
}
// static
constexpr Register StoreTransitionDescriptor::MapRegister() { return edi; }
// static
constexpr Register ApiGetterDescriptor::HolderRegister() { return ecx; }
// static
constexpr Register ApiGetterDescriptor::CallbackRegister() { return eax; }
// static
constexpr Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; }
// static
constexpr Register GrowArrayElementsDescriptor::KeyRegister() { return ecx; }
// static
constexpr Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() {
return esi;
}
// static
constexpr Register BaselineLeaveFrameDescriptor::WeightRegister() {
return edi;
}
// static
constexpr Register TypeConversionDescriptor::ArgumentRegister() { return eax; }
// static
constexpr auto TypeofDescriptor::registers() { return RegisterArray(eax); }
// static
constexpr auto CallTrampolineDescriptor::registers() {
// eax : number of arguments
// edi : the target to call
return RegisterArray(edi, eax);
}
// static
constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() {
// edi : the source
// eax : the excluded property count
return RegisterArray(edi, eax);
}
// static
constexpr auto
CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() {
// edi : the source
// eax : the excluded property count
// ecx : the excluded property base
return RegisterArray(edi, eax, ecx);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
// eax : number of arguments (on the stack)
// edi : the target to call
// ecx : arguments list length (untagged)
// On the stack : arguments list (FixedArray)
return RegisterArray(edi, eax, ecx);
}
// static
constexpr auto CallForwardVarargsDescriptor::registers() {
// eax : number of arguments
// ecx : start index (to support rest parameters)
// edi : the target to call
return RegisterArray(edi, eax, ecx);
}
// static
constexpr auto CallFunctionTemplateDescriptor::registers() {
// edx : function template info
// ecx : number of arguments (on the stack)
return RegisterArray(edx, ecx);
}
// static
constexpr auto CallWithSpreadDescriptor::registers() {
// eax : number of arguments (on the stack)
// edi : the target to call
// ecx : the object to spread
return RegisterArray(edi, eax, ecx);
}
// static
constexpr auto CallWithArrayLikeDescriptor::registers() {
// edi : the target to call
// edx : the arguments list
return RegisterArray(edi, edx);
}
// static
constexpr auto ConstructVarargsDescriptor::registers() {
// eax : number of arguments (on the stack)
// edi : the target to call
// edx : the new target
// ecx : arguments list length (untagged)
// On the stack : arguments list (FixedArray)
return RegisterArray(edi, edx, eax, ecx);
}
// static
constexpr auto ConstructForwardVarargsDescriptor::registers() {
// eax : number of arguments
// edx : the new target
// ecx : start index (to support rest parameters)
// edi : the target to call
return RegisterArray(edi, edx, eax, ecx);
}
// static
constexpr auto ConstructWithSpreadDescriptor::registers() {
// eax : number of arguments (on the stack)
// edi : the target to call
// edx : the new target
// ecx : the object to spread
return RegisterArray(edi, edx, eax, ecx);
}
// static
constexpr auto ConstructWithArrayLikeDescriptor::registers() {
// edi : the target to call
// edx : the new target
// ecx : the arguments list
return RegisterArray(edi, edx, ecx);
}
// static
constexpr auto ConstructStubDescriptor::registers() {
// eax : number of arguments
// edx : the new target
// edi : the target to call
// ecx : allocation site or undefined
// TODO(jgruber): Remove the unused allocation site parameter.
return RegisterArray(edi, edx, eax, ecx);
}
// static
constexpr auto AbortDescriptor::registers() { return RegisterArray(edx); }
// static
constexpr auto CompareDescriptor::registers() {
return RegisterArray(edx, eax);
}
// static
constexpr auto Compare_BaselineDescriptor::registers() {
return RegisterArray(edx, eax, ecx);
}
// static
constexpr auto BinaryOpDescriptor::registers() {
return RegisterArray(edx, eax);
}
// static
constexpr auto BinaryOp_BaselineDescriptor::registers() {
return RegisterArray(edx, eax, ecx);
}
// static
constexpr auto BinarySmiOp_BaselineDescriptor::registers() {
return RegisterArray(eax, edx, ecx);
}
// static
constexpr auto ApiCallbackDescriptor::registers() {
return RegisterArray(edx, // kApiFunctionAddress
ecx, // kArgc
eax, // kCallData
edi); // kHolder
}
// static
constexpr auto InterpreterDispatchDescriptor::registers() {
return RegisterArray(
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister);
}
// static
constexpr auto InterpreterPushArgsThenCallDescriptor::registers() {
return RegisterArray(eax, // argument count
ecx, // address of first argument
edi); // the target callable to be call
}
// static
constexpr auto InterpreterPushArgsThenConstructDescriptor::registers() {
return RegisterArray(eax, // argument count
ecx); // address of first argument
}
// static
constexpr auto ResumeGeneratorDescriptor::registers() {
return RegisterArray(eax, // the value to pass to the generator
edx); // the JSGeneratorObject to resume
}
// static
constexpr auto RunMicrotasksEntryDescriptor::registers() {
return RegisterArray();
}
// static
constexpr auto WasmFloat32ToNumberDescriptor::registers() {
// Work around using eax, whose register code is 0, and leads to the FP
// parameter being passed via xmm0, which is not allocatable on ia32.
return RegisterArray(ecx);
}
// static
constexpr auto WasmFloat64ToNumberDescriptor::registers() {
// Work around using eax, whose register code is 0, and leads to the FP
// parameter being passed via xmm0, which is not allocatable on ia32.
return RegisterArray(ecx);
}
} // namespace internal
} // namespace v8
#endif // V8_TARGET_ARCH_IA32
#endif // V8_CODEGEN_IA32_INTERFACE_DESCRIPTORS_IA32_INL_H_