1// Copyright 2021 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef V8_CODEGEN_IA32_INTERFACE_DESCRIPTORS_IA32_INL_H_ 6#define V8_CODEGEN_IA32_INTERFACE_DESCRIPTORS_IA32_INL_H_ 7 8#if V8_TARGET_ARCH_IA32 9 10#include "src/codegen/interface-descriptors.h" 11 12namespace v8 { 13namespace internal { 14 15constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() { 16 auto registers = RegisterArray(eax, ecx, edx, edi); 17 STATIC_ASSERT(registers.size() == kMaxBuiltinRegisterParams); 18 return registers; 19} 20 21#if DEBUG 22template <typename DerivedDescriptor> 23void StaticCallInterfaceDescriptor<DerivedDescriptor>:: 24 VerifyArgumentRegisterCount(CallInterfaceDescriptorData* data, 25 int nof_expected_args) { 26 RegList allocatable_regs = data->allocatable_registers(); 27 if (nof_expected_args >= 1) DCHECK(allocatable_regs.has(esi)); 28 if (nof_expected_args >= 2) DCHECK(allocatable_regs.has(edi)); 29 // Additional arguments are passed on the stack. 30} 31#endif // DEBUG 32 33// static 34constexpr auto WriteBarrierDescriptor::registers() { 35 return RegisterArray(edi, ecx, edx, esi, kReturnRegister0); 36} 37 38// static 39constexpr Register LoadDescriptor::ReceiverRegister() { return edx; } 40// static 41constexpr Register LoadDescriptor::NameRegister() { return ecx; } 42// static 43constexpr Register LoadDescriptor::SlotRegister() { return eax; } 44 45// static 46constexpr Register LoadWithVectorDescriptor::VectorRegister() { return no_reg; } 47 48// static 49constexpr Register KeyedLoadBaselineDescriptor::ReceiverRegister() { 50 return edx; 51} 52// static 53constexpr Register KeyedLoadBaselineDescriptor::NameRegister() { 54 return kInterpreterAccumulatorRegister; 55} 56// static 57constexpr Register KeyedLoadBaselineDescriptor::SlotRegister() { return ecx; } 58 59// static 60constexpr Register KeyedLoadWithVectorDescriptor::VectorRegister() { 61 return no_reg; 62} 63 64// static 65constexpr Register KeyedHasICBaselineDescriptor::ReceiverRegister() { 66 return kInterpreterAccumulatorRegister; 67} 68// static 69constexpr Register KeyedHasICBaselineDescriptor::NameRegister() { return edx; } 70// static 71constexpr Register KeyedHasICBaselineDescriptor::SlotRegister() { return ecx; } 72 73// static 74constexpr Register KeyedHasICWithVectorDescriptor::VectorRegister() { 75 return no_reg; 76} 77 78// static 79constexpr Register 80LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() { 81 return edi; 82} 83 84// static 85constexpr Register StoreDescriptor::ReceiverRegister() { return edx; } 86// static 87constexpr Register StoreDescriptor::NameRegister() { return ecx; } 88// static 89constexpr Register StoreDescriptor::ValueRegister() { return no_reg; } 90// static 91constexpr Register StoreDescriptor::SlotRegister() { return no_reg; } 92 93// static 94constexpr Register StoreWithVectorDescriptor::VectorRegister() { 95 return no_reg; 96} 97 98// static 99constexpr Register StoreTransitionDescriptor::MapRegister() { return edi; } 100 101// static 102constexpr Register ApiGetterDescriptor::HolderRegister() { return ecx; } 103// static 104constexpr Register ApiGetterDescriptor::CallbackRegister() { return eax; } 105 106// static 107constexpr Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; } 108// static 109constexpr Register GrowArrayElementsDescriptor::KeyRegister() { return ecx; } 110 111// static 112constexpr Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() { 113 return esi; 114} 115// static 116constexpr Register BaselineLeaveFrameDescriptor::WeightRegister() { 117 return edi; 118} 119 120// static 121constexpr Register TypeConversionDescriptor::ArgumentRegister() { return eax; } 122 123// static 124constexpr auto TypeofDescriptor::registers() { return RegisterArray(eax); } 125 126// static 127constexpr auto CallTrampolineDescriptor::registers() { 128 // eax : number of arguments 129 // edi : the target to call 130 return RegisterArray(edi, eax); 131} 132 133// static 134constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() { 135 // edi : the source 136 // eax : the excluded property count 137 return RegisterArray(edi, eax); 138} 139 140// static 141constexpr auto 142CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() { 143 // edi : the source 144 // eax : the excluded property count 145 // ecx : the excluded property base 146 return RegisterArray(edi, eax, ecx); 147} 148 149// static 150constexpr auto CallVarargsDescriptor::registers() { 151 // eax : number of arguments (on the stack) 152 // edi : the target to call 153 // ecx : arguments list length (untagged) 154 // On the stack : arguments list (FixedArray) 155 return RegisterArray(edi, eax, ecx); 156} 157 158// static 159constexpr auto CallForwardVarargsDescriptor::registers() { 160 // eax : number of arguments 161 // ecx : start index (to support rest parameters) 162 // edi : the target to call 163 return RegisterArray(edi, eax, ecx); 164} 165 166// static 167constexpr auto CallFunctionTemplateDescriptor::registers() { 168 // edx : function template info 169 // ecx : number of arguments (on the stack) 170 return RegisterArray(edx, ecx); 171} 172 173// static 174constexpr auto CallWithSpreadDescriptor::registers() { 175 // eax : number of arguments (on the stack) 176 // edi : the target to call 177 // ecx : the object to spread 178 return RegisterArray(edi, eax, ecx); 179} 180 181// static 182constexpr auto CallWithArrayLikeDescriptor::registers() { 183 // edi : the target to call 184 // edx : the arguments list 185 return RegisterArray(edi, edx); 186} 187 188// static 189constexpr auto ConstructVarargsDescriptor::registers() { 190 // eax : number of arguments (on the stack) 191 // edi : the target to call 192 // edx : the new target 193 // ecx : arguments list length (untagged) 194 // On the stack : arguments list (FixedArray) 195 return RegisterArray(edi, edx, eax, ecx); 196} 197 198// static 199constexpr auto ConstructForwardVarargsDescriptor::registers() { 200 // eax : number of arguments 201 // edx : the new target 202 // ecx : start index (to support rest parameters) 203 // edi : the target to call 204 return RegisterArray(edi, edx, eax, ecx); 205} 206 207// static 208constexpr auto ConstructWithSpreadDescriptor::registers() { 209 // eax : number of arguments (on the stack) 210 // edi : the target to call 211 // edx : the new target 212 // ecx : the object to spread 213 return RegisterArray(edi, edx, eax, ecx); 214} 215 216// static 217constexpr auto ConstructWithArrayLikeDescriptor::registers() { 218 // edi : the target to call 219 // edx : the new target 220 // ecx : the arguments list 221 return RegisterArray(edi, edx, ecx); 222} 223 224// static 225constexpr auto ConstructStubDescriptor::registers() { 226 // eax : number of arguments 227 // edx : the new target 228 // edi : the target to call 229 // ecx : allocation site or undefined 230 // TODO(jgruber): Remove the unused allocation site parameter. 231 return RegisterArray(edi, edx, eax, ecx); 232} 233 234// static 235constexpr auto AbortDescriptor::registers() { return RegisterArray(edx); } 236 237// static 238constexpr auto CompareDescriptor::registers() { 239 return RegisterArray(edx, eax); 240} 241 242// static 243constexpr auto Compare_BaselineDescriptor::registers() { 244 return RegisterArray(edx, eax, ecx); 245} 246 247// static 248constexpr auto BinaryOpDescriptor::registers() { 249 return RegisterArray(edx, eax); 250} 251 252// static 253constexpr auto BinaryOp_BaselineDescriptor::registers() { 254 return RegisterArray(edx, eax, ecx); 255} 256 257// static 258constexpr auto BinarySmiOp_BaselineDescriptor::registers() { 259 return RegisterArray(eax, edx, ecx); 260} 261 262// static 263constexpr auto ApiCallbackDescriptor::registers() { 264 return RegisterArray(edx, // kApiFunctionAddress 265 ecx, // kArgc 266 eax, // kCallData 267 edi); // kHolder 268} 269 270// static 271constexpr auto InterpreterDispatchDescriptor::registers() { 272 return RegisterArray( 273 kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister, 274 kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister); 275} 276 277// static 278constexpr auto InterpreterPushArgsThenCallDescriptor::registers() { 279 return RegisterArray(eax, // argument count 280 ecx, // address of first argument 281 edi); // the target callable to be call 282} 283 284// static 285constexpr auto InterpreterPushArgsThenConstructDescriptor::registers() { 286 return RegisterArray(eax, // argument count 287 ecx); // address of first argument 288} 289 290// static 291constexpr auto ResumeGeneratorDescriptor::registers() { 292 return RegisterArray(eax, // the value to pass to the generator 293 edx); // the JSGeneratorObject to resume 294} 295 296// static 297constexpr auto RunMicrotasksEntryDescriptor::registers() { 298 return RegisterArray(); 299} 300 301// static 302constexpr auto WasmFloat32ToNumberDescriptor::registers() { 303 // Work around using eax, whose register code is 0, and leads to the FP 304 // parameter being passed via xmm0, which is not allocatable on ia32. 305 return RegisterArray(ecx); 306} 307 308// static 309constexpr auto WasmFloat64ToNumberDescriptor::registers() { 310 // Work around using eax, whose register code is 0, and leads to the FP 311 // parameter being passed via xmm0, which is not allocatable on ia32. 312 return RegisterArray(ecx); 313} 314 315} // namespace internal 316} // namespace v8 317 318#endif // V8_TARGET_ARCH_IA32 319 320#endif // V8_CODEGEN_IA32_INTERFACE_DESCRIPTORS_IA32_INL_H_ 321