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