1 // Copyright 2012 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 #include "src/v8.h" 6 7 #if V8_TARGET_ARCH_X87 8 9 #include "src/interface-descriptors.h" 10 11 namespace v8 { 12 namespace internal { 13 14 const Register CallInterfaceDescriptor::ContextRegister() { return esi; } 15 16 17 const Register LoadDescriptor::ReceiverRegister() { return edx; } 18 const Register LoadDescriptor::NameRegister() { return ecx; } 19 20 21 const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return eax; } 22 23 24 const Register VectorLoadICDescriptor::VectorRegister() { return ebx; } 25 26 27 const Register StoreDescriptor::ReceiverRegister() { return edx; } 28 const Register StoreDescriptor::NameRegister() { return ecx; } 29 const Register StoreDescriptor::ValueRegister() { return eax; } 30 31 32 const Register ElementTransitionAndStoreDescriptor::MapRegister() { 33 return ebx; 34 } 35 36 37 const Register InstanceofDescriptor::left() { return eax; } 38 const Register InstanceofDescriptor::right() { return edx; } 39 40 41 const Register ArgumentsAccessReadDescriptor::index() { return edx; } 42 const Register ArgumentsAccessReadDescriptor::parameter_count() { return eax; } 43 44 45 const Register ApiGetterDescriptor::function_address() { return edx; } 46 47 48 const Register MathPowTaggedDescriptor::exponent() { return eax; } 49 50 51 const Register MathPowIntegerDescriptor::exponent() { 52 return MathPowTaggedDescriptor::exponent(); 53 } 54 55 56 void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) { 57 Register registers[] = {esi, ebx}; 58 data->Initialize(arraysize(registers), registers, NULL); 59 } 60 61 62 void FastNewContextDescriptor::Initialize(CallInterfaceDescriptorData* data) { 63 Register registers[] = {esi, edi}; 64 data->Initialize(arraysize(registers), registers, NULL); 65 } 66 67 68 void ToNumberDescriptor::Initialize(CallInterfaceDescriptorData* data) { 69 // ToNumberStub invokes a function, and therefore needs a context. 70 Register registers[] = {esi, eax}; 71 data->Initialize(arraysize(registers), registers, NULL); 72 } 73 74 75 void NumberToStringDescriptor::Initialize(CallInterfaceDescriptorData* data) { 76 Register registers[] = {esi, eax}; 77 data->Initialize(arraysize(registers), registers, NULL); 78 } 79 80 81 void FastCloneShallowArrayDescriptor::Initialize( 82 CallInterfaceDescriptorData* data) { 83 Register registers[] = {esi, eax, ebx, ecx}; 84 Representation representations[] = { 85 Representation::Tagged(), Representation::Tagged(), Representation::Smi(), 86 Representation::Tagged()}; 87 data->Initialize(arraysize(registers), registers, representations); 88 } 89 90 91 void FastCloneShallowObjectDescriptor::Initialize( 92 CallInterfaceDescriptorData* data) { 93 Register registers[] = {esi, eax, ebx, ecx, edx}; 94 data->Initialize(arraysize(registers), registers, NULL); 95 } 96 97 98 void CreateAllocationSiteDescriptor::Initialize( 99 CallInterfaceDescriptorData* data) { 100 Register registers[] = {esi, ebx, edx}; 101 data->Initialize(arraysize(registers), registers, NULL); 102 } 103 104 105 void StoreArrayLiteralElementDescriptor::Initialize( 106 CallInterfaceDescriptorData* data) { 107 Register registers[] = {esi, ecx, eax}; 108 data->Initialize(arraysize(registers), registers, NULL); 109 } 110 111 112 void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) { 113 Register registers[] = {esi, edi}; 114 data->Initialize(arraysize(registers), registers, NULL); 115 } 116 117 118 void CallFunctionWithFeedbackDescriptor::Initialize( 119 CallInterfaceDescriptorData* data) { 120 Register registers[] = {esi, edi, edx}; 121 Representation representations[] = {Representation::Tagged(), 122 Representation::Tagged(), 123 Representation::Smi()}; 124 data->Initialize(arraysize(registers), registers, representations); 125 } 126 127 128 void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) { 129 // eax : number of arguments 130 // ebx : feedback vector 131 // edx : (only if ebx is not the megamorphic symbol) slot in feedback 132 // vector (Smi) 133 // edi : constructor function 134 // TODO(turbofan): So far we don't gather type feedback and hence skip the 135 // slot parameter, but ArrayConstructStub needs the vector to be undefined. 136 Register registers[] = {esi, eax, edi, ebx}; 137 data->Initialize(arraysize(registers), registers, NULL); 138 } 139 140 141 void RegExpConstructResultDescriptor::Initialize( 142 CallInterfaceDescriptorData* data) { 143 Register registers[] = {esi, ecx, ebx, eax}; 144 data->Initialize(arraysize(registers), registers, NULL); 145 } 146 147 148 void TransitionElementsKindDescriptor::Initialize( 149 CallInterfaceDescriptorData* data) { 150 Register registers[] = {esi, eax, ebx}; 151 data->Initialize(arraysize(registers), registers, NULL); 152 } 153 154 155 void ArrayConstructorConstantArgCountDescriptor::Initialize( 156 CallInterfaceDescriptorData* data) { 157 // register state 158 // eax -- number of arguments 159 // edi -- function 160 // ebx -- allocation site with elements kind 161 Register registers[] = {esi, edi, ebx}; 162 data->Initialize(arraysize(registers), registers, NULL); 163 } 164 165 166 void ArrayConstructorDescriptor::Initialize(CallInterfaceDescriptorData* data) { 167 // stack param count needs (constructor pointer, and single argument) 168 Register registers[] = {esi, edi, ebx, eax}; 169 Representation representations[] = { 170 Representation::Tagged(), Representation::Tagged(), 171 Representation::Tagged(), Representation::Integer32()}; 172 data->Initialize(arraysize(registers), registers, representations); 173 } 174 175 176 void InternalArrayConstructorConstantArgCountDescriptor::Initialize( 177 CallInterfaceDescriptorData* data) { 178 // register state 179 // eax -- number of arguments 180 // edi -- function 181 Register registers[] = {esi, edi}; 182 data->Initialize(arraysize(registers), registers, NULL); 183 } 184 185 186 void InternalArrayConstructorDescriptor::Initialize( 187 CallInterfaceDescriptorData* data) { 188 // stack param count needs (constructor pointer, and single argument) 189 Register registers[] = {esi, edi, eax}; 190 Representation representations[] = {Representation::Tagged(), 191 Representation::Tagged(), 192 Representation::Integer32()}; 193 data->Initialize(arraysize(registers), registers, representations); 194 } 195 196 197 void CompareNilDescriptor::Initialize(CallInterfaceDescriptorData* data) { 198 Register registers[] = {esi, eax}; 199 data->Initialize(arraysize(registers), registers, NULL); 200 } 201 202 203 void ToBooleanDescriptor::Initialize(CallInterfaceDescriptorData* data) { 204 Register registers[] = {esi, eax}; 205 data->Initialize(arraysize(registers), registers, NULL); 206 } 207 208 209 void BinaryOpDescriptor::Initialize(CallInterfaceDescriptorData* data) { 210 Register registers[] = {esi, edx, eax}; 211 data->Initialize(arraysize(registers), registers, NULL); 212 } 213 214 215 void BinaryOpWithAllocationSiteDescriptor::Initialize( 216 CallInterfaceDescriptorData* data) { 217 Register registers[] = {esi, ecx, edx, eax}; 218 data->Initialize(arraysize(registers), registers, NULL); 219 } 220 221 222 void StringAddDescriptor::Initialize(CallInterfaceDescriptorData* data) { 223 Register registers[] = {esi, edx, eax}; 224 data->Initialize(arraysize(registers), registers, NULL); 225 } 226 227 228 void KeyedDescriptor::Initialize(CallInterfaceDescriptorData* data) { 229 Register registers[] = { 230 esi, // context 231 ecx, // key 232 }; 233 Representation representations[] = { 234 Representation::Tagged(), // context 235 Representation::Tagged(), // key 236 }; 237 data->Initialize(arraysize(registers), registers, representations); 238 } 239 240 241 void NamedDescriptor::Initialize(CallInterfaceDescriptorData* data) { 242 Register registers[] = { 243 esi, // context 244 ecx, // name 245 }; 246 Representation representations[] = { 247 Representation::Tagged(), // context 248 Representation::Tagged(), // name 249 }; 250 data->Initialize(arraysize(registers), registers, representations); 251 } 252 253 254 void CallHandlerDescriptor::Initialize(CallInterfaceDescriptorData* data) { 255 Register registers[] = { 256 esi, // context 257 edx, // name 258 }; 259 Representation representations[] = { 260 Representation::Tagged(), // context 261 Representation::Tagged(), // receiver 262 }; 263 data->Initialize(arraysize(registers), registers, representations); 264 } 265 266 267 void ArgumentAdaptorDescriptor::Initialize(CallInterfaceDescriptorData* data) { 268 Register registers[] = { 269 esi, // context 270 edi, // JSFunction 271 eax, // actual number of arguments 272 ebx, // expected number of arguments 273 }; 274 Representation representations[] = { 275 Representation::Tagged(), // context 276 Representation::Tagged(), // JSFunction 277 Representation::Integer32(), // actual number of arguments 278 Representation::Integer32(), // expected number of arguments 279 }; 280 data->Initialize(arraysize(registers), registers, representations); 281 } 282 283 284 void ApiFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) { 285 Register registers[] = { 286 esi, // context 287 eax, // callee 288 ebx, // call_data 289 ecx, // holder 290 edx, // api_function_address 291 }; 292 Representation representations[] = { 293 Representation::Tagged(), // context 294 Representation::Tagged(), // callee 295 Representation::Tagged(), // call_data 296 Representation::Tagged(), // holder 297 Representation::External(), // api_function_address 298 }; 299 data->Initialize(arraysize(registers), registers, representations); 300 } 301 } 302 } // namespace v8::internal 303 304 #endif // V8_TARGET_ARCH_X87 305