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_ARM64 8 9 #include "src/interface-descriptors.h" 10 11 namespace v8 { 12 namespace internal { 13 14 const Register CallInterfaceDescriptor::ContextRegister() { return cp; } 15 16 17 const Register LoadDescriptor::ReceiverRegister() { return x1; } 18 const Register LoadDescriptor::NameRegister() { return x2; } 19 20 21 const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return x0; } 22 23 24 const Register VectorLoadICDescriptor::VectorRegister() { return x3; } 25 26 27 const Register StoreDescriptor::ReceiverRegister() { return x1; } 28 const Register StoreDescriptor::NameRegister() { return x2; } 29 const Register StoreDescriptor::ValueRegister() { return x0; } 30 31 32 const Register ElementTransitionAndStoreDescriptor::MapRegister() { return x3; } 33 34 35 const Register InstanceofDescriptor::left() { 36 // Object to check (instanceof lhs). 37 return x11; 38 } 39 40 41 const Register InstanceofDescriptor::right() { 42 // Constructor function (instanceof rhs). 43 return x10; 44 } 45 46 47 const Register ArgumentsAccessReadDescriptor::index() { return x1; } 48 const Register ArgumentsAccessReadDescriptor::parameter_count() { return x0; } 49 50 51 const Register ApiGetterDescriptor::function_address() { return x2; } 52 53 54 const Register MathPowTaggedDescriptor::exponent() { return x11; } 55 56 57 const Register MathPowIntegerDescriptor::exponent() { return x12; } 58 59 60 void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) { 61 // cp: context 62 // x2: function info 63 Register registers[] = {cp, x2}; 64 data->Initialize(arraysize(registers), registers, NULL); 65 } 66 67 68 void FastNewContextDescriptor::Initialize(CallInterfaceDescriptorData* data) { 69 // cp: context 70 // x1: function 71 Register registers[] = {cp, x1}; 72 data->Initialize(arraysize(registers), registers, NULL); 73 } 74 75 76 void ToNumberDescriptor::Initialize(CallInterfaceDescriptorData* data) { 77 // cp: context 78 // x0: value 79 Register registers[] = {cp, x0}; 80 data->Initialize(arraysize(registers), registers, NULL); 81 } 82 83 84 void NumberToStringDescriptor::Initialize(CallInterfaceDescriptorData* data) { 85 // cp: context 86 // x0: value 87 Register registers[] = {cp, x0}; 88 data->Initialize(arraysize(registers), registers, NULL); 89 } 90 91 92 void FastCloneShallowArrayDescriptor::Initialize( 93 CallInterfaceDescriptorData* data) { 94 // cp: context 95 // x3: array literals array 96 // x2: array literal index 97 // x1: constant elements 98 Register registers[] = {cp, x3, x2, x1}; 99 Representation representations[] = { 100 Representation::Tagged(), Representation::Tagged(), Representation::Smi(), 101 Representation::Tagged()}; 102 data->Initialize(arraysize(registers), registers, representations); 103 } 104 105 106 void FastCloneShallowObjectDescriptor::Initialize( 107 CallInterfaceDescriptorData* data) { 108 // cp: context 109 // x3: object literals array 110 // x2: object literal index 111 // x1: constant properties 112 // x0: object literal flags 113 Register registers[] = {cp, x3, x2, x1, x0}; 114 data->Initialize(arraysize(registers), registers, NULL); 115 } 116 117 118 void CreateAllocationSiteDescriptor::Initialize( 119 CallInterfaceDescriptorData* data) { 120 // cp: context 121 // x2: feedback vector 122 // x3: call feedback slot 123 Register registers[] = {cp, x2, x3}; 124 data->Initialize(arraysize(registers), registers, NULL); 125 } 126 127 128 void StoreArrayLiteralElementDescriptor::Initialize( 129 CallInterfaceDescriptorData* data) { 130 Register registers[] = {cp, x3, x0}; 131 data->Initialize(arraysize(registers), registers, NULL); 132 } 133 134 135 void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) { 136 // x1 function the function to call 137 Register registers[] = {cp, x1}; 138 data->Initialize(arraysize(registers), registers, NULL); 139 } 140 141 142 void CallFunctionWithFeedbackDescriptor::Initialize( 143 CallInterfaceDescriptorData* data) { 144 Register registers[] = {cp, x1, x3}; 145 Representation representations[] = {Representation::Tagged(), 146 Representation::Tagged(), 147 Representation::Smi()}; 148 data->Initialize(arraysize(registers), registers, representations); 149 } 150 151 152 void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) { 153 // x0 : number of arguments 154 // x1 : the function to call 155 // x2 : feedback vector 156 // x3 : slot in feedback vector (smi) (if r2 is not the megamorphic symbol) 157 // TODO(turbofan): So far we don't gather type feedback and hence skip the 158 // slot parameter, but ArrayConstructStub needs the vector to be undefined. 159 Register registers[] = {cp, x0, x1, x2}; 160 data->Initialize(arraysize(registers), registers, NULL); 161 } 162 163 164 void RegExpConstructResultDescriptor::Initialize( 165 CallInterfaceDescriptorData* data) { 166 // cp: context 167 // x2: length 168 // x1: index (of last match) 169 // x0: string 170 Register registers[] = {cp, x2, x1, x0}; 171 data->Initialize(arraysize(registers), registers, NULL); 172 } 173 174 175 void TransitionElementsKindDescriptor::Initialize( 176 CallInterfaceDescriptorData* data) { 177 // cp: context 178 // x0: value (js_array) 179 // x1: to_map 180 Register registers[] = {cp, x0, x1}; 181 data->Initialize(arraysize(registers), registers, NULL); 182 } 183 184 185 void ArrayConstructorConstantArgCountDescriptor::Initialize( 186 CallInterfaceDescriptorData* data) { 187 // cp: context 188 // x1: function 189 // x2: allocation site with elements kind 190 // x0: number of arguments to the constructor function 191 Register registers[] = {cp, x1, x2}; 192 data->Initialize(arraysize(registers), registers, NULL); 193 } 194 195 196 void ArrayConstructorDescriptor::Initialize(CallInterfaceDescriptorData* data) { 197 // stack param count needs (constructor pointer, and single argument) 198 Register registers[] = {cp, x1, x2, x0}; 199 Representation representations[] = { 200 Representation::Tagged(), Representation::Tagged(), 201 Representation::Tagged(), Representation::Integer32()}; 202 data->Initialize(arraysize(registers), registers, representations); 203 } 204 205 206 void InternalArrayConstructorConstantArgCountDescriptor::Initialize( 207 CallInterfaceDescriptorData* data) { 208 // cp: context 209 // x1: constructor function 210 // x0: number of arguments to the constructor function 211 Register registers[] = {cp, x1}; 212 data->Initialize(arraysize(registers), registers, NULL); 213 } 214 215 216 void InternalArrayConstructorDescriptor::Initialize( 217 CallInterfaceDescriptorData* data) { 218 // stack param count needs (constructor pointer, and single argument) 219 Register registers[] = {cp, x1, x0}; 220 Representation representations[] = {Representation::Tagged(), 221 Representation::Tagged(), 222 Representation::Integer32()}; 223 data->Initialize(arraysize(registers), registers, representations); 224 } 225 226 227 void CompareNilDescriptor::Initialize(CallInterfaceDescriptorData* data) { 228 // cp: context 229 // x0: value to compare 230 Register registers[] = {cp, x0}; 231 data->Initialize(arraysize(registers), registers, NULL); 232 } 233 234 235 void ToBooleanDescriptor::Initialize(CallInterfaceDescriptorData* data) { 236 // cp: context 237 // x0: value 238 Register registers[] = {cp, x0}; 239 data->Initialize(arraysize(registers), registers, NULL); 240 } 241 242 243 void BinaryOpDescriptor::Initialize(CallInterfaceDescriptorData* data) { 244 // cp: context 245 // x1: left operand 246 // x0: right operand 247 Register registers[] = {cp, x1, x0}; 248 data->Initialize(arraysize(registers), registers, NULL); 249 } 250 251 252 void BinaryOpWithAllocationSiteDescriptor::Initialize( 253 CallInterfaceDescriptorData* data) { 254 // cp: context 255 // x2: allocation site 256 // x1: left operand 257 // x0: right operand 258 Register registers[] = {cp, x2, x1, x0}; 259 data->Initialize(arraysize(registers), registers, NULL); 260 } 261 262 263 void StringAddDescriptor::Initialize(CallInterfaceDescriptorData* data) { 264 // cp: context 265 // x1: left operand 266 // x0: right operand 267 Register registers[] = {cp, x1, x0}; 268 data->Initialize(arraysize(registers), registers, NULL); 269 } 270 271 272 void KeyedDescriptor::Initialize(CallInterfaceDescriptorData* data) { 273 static PlatformInterfaceDescriptor noInlineDescriptor = 274 PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS); 275 276 Register registers[] = { 277 cp, // context 278 x2, // key 279 }; 280 Representation representations[] = { 281 Representation::Tagged(), // context 282 Representation::Tagged(), // key 283 }; 284 data->Initialize(arraysize(registers), registers, representations, 285 &noInlineDescriptor); 286 } 287 288 289 void NamedDescriptor::Initialize(CallInterfaceDescriptorData* data) { 290 static PlatformInterfaceDescriptor noInlineDescriptor = 291 PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS); 292 293 Register registers[] = { 294 cp, // context 295 x2, // name 296 }; 297 Representation representations[] = { 298 Representation::Tagged(), // context 299 Representation::Tagged(), // name 300 }; 301 data->Initialize(arraysize(registers), registers, representations, 302 &noInlineDescriptor); 303 } 304 305 306 void CallHandlerDescriptor::Initialize(CallInterfaceDescriptorData* data) { 307 static PlatformInterfaceDescriptor default_descriptor = 308 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS); 309 310 Register registers[] = { 311 cp, // context 312 x0, // receiver 313 }; 314 Representation representations[] = { 315 Representation::Tagged(), // context 316 Representation::Tagged(), // receiver 317 }; 318 data->Initialize(arraysize(registers), registers, representations, 319 &default_descriptor); 320 } 321 322 323 void ArgumentAdaptorDescriptor::Initialize(CallInterfaceDescriptorData* data) { 324 static PlatformInterfaceDescriptor default_descriptor = 325 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS); 326 327 Register registers[] = { 328 cp, // context 329 x1, // JSFunction 330 x0, // actual number of arguments 331 x2, // expected number of arguments 332 }; 333 Representation representations[] = { 334 Representation::Tagged(), // context 335 Representation::Tagged(), // JSFunction 336 Representation::Integer32(), // actual number of arguments 337 Representation::Integer32(), // expected number of arguments 338 }; 339 data->Initialize(arraysize(registers), registers, representations, 340 &default_descriptor); 341 } 342 343 344 void ApiFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) { 345 static PlatformInterfaceDescriptor default_descriptor = 346 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS); 347 348 Register registers[] = { 349 cp, // context 350 x0, // callee 351 x4, // call_data 352 x2, // holder 353 x1, // api_function_address 354 }; 355 Representation representations[] = { 356 Representation::Tagged(), // context 357 Representation::Tagged(), // callee 358 Representation::Tagged(), // call_data 359 Representation::Tagged(), // holder 360 Representation::External(), // api_function_address 361 }; 362 data->Initialize(arraysize(registers), registers, representations, 363 &default_descriptor); 364 } 365 } 366 } // namespace v8::internal 367 368 #endif // V8_TARGET_ARCH_ARM64 369