1 // Copyright 2015 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 #if V8_TARGET_ARCH_S390 6 7 #include "src/interface-descriptors.h" 8 9 namespace v8 { 10 namespace internal { 11 12 const Register CallInterfaceDescriptor::ContextRegister() { return cp; } 13 14 void CallInterfaceDescriptor::DefaultInitializePlatformSpecific( 15 CallInterfaceDescriptorData* data, int register_parameter_count) { 16 const Register default_stub_registers[] = {r2, r3, r4, r5, r6}; 17 CHECK_LE(static_cast<size_t>(register_parameter_count), 18 arraysize(default_stub_registers)); 19 data->InitializePlatformSpecific(register_parameter_count, 20 default_stub_registers); 21 } 22 23 const Register FastNewFunctionContextDescriptor::FunctionRegister() { 24 return r3; 25 } 26 const Register FastNewFunctionContextDescriptor::SlotsRegister() { return r2; } 27 28 const Register LoadDescriptor::ReceiverRegister() { return r3; } 29 const Register LoadDescriptor::NameRegister() { return r4; } 30 const Register LoadDescriptor::SlotRegister() { return r2; } 31 32 const Register LoadWithVectorDescriptor::VectorRegister() { return r5; } 33 34 const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r6; } 35 36 const Register StoreDescriptor::ReceiverRegister() { return r3; } 37 const Register StoreDescriptor::NameRegister() { return r4; } 38 const Register StoreDescriptor::ValueRegister() { return r2; } 39 const Register StoreDescriptor::SlotRegister() { return r6; } 40 41 const Register StoreWithVectorDescriptor::VectorRegister() { return r5; } 42 43 const Register StoreTransitionDescriptor::SlotRegister() { return r6; } 44 const Register StoreTransitionDescriptor::VectorRegister() { return r5; } 45 const Register StoreTransitionDescriptor::MapRegister() { return r7; } 46 47 const Register StringCompareDescriptor::LeftRegister() { return r3; } 48 const Register StringCompareDescriptor::RightRegister() { return r2; } 49 50 const Register ApiGetterDescriptor::HolderRegister() { return r2; } 51 const Register ApiGetterDescriptor::CallbackRegister() { return r5; } 52 53 const Register MathPowTaggedDescriptor::exponent() { return r4; } 54 55 const Register MathPowIntegerDescriptor::exponent() { 56 return MathPowTaggedDescriptor::exponent(); 57 } 58 59 const Register GrowArrayElementsDescriptor::ObjectRegister() { return r2; } 60 const Register GrowArrayElementsDescriptor::KeyRegister() { return r5; } 61 62 void FastNewClosureDescriptor::InitializePlatformSpecific( 63 CallInterfaceDescriptorData* data) { 64 Register registers[] = {r3, r4, r5}; 65 data->InitializePlatformSpecific(arraysize(registers), registers); 66 } 67 68 // static 69 const Register TypeConversionDescriptor::ArgumentRegister() { return r2; } 70 71 void TypeofDescriptor::InitializePlatformSpecific( 72 CallInterfaceDescriptorData* data) { 73 Register registers[] = {r5}; 74 data->InitializePlatformSpecific(arraysize(registers), registers); 75 } 76 77 void FastCloneRegExpDescriptor::InitializePlatformSpecific( 78 CallInterfaceDescriptorData* data) { 79 Register registers[] = {r5, r4, r3, r2}; 80 data->InitializePlatformSpecific(arraysize(registers), registers); 81 } 82 83 void FastCloneShallowArrayDescriptor::InitializePlatformSpecific( 84 CallInterfaceDescriptorData* data) { 85 Register registers[] = {r5, r4, r3}; 86 data->InitializePlatformSpecific(arraysize(registers), registers); 87 } 88 89 void FastCloneShallowObjectDescriptor::InitializePlatformSpecific( 90 CallInterfaceDescriptorData* data) { 91 Register registers[] = {r5, r4, r3, r2}; 92 data->InitializePlatformSpecific(arraysize(registers), registers); 93 } 94 95 void CreateAllocationSiteDescriptor::InitializePlatformSpecific( 96 CallInterfaceDescriptorData* data) { 97 Register registers[] = {r4, r5}; 98 data->InitializePlatformSpecific(arraysize(registers), registers); 99 } 100 101 void CreateWeakCellDescriptor::InitializePlatformSpecific( 102 CallInterfaceDescriptorData* data) { 103 Register registers[] = {r4, r5, r3}; 104 data->InitializePlatformSpecific(arraysize(registers), registers); 105 } 106 107 void CallFunctionDescriptor::InitializePlatformSpecific( 108 CallInterfaceDescriptorData* data) { 109 Register registers[] = {r3}; 110 data->InitializePlatformSpecific(arraysize(registers), registers); 111 } 112 113 void CallICTrampolineDescriptor::InitializePlatformSpecific( 114 CallInterfaceDescriptorData* data) { 115 Register registers[] = {r3, r2, r5}; 116 data->InitializePlatformSpecific(arraysize(registers), registers); 117 } 118 119 void CallICDescriptor::InitializePlatformSpecific( 120 CallInterfaceDescriptorData* data) { 121 Register registers[] = {r3, r2, r5, r4}; 122 data->InitializePlatformSpecific(arraysize(registers), registers); 123 } 124 125 void CallConstructDescriptor::InitializePlatformSpecific( 126 CallInterfaceDescriptorData* data) { 127 // r2 : number of arguments 128 // r3 : the function to call 129 // r4 : feedback vector 130 // r5 : slot in feedback vector (Smi, for RecordCallTarget) 131 // r6 : new target (for IsSuperConstructorCall) 132 // TODO(turbofan): So far we don't gather type feedback and hence skip the 133 // slot parameter, but ArrayConstructStub needs the vector to be undefined. 134 Register registers[] = {r2, r3, r6, r4}; 135 data->InitializePlatformSpecific(arraysize(registers), registers); 136 } 137 138 void CallTrampolineDescriptor::InitializePlatformSpecific( 139 CallInterfaceDescriptorData* data) { 140 // r2 : number of arguments 141 // r3 : the target to call 142 Register registers[] = {r3, r2}; 143 data->InitializePlatformSpecific(arraysize(registers), registers); 144 } 145 146 void CallForwardVarargsDescriptor::InitializePlatformSpecific( 147 CallInterfaceDescriptorData* data) { 148 // r4 : start index (to support rest parameters) 149 // r3 : the target to call 150 Register registers[] = {r3, r4}; 151 data->InitializePlatformSpecific(arraysize(registers), registers); 152 } 153 154 void ConstructStubDescriptor::InitializePlatformSpecific( 155 CallInterfaceDescriptorData* data) { 156 // r2 : number of arguments 157 // r3 : the target to call 158 // r5 : the new target 159 // r4 : allocation site or undefined 160 Register registers[] = {r3, r5, r2, r4}; 161 data->InitializePlatformSpecific(arraysize(registers), registers); 162 } 163 164 void ConstructTrampolineDescriptor::InitializePlatformSpecific( 165 CallInterfaceDescriptorData* data) { 166 // r2 : number of arguments 167 // r3 : the target to call 168 // r5 : the new target 169 Register registers[] = {r3, r5, r2}; 170 data->InitializePlatformSpecific(arraysize(registers), registers); 171 } 172 173 void TransitionElementsKindDescriptor::InitializePlatformSpecific( 174 CallInterfaceDescriptorData* data) { 175 Register registers[] = {r2, r3}; 176 data->InitializePlatformSpecific(arraysize(registers), registers); 177 } 178 179 void AllocateHeapNumberDescriptor::InitializePlatformSpecific( 180 CallInterfaceDescriptorData* data) { 181 data->InitializePlatformSpecific(0, nullptr, nullptr); 182 } 183 184 void ArrayConstructorDescriptor::InitializePlatformSpecific( 185 CallInterfaceDescriptorData* data) { 186 // kTarget, kNewTarget, kActualArgumentsCount, kAllocationSite 187 Register registers[] = {r3, r5, r2, r4}; 188 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 189 } 190 191 void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific( 192 CallInterfaceDescriptorData* data) { 193 // register state 194 // r2 -- number of arguments 195 // r3 -- function 196 // r4 -- allocation site with elements kind 197 Register registers[] = {r3, r4, r2}; 198 data->InitializePlatformSpecific(arraysize(registers), registers); 199 } 200 201 void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific( 202 CallInterfaceDescriptorData* data) { 203 // register state 204 // r2 -- number of arguments 205 // r3 -- function 206 // r4 -- allocation site with elements kind 207 Register registers[] = {r3, r4, r2}; 208 data->InitializePlatformSpecific(arraysize(registers), registers, NULL); 209 } 210 211 void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific( 212 CallInterfaceDescriptorData* data) { 213 // stack param count needs (constructor pointer, and single argument) 214 Register registers[] = {r3, r4, r2}; 215 data->InitializePlatformSpecific(arraysize(registers), registers); 216 } 217 218 void VarArgFunctionDescriptor::InitializePlatformSpecific( 219 CallInterfaceDescriptorData* data) { 220 // stack param count needs (arg count) 221 Register registers[] = {r2}; 222 data->InitializePlatformSpecific(arraysize(registers), registers); 223 } 224 225 void CompareDescriptor::InitializePlatformSpecific( 226 CallInterfaceDescriptorData* data) { 227 Register registers[] = {r3, r2}; 228 data->InitializePlatformSpecific(arraysize(registers), registers); 229 } 230 231 void BinaryOpDescriptor::InitializePlatformSpecific( 232 CallInterfaceDescriptorData* data) { 233 Register registers[] = {r3, r2}; 234 data->InitializePlatformSpecific(arraysize(registers), registers); 235 } 236 237 void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific( 238 CallInterfaceDescriptorData* data) { 239 Register registers[] = {r4, r3, r2}; 240 data->InitializePlatformSpecific(arraysize(registers), registers); 241 } 242 243 void BinaryOpWithVectorDescriptor::InitializePlatformSpecific( 244 CallInterfaceDescriptorData* data) { 245 // register state 246 // r3 -- lhs 247 // r2 -- rhs 248 // r6 -- slot id 249 // r5 -- vector 250 Register registers[] = {r3, r2, r6, r5}; 251 data->InitializePlatformSpecific(arraysize(registers), registers); 252 } 253 254 void CountOpDescriptor::InitializePlatformSpecific( 255 CallInterfaceDescriptorData* data) { 256 Register registers[] = {r4}; 257 data->InitializePlatformSpecific(arraysize(registers), registers); 258 } 259 260 void StringAddDescriptor::InitializePlatformSpecific( 261 CallInterfaceDescriptorData* data) { 262 Register registers[] = {r3, r2}; 263 data->InitializePlatformSpecific(arraysize(registers), registers); 264 } 265 266 void KeyedDescriptor::InitializePlatformSpecific( 267 CallInterfaceDescriptorData* data) { 268 Register registers[] = { 269 r4, // key 270 }; 271 data->InitializePlatformSpecific(arraysize(registers), registers); 272 } 273 274 void NamedDescriptor::InitializePlatformSpecific( 275 CallInterfaceDescriptorData* data) { 276 Register registers[] = { 277 r4, // name 278 }; 279 data->InitializePlatformSpecific(arraysize(registers), registers); 280 } 281 282 void CallHandlerDescriptor::InitializePlatformSpecific( 283 CallInterfaceDescriptorData* data) { 284 Register registers[] = { 285 r2, // receiver 286 }; 287 data->InitializePlatformSpecific(arraysize(registers), registers); 288 } 289 290 void ArgumentAdaptorDescriptor::InitializePlatformSpecific( 291 CallInterfaceDescriptorData* data) { 292 Register registers[] = { 293 r3, // JSFunction 294 r5, // the new target 295 r2, // actual number of arguments 296 r4, // expected number of arguments 297 }; 298 data->InitializePlatformSpecific(arraysize(registers), registers); 299 } 300 301 void ApiCallbackDescriptor::InitializePlatformSpecific( 302 CallInterfaceDescriptorData* data) { 303 Register registers[] = { 304 r2, // callee 305 r6, // call_data 306 r4, // holder 307 r3, // api_function_address 308 }; 309 data->InitializePlatformSpecific(arraysize(registers), registers); 310 } 311 312 void InterpreterDispatchDescriptor::InitializePlatformSpecific( 313 CallInterfaceDescriptorData* data) { 314 Register registers[] = { 315 kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister, 316 kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister}; 317 data->InitializePlatformSpecific(arraysize(registers), registers); 318 } 319 320 void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( 321 CallInterfaceDescriptorData* data) { 322 Register registers[] = { 323 r2, // argument count (not including receiver) 324 r4, // address of first argument 325 r3 // the target callable to be call 326 }; 327 data->InitializePlatformSpecific(arraysize(registers), registers); 328 } 329 330 void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( 331 CallInterfaceDescriptorData* data) { 332 Register registers[] = { 333 r2, // argument count (not including receiver) 334 r5, // new target 335 r3, // constructor to call 336 r4, // allocation site feedback if available, undefined otherwise 337 r6 // address of the first argument 338 }; 339 data->InitializePlatformSpecific(arraysize(registers), registers); 340 } 341 342 void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific( 343 CallInterfaceDescriptorData* data) { 344 Register registers[] = { 345 r2, // argument count (not including receiver) 346 r3, // target to call checked to be Array function 347 r4, // allocation site feedback if available, undefined otherwise 348 r5 // address of the first argument 349 }; 350 data->InitializePlatformSpecific(arraysize(registers), registers); 351 } 352 353 void InterpreterCEntryDescriptor::InitializePlatformSpecific( 354 CallInterfaceDescriptorData* data) { 355 Register registers[] = { 356 r2, // argument count (argc) 357 r4, // address of first argument (argv) 358 r3 // the runtime function to call 359 }; 360 data->InitializePlatformSpecific(arraysize(registers), registers); 361 } 362 363 void ResumeGeneratorDescriptor::InitializePlatformSpecific( 364 CallInterfaceDescriptorData* data) { 365 Register registers[] = { 366 r2, // the value to pass to the generator 367 r3, // the JSGeneratorObject to resume 368 r4 // the resume mode (tagged) 369 }; 370 data->InitializePlatformSpecific(arraysize(registers), registers); 371 } 372 373 void FrameDropperTrampolineDescriptor::InitializePlatformSpecific( 374 CallInterfaceDescriptorData* data) { 375 Register registers[] = { 376 r3, // loaded new FP 377 }; 378 data->InitializePlatformSpecific(arraysize(registers), registers); 379 } 380 381 } // namespace internal 382 } // namespace v8 383 384 #endif // V8_TARGET_ARCH_S390 385